| author | |
| committer | |
| log | 289ae45c1b58e952867c4fa1e246d0ef7bc2ff64 |
| tree | 5dd034143a2354b7b44496e684f1c764e2f9664c |
| parent | c89bb3e141ee215add0b52930d48bffd8dae8342 |
| parent | c546ddb3edc557fae4b932e5239b9dcb66117832 |
| signature |
Move many settings from being per-Compilation to being per-Module258 files changed, 43139 insertions(+), 40739 deletions(-)
CMakeLists.txt+43-34| ... | ... | @@ -480,22 +480,23 @@ set(ZIG_STAGE2_SOURCES |
| 480 | 480 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/unordtf2.zig" |
| 481 | 481 | "${CMAKE_SOURCE_DIR}/lib/std/start.zig" |
| 482 | 482 | "${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" | |
| 499 | 500 | "${CMAKE_SOURCE_DIR}/lib/std/Thread.zig" |
| 500 | 501 | "${CMAKE_SOURCE_DIR}/lib/std/Thread/Futex.zig" |
| 501 | 502 | "${CMAKE_SOURCE_DIR}/lib/std/Thread/Mutex.zig" |
| ... | ... | @@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES |
| 508 | 509 | "${CMAKE_SOURCE_DIR}/lib/std/zig.zig" |
| 509 | 510 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig" |
| 510 | 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig" |
| 511 | "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig" | |
| 512 | 512 | "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" |
| 513 | 513 | "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" |
| 514 | 514 | "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig" |
| ... | ... | @@ -516,12 +516,12 @@ set(ZIG_STAGE2_SOURCES |
| 516 | 516 | "${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig" |
| 517 | 517 | "${CMAKE_SOURCE_DIR}/lib/std/zig/system.zig" |
| 518 | 518 | "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativePaths.zig" |
| 519 | "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativeTargetInfo.zig" | |
| 520 | 519 | "${CMAKE_SOURCE_DIR}/lib/std/zig/system/x86.zig" |
| 521 | 520 | "${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig" |
| 522 | 521 | "${CMAKE_SOURCE_DIR}/src/Air.zig" |
| 523 | 522 | "${CMAKE_SOURCE_DIR}/src/AstGen.zig" |
| 524 | 523 | "${CMAKE_SOURCE_DIR}/src/Compilation.zig" |
| 524 | "${CMAKE_SOURCE_DIR}/src/Compilation/Config.zig" | |
| 525 | 525 | "${CMAKE_SOURCE_DIR}/src/Liveness.zig" |
| 526 | 526 | "${CMAKE_SOURCE_DIR}/src/Module.zig" |
| 527 | 527 | "${CMAKE_SOURCE_DIR}/src/Package.zig" |
| ... | ... | @@ -810,18 +810,26 @@ endif() |
| 810 | 810 | |
| 811 | 811 | set(BUILD_ZIG2_ARGS |
| 812 | 812 | "${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}" | |
| 824 | 816 | -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" | |
| 825 | 833 | ) |
| 826 | 834 | |
| 827 | 835 | add_custom_command( |
| ... | ... | @@ -834,12 +842,13 @@ add_custom_command( |
| 834 | 842 | |
| 835 | 843 | set(BUILD_COMPILER_RT_ARGS |
| 836 | 844 | "${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}" | |
| 842 | 848 | -target "${ZIG_HOST_TARGET_TRIPLE}" |
| 849 | --dep "build_options" | |
| 850 | --mod "root" "lib/compiler_rt.zig" | |
| 851 | --mod "build_options" "${ZIG_CONFIG_ZIG_OUT}" | |
| 843 | 852 | ) |
| 844 | 853 | |
| 845 | 854 | add_custom_command( |
bootstrap.c+24-12| ... | ... | @@ -138,18 +138,29 @@ int main(int argc, char **argv) { |
| 138 | 138 | |
| 139 | 139 | { |
| 140 | 140 | const char *child_argv[] = { |
| 141 | "./zig1", "lib", "build-exe", "src/main.zig", | |
| 141 | "./zig1", "lib", "build-exe", | |
| 142 | 142 | "-ofmt=c", "-lc", "-OReleaseSmall", |
| 143 | 143 | "--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", | |
| 152 | 144 | "-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", | |
| 153 | 164 | NULL, |
| 154 | 165 | }; |
| 155 | 166 | print_and_run(child_argv); |
| ... | ... | @@ -157,12 +168,13 @@ int main(int argc, char **argv) { |
| 157 | 168 | |
| 158 | 169 | { |
| 159 | 170 | const char *child_argv[] = { |
| 160 | "./zig1", "lib", "build-obj", "lib/compiler_rt.zig", | |
| 171 | "./zig1", "lib", "build-obj", | |
| 161 | 172 | "-ofmt=c", "-OReleaseSmall", |
| 162 | 173 | "--name", "compiler_rt", "-femit-bin=compiler_rt.c", |
| 163 | "--mod", "build_options::config.zig", | |
| 164 | "--deps", "build_options", | |
| 165 | 174 | "-target", host_triple, |
| 175 | "--dep", "build_options", | |
| 176 | "--mod", "root", "lib/compiler_rt.zig", | |
| 177 | "--mod", "build_options", "config.zig", | |
| 166 | 178 | NULL, |
| 167 | 179 | }; |
| 168 | 180 | print_and_run(child_argv); |
build.zig+53-39| ... | ... | @@ -39,10 +39,10 @@ pub fn build(b: *std.Build) !void { |
| 39 | 39 | const docgen_exe = b.addExecutable(.{ |
| 40 | 40 | .name = "docgen", |
| 41 | 41 | .root_source_file = .{ .path = "tools/docgen.zig" }, |
| 42 | .target = .{}, | |
| 42 | .target = b.host, | |
| 43 | 43 | .optimize = .Debug, |
| 44 | .single_threaded = single_threaded, | |
| 44 | 45 | }); |
| 45 | docgen_exe.single_threaded = single_threaded; | |
| 46 | 46 | |
| 47 | 47 | const docgen_cmd = b.addRunArtifact(docgen_exe); |
| 48 | 48 | docgen_cmd.addArgs(&.{ "--zig", b.zig_exe }); |
| ... | ... | @@ -89,11 +89,11 @@ pub fn build(b: *std.Build) !void { |
| 89 | 89 | const check_case_exe = b.addExecutable(.{ |
| 90 | 90 | .name = "check-case", |
| 91 | 91 | .root_source_file = .{ .path = "test/src/Cases.zig" }, |
| 92 | .target = b.host, | |
| 92 | 93 | .optimize = optimize, |
| 93 | .main_mod_path = .{ .path = "." }, | |
| 94 | .single_threaded = single_threaded, | |
| 94 | 95 | }); |
| 95 | 96 | check_case_exe.stack_size = stack_size; |
| 96 | check_case_exe.single_threaded = single_threaded; | |
| 97 | 97 | |
| 98 | 98 | const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false; |
| 99 | 99 | 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 { |
| 194 | 194 | break :blk 4; |
| 195 | 195 | }; |
| 196 | 196 | |
| 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 | }); | |
| 199 | 204 | exe.pie = pie; |
| 200 | exe.sanitize_thread = sanitize_thread; | |
| 201 | 205 | exe.entitlements = entitlements; |
| 202 | 206 | |
| 203 | 207 | exe.build_id = b.option( |
| 204 | std.Build.Step.Compile.BuildId, | |
| 208 | std.zig.BuildId, | |
| 205 | 209 | "build-id", |
| 206 | 210 | "Request creation of '.note.gnu.build-id' section", |
| 207 | 211 | ); |
| ... | ... | @@ -217,9 +221,7 @@ pub fn build(b: *std.Build) !void { |
| 217 | 221 | |
| 218 | 222 | test_step.dependOn(&exe.step); |
| 219 | 223 | |
| 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) { | |
| 223 | 225 | // LTO is currently broken on mingw, this can be removed when it's fixed. |
| 224 | 226 | exe.want_lto = false; |
| 225 | 227 | check_case_exe.want_lto = false; |
| ... | ... | @@ -230,7 +232,7 @@ pub fn build(b: *std.Build) !void { |
| 230 | 232 | exe.use_lld = use_llvm; |
| 231 | 233 | |
| 232 | 234 | const exe_options = b.addOptions(); |
| 233 | exe.addOptions("build_options", exe_options); | |
| 235 | exe.root_module.addOptions("build_options", exe_options); | |
| 234 | 236 | |
| 235 | 237 | exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames); |
| 236 | 238 | exe_options.addOption(bool, "skip_non_native", skip_non_native); |
| ... | ... | @@ -345,7 +347,7 @@ pub fn build(b: *std.Build) !void { |
| 345 | 347 | try addStaticLlvmOptionsToExe(exe); |
| 346 | 348 | try addStaticLlvmOptionsToExe(check_case_exe); |
| 347 | 349 | } |
| 348 | if (target.isWindows()) { | |
| 350 | if (target.result.os.tag == .windows) { | |
| 349 | 351 | inline for (.{ exe, check_case_exe }) |artifact| { |
| 350 | 352 | artifact.linkSystemLibrary("version"); |
| 351 | 353 | artifact.linkSystemLibrary("uuid"); |
| ... | ... | @@ -369,7 +371,7 @@ pub fn build(b: *std.Build) !void { |
| 369 | 371 | ); |
| 370 | 372 | |
| 371 | 373 | // 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) | |
| 373 | 375 | &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" } |
| 374 | 376 | else |
| 375 | 377 | &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" }; |
| ... | ... | @@ -377,11 +379,11 @@ pub fn build(b: *std.Build) !void { |
| 377 | 379 | exe.addIncludePath(.{ .cwd_relative = tracy_path }); |
| 378 | 380 | exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); |
| 379 | 381 | if (!enable_llvm) { |
| 380 | exe.linkSystemLibraryName("c++"); | |
| 382 | exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no }); | |
| 381 | 383 | } |
| 382 | 384 | exe.linkLibC(); |
| 383 | 385 | |
| 384 | if (target.isWindows()) { | |
| 386 | if (target.result.os.tag == .windows) { | |
| 385 | 387 | exe.linkSystemLibrary("dbghelp"); |
| 386 | 388 | exe.linkSystemLibrary("ws2_32"); |
| 387 | 389 | } |
| ... | ... | @@ -390,7 +392,7 @@ pub fn build(b: *std.Build) !void { |
| 390 | 392 | const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); |
| 391 | 393 | |
| 392 | 394 | 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); | |
| 394 | 396 | |
| 395 | 397 | test_cases_options.addOption(bool, "enable_tracy", false); |
| 396 | 398 | test_cases_options.addOption(bool, "enable_logging", enable_logging); |
| ... | ... | @@ -540,16 +542,19 @@ pub fn build(b: *std.Build) !void { |
| 540 | 542 | fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 541 | 543 | const semver = try std.SemanticVersion.parse(version); |
| 542 | 544 | |
| 543 | var target: std.zig.CrossTarget = .{ | |
| 545 | var target_query: std.zig.CrossTarget = .{ | |
| 544 | 546 | .cpu_arch = .wasm32, |
| 545 | 547 | .os_tag = .wasi, |
| 546 | 548 | }; |
| 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)); | |
| 548 | 550 | |
| 549 | const exe = addCompilerStep(b, .ReleaseSmall, target); | |
| 551 | const exe = addCompilerStep(b, .{ | |
| 552 | .optimize = .ReleaseSmall, | |
| 553 | .target = b.resolveTargetQuery(target_query), | |
| 554 | }); | |
| 550 | 555 | |
| 551 | 556 | const exe_options = b.addOptions(); |
| 552 | exe.addOptions("build_options", exe_options); | |
| 557 | exe.root_module.addOptions("build_options", exe_options); | |
| 553 | 558 | |
| 554 | 559 | exe_options.addOption(u32, "mem_leak_frames", 0); |
| 555 | 560 | exe_options.addOption(bool, "have_llvm", false); |
| ... | ... | @@ -584,17 +589,24 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 584 | 589 | update_zig1_step.dependOn(&copy_zig_h.step); |
| 585 | 590 | } |
| 586 | 591 | |
| 587 | fn addCompilerStep( | |
| 588 | b: *std.Build, | |
| 592 | const AddCompilerStepOptions = struct { | |
| 589 | 593 | 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 | ||
| 600 | fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile { | |
| 592 | 601 | const exe = b.addExecutable(.{ |
| 593 | 602 | .name = "zig", |
| 594 | 603 | .root_source_file = .{ .path = "src/main.zig" }, |
| 595 | .target = target, | |
| 596 | .optimize = optimize, | |
| 604 | .target = options.target, | |
| 605 | .optimize = options.optimize, | |
| 597 | 606 | .max_rss = 7_000_000_000, |
| 607 | .strip = options.strip, | |
| 608 | .sanitize_thread = options.sanitize_thread, | |
| 609 | .single_threaded = options.single_threaded, | |
| 598 | 610 | }); |
| 599 | 611 | exe.stack_size = stack_size; |
| 600 | 612 | |
| ... | ... | @@ -602,15 +614,15 @@ fn addCompilerStep( |
| 602 | 614 | aro_options.addOption([]const u8, "version_str", "aro-zig"); |
| 603 | 615 | const aro_options_module = aro_options.createModule(); |
| 604 | 616 | 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 = &.{.{ | |
| 607 | 619 | .name = "build_options", |
| 608 | 620 | .module = aro_options_module, |
| 609 | 621 | }}, |
| 610 | 622 | }); |
| 611 | 623 | 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 = &.{ | |
| 614 | 626 | .{ |
| 615 | 627 | .name = "build_options", |
| 616 | 628 | .module = aro_options_module, |
| ... | ... | @@ -625,7 +637,7 @@ fn addCompilerStep( |
| 625 | 637 | }, |
| 626 | 638 | }); |
| 627 | 639 | |
| 628 | exe.addModule("aro", aro_module); | |
| 640 | exe.root_module.addImport("aro", aro_module); | |
| 629 | 641 | return exe; |
| 630 | 642 | } |
| 631 | 643 | |
| ... | ... | @@ -649,7 +661,7 @@ fn addCmakeCfgOptionsToExe( |
| 649 | 661 | exe: *std.Build.Step.Compile, |
| 650 | 662 | use_zig_libcxx: bool, |
| 651 | 663 | ) !void { |
| 652 | if (exe.target.isDarwin()) { | |
| 664 | if (exe.rootModuleTarget().isDarwin()) { | |
| 653 | 665 | // useful for package maintainers |
| 654 | 666 | exe.headerpad_max_install_names = true; |
| 655 | 667 | } |
| ... | ... | @@ -677,8 +689,8 @@ fn addCmakeCfgOptionsToExe( |
| 677 | 689 | // against system-provided LLVM, Clang, LLD. |
| 678 | 690 | const need_cpp_includes = true; |
| 679 | 691 | 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) { | |
| 682 | 694 | .linux => { |
| 683 | 695 | // First we try to link against the detected libcxx name. If that doesn't work, we fall |
| 684 | 696 | // back to -lc++ and cross our fingers. |
| ... | ... | @@ -694,7 +706,7 @@ fn addCmakeCfgOptionsToExe( |
| 694 | 706 | exe.linkLibCpp(); |
| 695 | 707 | }, |
| 696 | 708 | .windows => { |
| 697 | if (exe.target.getAbi() != .msvc) exe.linkLibCpp(); | |
| 709 | if (exe.rootModuleTarget().abi != .msvc) exe.linkLibCpp(); | |
| 698 | 710 | }, |
| 699 | 711 | .freebsd => { |
| 700 | 712 | if (static) { |
| ... | ... | @@ -756,12 +768,12 @@ fn addStaticLlvmOptionsToExe(exe: *std.Build.Step.Compile) !void { |
| 756 | 768 | exe.linkSystemLibrary("z"); |
| 757 | 769 | exe.linkSystemLibrary("zstd"); |
| 758 | 770 | |
| 759 | if (exe.target.getOs().tag != .windows or exe.target.getAbi() != .msvc) { | |
| 771 | if (exe.rootModuleTarget().os.tag != .windows or exe.rootModuleTarget().abi != .msvc) { | |
| 760 | 772 | // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries. |
| 761 | 773 | exe.linkSystemLibrary("c++"); |
| 762 | 774 | } |
| 763 | 775 | |
| 764 | if (exe.target.getOs().tag == .windows) { | |
| 776 | if (exe.rootModuleTarget().os.tag == .windows) { | |
| 765 | 777 | exe.linkSystemLibrary("version"); |
| 766 | 778 | exe.linkSystemLibrary("uuid"); |
| 767 | 779 | exe.linkSystemLibrary("ole32"); |
| ... | ... | @@ -810,7 +822,9 @@ fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void { |
| 810 | 822 | while (it.next()) |lib| { |
| 811 | 823 | if (mem.startsWith(u8, lib, "-l")) { |
| 812 | 824 | 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 | { | |
| 814 | 828 | exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]); |
| 815 | 829 | } else { |
| 816 | 830 | 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..." |
| 76 | 76 | CheckLastExitCode |
| 77 | 77 | |
| 78 | 78 | & "stage3-debug\bin\zig.exe" build-obj ` |
| 79 | ..\lib\compiler_rt.zig ` | |
| 80 | 79 | --zig-lib-dir "$ZIG_LIB_DIR" ` |
| 81 | 80 | -ofmt=c ` |
| 82 | 81 | -OReleaseSmall ` |
| 83 | 82 | --name compiler_rt ` |
| 84 | 83 | -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 | |
| 88 | 88 | CheckLastExitCode |
| 89 | 89 | |
| 90 | 90 | Import-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..." |
| 75 | 75 | CheckLastExitCode |
| 76 | 76 | |
| 77 | 77 | & "stage3-release\bin\zig.exe" build-obj ` |
| 78 | ..\lib\compiler_rt.zig ` | |
| 79 | 78 | --zig-lib-dir "$ZIG_LIB_DIR" ` |
| 80 | 79 | -ofmt=c ` |
| 81 | 80 | -OReleaseSmall ` |
| 82 | 81 | --name compiler_rt ` |
| 83 | 82 | -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 | |
| 87 | 87 | CheckLastExitCode |
| 88 | 88 | |
| 89 | 89 | Import-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( |
| 366 | 366 | } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) { |
| 367 | 367 | d.only_preprocess_and_compile = true; |
| 368 | 368 | } 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 { | |
| 370 | 370 | try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{}); |
| 371 | 371 | continue; |
| 372 | 372 | }; |
| 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)); | |
| 375 | 378 | d.raw_target_triple = triple; |
| 376 | 379 | } else if (mem.eql(u8, arg, "--verbose-ast")) { |
| 377 | 380 | d.verbose_ast = true; |
deps/aro/build/GenerateDef.zig+2-2| ... | ... | @@ -21,7 +21,7 @@ pub const Options = struct { |
| 21 | 21 | pub const Kind = enum { dafsa, named }; |
| 22 | 22 | }; |
| 23 | 23 | |
| 24 | pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency { | |
| 24 | pub fn create(owner: *std.Build, options: Options) std.Build.Module.Import { | |
| 25 | 25 | const self = owner.allocator.create(GenerateDef) catch @panic("OOM"); |
| 26 | 26 | const path = owner.pathJoin(&.{ options.src_prefix, options.name }); |
| 27 | 27 | |
| ... | ... | @@ -39,7 +39,7 @@ pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency { |
| 39 | 39 | .generated_file = .{ .step = &self.step }, |
| 40 | 40 | }; |
| 41 | 41 | const module = self.step.owner.createModule(.{ |
| 42 | .source_file = .{ .generated = &self.generated_file }, | |
| 42 | .root_source_file = .{ .generated = &self.generated_file }, | |
| 43 | 43 | }); |
| 44 | 44 | return .{ |
| 45 | 45 | .module = module, |
lib/build_runner.zig+205-140| ... | ... | @@ -46,7 +46,10 @@ pub fn main() !void { |
| 46 | 46 | return error.InvalidArgs; |
| 47 | 47 | }; |
| 48 | 48 | |
| 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 | }; | |
| 50 | 53 | |
| 51 | 54 | const build_root_directory: std.Build.Cache.Directory = .{ |
| 52 | 55 | .path = build_root, |
| ... | ... | @@ -96,6 +99,7 @@ pub fn main() !void { |
| 96 | 99 | var skip_oom_steps: bool = false; |
| 97 | 100 | var color: Color = .auto; |
| 98 | 101 | var seed: u32 = 0; |
| 102 | var prominent_compile_errors: bool = false; | |
| 99 | 103 | |
| 100 | 104 | const stderr_stream = io.getStdErr().writer(); |
| 101 | 105 | const stdout_stream = io.getStdOut().writer(); |
| ... | ... | @@ -239,6 +243,8 @@ pub fn main() !void { |
| 239 | 243 | builder.verbose_cc = true; |
| 240 | 244 | } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) { |
| 241 | 245 | builder.verbose_llvm_cpu_features = true; |
| 246 | } else if (mem.eql(u8, arg, "--prominent-compile-errors")) { | |
| 247 | prominent_compile_errors = true; | |
| 242 | 248 | } else if (mem.eql(u8, arg, "-fwine")) { |
| 243 | 249 | builder.enable_wine = true; |
| 244 | 250 | } else if (mem.eql(u8, arg, "-fno-wine")) { |
| ... | ... | @@ -322,6 +328,7 @@ pub fn main() !void { |
| 322 | 328 | .max_rss_mutex = .{}, |
| 323 | 329 | .skip_oom_steps = skip_oom_steps, |
| 324 | 330 | .memory_blocked_steps = std.ArrayList(*Step).init(arena), |
| 331 | .prominent_compile_errors = prominent_compile_errors, | |
| 325 | 332 | |
| 326 | 333 | .claimed_rss = 0, |
| 327 | 334 | .summary = summary, |
| ... | ... | @@ -354,11 +361,12 @@ const Run = struct { |
| 354 | 361 | max_rss_mutex: std.Thread.Mutex, |
| 355 | 362 | skip_oom_steps: bool, |
| 356 | 363 | memory_blocked_steps: std.ArrayList(*Step), |
| 364 | prominent_compile_errors: bool, | |
| 357 | 365 | |
| 358 | 366 | claimed_rss: usize, |
| 359 | 367 | summary: ?Summary, |
| 360 | 368 | ttyconf: std.io.tty.Config, |
| 361 | stderr: std.fs.File, | |
| 369 | stderr: File, | |
| 362 | 370 | }; |
| 363 | 371 | |
| 364 | 372 | fn runStepNames( |
| ... | ... | @@ -558,7 +566,7 @@ fn runStepNames( |
| 558 | 566 | // Finally, render compile errors at the bottom of the terminal. |
| 559 | 567 | // We use a separate compile_error_steps array list because step_stack is destructively |
| 560 | 568 | // mutated in printTreeStep above. |
| 561 | if (total_compile_errors > 0) { | |
| 569 | if (run.prominent_compile_errors and total_compile_errors > 0) { | |
| 562 | 570 | for (compile_error_steps.items) |s| { |
| 563 | 571 | if (s.result_error_bundle.errorMessageCount() > 0) { |
| 564 | 572 | s.result_error_bundle.renderToStdErr(renderOptions(ttyconf)); |
| ... | ... | @@ -579,7 +587,7 @@ const PrintNode = struct { |
| 579 | 587 | last: bool = false, |
| 580 | 588 | }; |
| 581 | 589 | |
| 582 | fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.io.tty.Config) !void { | |
| 590 | fn printPrefix(node: *PrintNode, stderr: File, ttyconf: std.io.tty.Config) !void { | |
| 583 | 591 | const parent = node.parent orelse return; |
| 584 | 592 | if (parent.parent == null) return; |
| 585 | 593 | try printPrefix(parent, stderr, ttyconf); |
| ... | ... | @@ -593,11 +601,145 @@ fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.io.tty.Config |
| 593 | 601 | } |
| 594 | 602 | } |
| 595 | 603 | |
| 604 | fn 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 | ||
| 611 | fn 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 | ||
| 691 | fn 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 | ||
| 596 | 738 | fn printTreeStep( |
| 597 | 739 | b: *std.Build, |
| 598 | 740 | s: *Step, |
| 599 | 741 | run: *const Run, |
| 600 | stderr: std.fs.File, | |
| 742 | stderr: File, | |
| 601 | 743 | ttyconf: std.io.tty.Config, |
| 602 | 744 | parent_node: *PrintNode, |
| 603 | 745 | step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), |
| ... | ... | @@ -610,10 +752,7 @@ fn printTreeStep( |
| 610 | 752 | if (!first) try ttyconf.setColor(stderr, .dim); |
| 611 | 753 | if (parent_node.parent != null) { |
| 612 | 754 | 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); | |
| 617 | 756 | } else { |
| 618 | 757 | try stderr.writeAll(switch (ttyconf) { |
| 619 | 758 | .no_color, .windows_api => "+- ", |
| ... | ... | @@ -626,119 +765,7 @@ fn printTreeStep( |
| 626 | 765 | try stderr.writeAll(s.name); |
| 627 | 766 | |
| 628 | 767 | 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); | |
| 742 | 769 | |
| 743 | 770 | const last_index = if (!failures_only) s.dependencies.items.len -| 1 else blk: { |
| 744 | 771 | var i: usize = s.dependencies.items.len; |
| ... | ... | @@ -888,26 +915,15 @@ fn workerMakeOneStep( |
| 888 | 915 | const make_result = s.make(&sub_prog_node); |
| 889 | 916 | |
| 890 | 917 | // 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) { | |
| 892 | 923 | sub_prog_node.context.lock_stderr(); |
| 893 | 924 | defer sub_prog_node.context.unlock_stderr(); |
| 894 | 925 | |
| 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 {}; | |
| 911 | 927 | } |
| 912 | 928 | |
| 913 | 929 | handle_result: { |
| ... | ... | @@ -962,6 +978,54 @@ fn workerMakeOneStep( |
| 962 | 978 | } |
| 963 | 979 | } |
| 964 | 980 | |
| 981 | fn 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 | ||
| 965 | 1029 | fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !void { |
| 966 | 1030 | // run the build script to collect the options |
| 967 | 1031 | if (!already_ran_build) { |
| ... | ... | @@ -1027,6 +1091,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi |
| 1027 | 1091 | \\ -l, --list-steps Print available steps |
| 1028 | 1092 | \\ --verbose Print commands before executing them |
| 1029 | 1093 | \\ --color [auto|off|on] Enable or disable colored error messages |
| 1094 | \\ --prominent-compile-errors Buffer compile errors and display at end | |
| 1030 | 1095 | \\ --summary [mode] Control the printing of the build summary |
| 1031 | 1096 | \\ all Print the build summary in its entirety |
| 1032 | 1097 | \\ failures (Default) Only print failed steps |
| ... | ... | @@ -1111,7 +1176,7 @@ fn cleanExit() void { |
| 1111 | 1176 | const Color = enum { auto, off, on }; |
| 1112 | 1177 | const Summary = enum { all, failures, none }; |
| 1113 | 1178 | |
| 1114 | fn get_tty_conf(color: Color, stderr: std.fs.File) std.io.tty.Config { | |
| 1179 | fn get_tty_conf(color: Color, stderr: File) std.io.tty.Config { | |
| 1115 | 1180 | return switch (color) { |
| 1116 | 1181 | .auto => std.io.tty.detectConfig(stderr), |
| 1117 | 1182 | .on => .escape_codes, |
lib/std/Build.zig+207-287| ... | ... | @@ -10,55 +10,17 @@ const log = std.log; |
| 10 | 10 | const ArrayList = std.ArrayList; |
| 11 | 11 | const StringHashMap = std.StringHashMap; |
| 12 | 12 | const Allocator = mem.Allocator; |
| 13 | const Target = std.Target; | |
| 13 | 14 | const process = std.process; |
| 14 | 15 | const EnvMap = std.process.EnvMap; |
| 15 | 16 | const fmt_lib = std.fmt; |
| 16 | 17 | const File = std.fs.File; |
| 17 | const CrossTarget = std.zig.CrossTarget; | |
| 18 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; | |
| 19 | 18 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 20 | 19 | const Build = @This(); |
| 21 | 20 | |
| 22 | 21 | pub const Cache = @import("Build/Cache.zig"); |
| 23 | ||
| 24 | /// deprecated: use `Step.Compile`. | |
| 25 | pub const LibExeObjStep = Step.Compile; | |
| 26 | /// deprecated: use `Build`. | |
| 27 | pub const Builder = Build; | |
| 28 | /// deprecated: use `Step.InstallDir.Options` | |
| 29 | pub const InstallDirectoryOptions = Step.InstallDir.Options; | |
| 30 | ||
| 31 | 22 | pub const Step = @import("Build/Step.zig"); |
| 32 | /// deprecated: use `Step.CheckFile`. | |
| 33 | pub const CheckFileStep = @import("Build/Step/CheckFile.zig"); | |
| 34 | /// deprecated: use `Step.CheckObject`. | |
| 35 | pub const CheckObjectStep = @import("Build/Step/CheckObject.zig"); | |
| 36 | /// deprecated: use `Step.ConfigHeader`. | |
| 37 | pub const ConfigHeaderStep = @import("Build/Step/ConfigHeader.zig"); | |
| 38 | /// deprecated: use `Step.Fmt`. | |
| 39 | pub const FmtStep = @import("Build/Step/Fmt.zig"); | |
| 40 | /// deprecated: use `Step.InstallArtifact`. | |
| 41 | pub const InstallArtifactStep = @import("Build/Step/InstallArtifact.zig"); | |
| 42 | /// deprecated: use `Step.InstallDir`. | |
| 43 | pub const InstallDirStep = @import("Build/Step/InstallDir.zig"); | |
| 44 | /// deprecated: use `Step.InstallFile`. | |
| 45 | pub const InstallFileStep = @import("Build/Step/InstallFile.zig"); | |
| 46 | /// deprecated: use `Step.ObjCopy`. | |
| 47 | pub const ObjCopyStep = @import("Build/Step/ObjCopy.zig"); | |
| 48 | /// deprecated: use `Step.Compile`. | |
| 49 | pub const CompileStep = @import("Build/Step/Compile.zig"); | |
| 50 | /// deprecated: use `Step.Options`. | |
| 51 | pub const OptionsStep = @import("Build/Step/Options.zig"); | |
| 52 | /// deprecated: use `Step.RemoveDir`. | |
| 53 | pub const RemoveDirStep = @import("Build/Step/RemoveDir.zig"); | |
| 54 | /// deprecated: use `Step.Run`. | |
| 55 | pub const RunStep = @import("Build/Step/Run.zig"); | |
| 56 | /// deprecated: use `Step.TranslateC`. | |
| 57 | pub const TranslateCStep = @import("Build/Step/TranslateC.zig"); | |
| 58 | /// deprecated: use `Step.WriteFile`. | |
| 59 | pub const WriteFileStep = @import("Build/Step/WriteFile.zig"); | |
| 60 | /// deprecated: use `LazyPath`. | |
| 61 | pub const FileSource = LazyPath; | |
| 23 | pub const Module = @import("Build/Module.zig"); | |
| 62 | 24 | |
| 63 | 25 | install_tls: TopLevelStep, |
| 64 | 26 | uninstall_tls: TopLevelStep, |
| ... | ... | @@ -96,7 +58,6 @@ cache_root: Cache.Directory, |
| 96 | 58 | global_cache_root: Cache.Directory, |
| 97 | 59 | cache: *Cache, |
| 98 | 60 | zig_lib_dir: ?LazyPath, |
| 99 | vcpkg_root: VcpkgRoot = .unattempted, | |
| 100 | 61 | pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null, |
| 101 | 62 | args: ?[][]const u8 = null, |
| 102 | 63 | debug_log_scopes: []const []const u8 = &.{}, |
| ... | ... | @@ -124,7 +85,7 @@ enable_wine: bool = false, |
| 124 | 85 | glibc_runtimes_dir: ?[]const u8 = null, |
| 125 | 86 | |
| 126 | 87 | /// Information about the native target. Computed before build() is invoked. |
| 127 | host: NativeTargetInfo, | |
| 88 | host: ResolvedTarget, | |
| 128 | 89 | |
| 129 | 90 | dep_prefix: []const u8 = "", |
| 130 | 91 | |
| ... | ... | @@ -250,7 +211,7 @@ pub fn create( |
| 250 | 211 | build_root: Cache.Directory, |
| 251 | 212 | cache_root: Cache.Directory, |
| 252 | 213 | global_cache_root: Cache.Directory, |
| 253 | host: NativeTargetInfo, | |
| 214 | host: ResolvedTarget, | |
| 254 | 215 | cache: *Cache, |
| 255 | 216 | available_deps: AvailableDeps, |
| 256 | 217 | ) !*Build { |
| ... | ... | @@ -414,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption |
| 414 | 375 | const v = @field(args, field.name); |
| 415 | 376 | const T = @TypeOf(v); |
| 416 | 377 | switch (T) { |
| 417 | CrossTarget => { | |
| 378 | Target.Query => { | |
| 418 | 379 | user_input_options.put(field.name, .{ |
| 419 | 380 | .name = field.name, |
| 420 | 381 | .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") }, |
| ... | ... | @@ -422,12 +383,19 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption |
| 422 | 383 | }) catch @panic("OOM"); |
| 423 | 384 | user_input_options.put("cpu", .{ |
| 424 | 385 | .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") }, | |
| 431 | 399 | .used = false, |
| 432 | 400 | }) catch @panic("OOM"); |
| 433 | 401 | }, |
| ... | ... | @@ -633,45 +601,57 @@ pub fn addOptions(self: *Build) *Step.Options { |
| 633 | 601 | |
| 634 | 602 | pub const ExecutableOptions = struct { |
| 635 | 603 | 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, | |
| 636 | 608 | root_source_file: ?LazyPath = null, |
| 637 | 609 | version: ?std.SemanticVersion = null, |
| 638 | target: CrossTarget = .{}, | |
| 639 | 610 | optimize: std.builtin.OptimizeMode = .Debug, |
| 640 | 611 | linkage: ?Step.Compile.Linkage = null, |
| 641 | 612 | max_rss: usize = 0, |
| 642 | 613 | link_libc: ?bool = null, |
| 643 | 614 | 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, | |
| 644 | 621 | use_llvm: ?bool = null, |
| 645 | 622 | use_lld: ?bool = null, |
| 646 | 623 | zig_lib_dir: ?LazyPath = null, |
| 647 | main_mod_path: ?LazyPath = null, | |
| 648 | 624 | /// Embed a `.manifest` file in the compilation if the object format supports it. |
| 649 | 625 | /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference |
| 650 | 626 | /// Manifest files must have the extension `.manifest`. |
| 651 | 627 | /// Can be set regardless of target. The `.manifest` file will be ignored |
| 652 | 628 | /// if the target object format does not support embedded manifests. |
| 653 | 629 | win32_manifest: ?LazyPath = null, |
| 654 | ||
| 655 | /// Deprecated; use `main_mod_path`. | |
| 656 | main_pkg_path: ?LazyPath = null, | |
| 657 | 630 | }; |
| 658 | 631 | |
| 659 | 632 | pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { |
| 660 | 633 | return Step.Compile.create(b, .{ |
| 661 | 634 | .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 | }, | |
| 663 | 648 | .version = options.version, |
| 664 | .target = options.target, | |
| 665 | .optimize = options.optimize, | |
| 666 | 649 | .kind = .exe, |
| 667 | 650 | .linkage = options.linkage, |
| 668 | 651 | .max_rss = options.max_rss, |
| 669 | .link_libc = options.link_libc, | |
| 670 | .single_threaded = options.single_threaded, | |
| 671 | 652 | .use_llvm = options.use_llvm, |
| 672 | 653 | .use_lld = options.use_lld, |
| 673 | 654 | .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, | |
| 675 | 655 | .win32_manifest = options.win32_manifest, |
| 676 | 656 | }); |
| 677 | 657 | } |
| ... | ... | @@ -679,77 +659,99 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { |
| 679 | 659 | pub const ObjectOptions = struct { |
| 680 | 660 | name: []const u8, |
| 681 | 661 | 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, | |
| 683 | 665 | optimize: std.builtin.OptimizeMode, |
| 684 | 666 | max_rss: usize = 0, |
| 685 | 667 | link_libc: ?bool = null, |
| 686 | 668 | 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, | |
| 687 | 675 | use_llvm: ?bool = null, |
| 688 | 676 | use_lld: ?bool = null, |
| 689 | 677 | zig_lib_dir: ?LazyPath = null, |
| 690 | main_mod_path: ?LazyPath = null, | |
| 691 | ||
| 692 | /// Deprecated; use `main_mod_path`. | |
| 693 | main_pkg_path: ?LazyPath = null, | |
| 694 | 678 | }; |
| 695 | 679 | |
| 696 | 680 | pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile { |
| 697 | 681 | return Step.Compile.create(b, .{ |
| 698 | 682 | .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 | }, | |
| 702 | 696 | .kind = .obj, |
| 703 | 697 | .max_rss = options.max_rss, |
| 704 | .link_libc = options.link_libc, | |
| 705 | .single_threaded = options.single_threaded, | |
| 706 | 698 | .use_llvm = options.use_llvm, |
| 707 | 699 | .use_lld = options.use_lld, |
| 708 | 700 | .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, | |
| 710 | 701 | }); |
| 711 | 702 | } |
| 712 | 703 | |
| 713 | 704 | pub const SharedLibraryOptions = struct { |
| 714 | 705 | 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, | |
| 715 | 710 | root_source_file: ?LazyPath = null, |
| 716 | 711 | version: ?std.SemanticVersion = null, |
| 717 | target: CrossTarget, | |
| 718 | optimize: std.builtin.OptimizeMode, | |
| 719 | 712 | max_rss: usize = 0, |
| 720 | 713 | link_libc: ?bool = null, |
| 721 | 714 | 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, | |
| 722 | 721 | use_llvm: ?bool = null, |
| 723 | 722 | use_lld: ?bool = null, |
| 724 | 723 | zig_lib_dir: ?LazyPath = null, |
| 725 | main_mod_path: ?LazyPath = null, | |
| 726 | 724 | /// Embed a `.manifest` file in the compilation if the object format supports it. |
| 727 | 725 | /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference |
| 728 | 726 | /// Manifest files must have the extension `.manifest`. |
| 729 | 727 | /// Can be set regardless of target. The `.manifest` file will be ignored |
| 730 | 728 | /// if the target object format does not support embedded manifests. |
| 731 | 729 | win32_manifest: ?LazyPath = null, |
| 732 | ||
| 733 | /// Deprecated; use `main_mod_path`. | |
| 734 | main_pkg_path: ?LazyPath = null, | |
| 735 | 730 | }; |
| 736 | 731 | |
| 737 | 732 | pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile { |
| 738 | 733 | return Step.Compile.create(b, .{ |
| 739 | 734 | .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 | }, | |
| 741 | 748 | .kind = .lib, |
| 742 | 749 | .linkage = .dynamic, |
| 743 | 750 | .version = options.version, |
| 744 | .target = options.target, | |
| 745 | .optimize = options.optimize, | |
| 746 | 751 | .max_rss = options.max_rss, |
| 747 | .link_libc = options.link_libc, | |
| 748 | .single_threaded = options.single_threaded, | |
| 749 | 752 | .use_llvm = options.use_llvm, |
| 750 | 753 | .use_lld = options.use_lld, |
| 751 | 754 | .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, | |
| 753 | 755 | .win32_manifest = options.win32_manifest, |
| 754 | 756 | }); |
| 755 | 757 | } |
| ... | ... | @@ -757,44 +759,55 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile |
| 757 | 759 | pub const StaticLibraryOptions = struct { |
| 758 | 760 | name: []const u8, |
| 759 | 761 | 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, | |
| 761 | 765 | optimize: std.builtin.OptimizeMode, |
| 762 | 766 | version: ?std.SemanticVersion = null, |
| 763 | 767 | max_rss: usize = 0, |
| 764 | 768 | link_libc: ?bool = null, |
| 765 | 769 | 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, | |
| 766 | 776 | use_llvm: ?bool = null, |
| 767 | 777 | use_lld: ?bool = null, |
| 768 | 778 | zig_lib_dir: ?LazyPath = null, |
| 769 | main_mod_path: ?LazyPath = null, | |
| 770 | ||
| 771 | /// Deprecated; use `main_mod_path`. | |
| 772 | main_pkg_path: ?LazyPath = null, | |
| 773 | 779 | }; |
| 774 | 780 | |
| 775 | 781 | pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile { |
| 776 | 782 | return Step.Compile.create(b, .{ |
| 777 | 783 | .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 | }, | |
| 779 | 797 | .kind = .lib, |
| 780 | 798 | .linkage = .static, |
| 781 | 799 | .version = options.version, |
| 782 | .target = options.target, | |
| 783 | .optimize = options.optimize, | |
| 784 | 800 | .max_rss = options.max_rss, |
| 785 | .link_libc = options.link_libc, | |
| 786 | .single_threaded = options.single_threaded, | |
| 787 | 801 | .use_llvm = options.use_llvm, |
| 788 | 802 | .use_lld = options.use_lld, |
| 789 | 803 | .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, | |
| 791 | 804 | }); |
| 792 | 805 | } |
| 793 | 806 | |
| 794 | 807 | pub const TestOptions = struct { |
| 795 | 808 | name: []const u8 = "test", |
| 796 | 809 | root_source_file: LazyPath, |
| 797 | target: CrossTarget = .{}, | |
| 810 | target: ?ResolvedTarget = null, | |
| 798 | 811 | optimize: std.builtin.OptimizeMode = .Debug, |
| 799 | 812 | version: ?std.SemanticVersion = null, |
| 800 | 813 | max_rss: usize = 0, |
| ... | ... | @@ -802,38 +815,49 @@ pub const TestOptions = struct { |
| 802 | 815 | test_runner: ?[]const u8 = null, |
| 803 | 816 | link_libc: ?bool = null, |
| 804 | 817 | 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, | |
| 805 | 824 | use_llvm: ?bool = null, |
| 806 | 825 | use_lld: ?bool = null, |
| 807 | 826 | zig_lib_dir: ?LazyPath = null, |
| 808 | main_mod_path: ?LazyPath = null, | |
| 809 | ||
| 810 | /// Deprecated; use `main_mod_path`. | |
| 811 | main_pkg_path: ?LazyPath = null, | |
| 812 | 827 | }; |
| 813 | 828 | |
| 814 | 829 | pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { |
| 815 | 830 | return Step.Compile.create(b, .{ |
| 816 | 831 | .name = options.name, |
| 817 | 832 | .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 | }, | |
| 821 | 846 | .max_rss = options.max_rss, |
| 822 | 847 | .filter = options.filter, |
| 823 | 848 | .test_runner = options.test_runner, |
| 824 | .link_libc = options.link_libc, | |
| 825 | .single_threaded = options.single_threaded, | |
| 826 | 849 | .use_llvm = options.use_llvm, |
| 827 | 850 | .use_lld = options.use_lld, |
| 828 | 851 | .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, | |
| 830 | 852 | }); |
| 831 | 853 | } |
| 832 | 854 | |
| 833 | 855 | pub const AssemblyOptions = struct { |
| 834 | 856 | name: []const u8, |
| 835 | 857 | 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, | |
| 837 | 861 | optimize: std.builtin.OptimizeMode, |
| 838 | 862 | max_rss: usize = 0, |
| 839 | 863 | zig_lib_dir: ?LazyPath = null, |
| ... | ... | @@ -843,9 +867,10 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile { |
| 843 | 867 | const obj_step = Step.Compile.create(b, .{ |
| 844 | 868 | .name = options.name, |
| 845 | 869 | .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 | }, | |
| 849 | 874 | .max_rss = options.max_rss, |
| 850 | 875 | .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir, |
| 851 | 876 | }); |
| ... | ... | @@ -856,41 +881,17 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile { |
| 856 | 881 | /// This function creates a module and adds it to the package's module set, making |
| 857 | 882 | /// it available to other packages which depend on this one. |
| 858 | 883 | /// `createModule` can be used instead to create a private module. |
| 859 | pub fn addModule(b: *Build, name: []const u8, options: CreateModuleOptions) *Module { | |
| 860 | const module = b.createModule(options); | |
| 884 | pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module { | |
| 885 | const module = Module.create(b, options); | |
| 861 | 886 | b.modules.put(b.dupe(name), module) catch @panic("OOM"); |
| 862 | 887 | return module; |
| 863 | 888 | } |
| 864 | 889 | |
| 865 | pub const ModuleDependency = struct { | |
| 866 | name: []const u8, | |
| 867 | module: *Module, | |
| 868 | }; | |
| 869 | ||
| 870 | pub const CreateModuleOptions = struct { | |
| 871 | source_file: LazyPath, | |
| 872 | dependencies: []const ModuleDependency = &.{}, | |
| 873 | }; | |
| 874 | ||
| 875 | 890 | /// This function creates a private module, to be used by the current package, |
| 876 | 891 | /// but not exposed to other packages depending on this one. |
| 877 | 892 | /// `addModule` can be used instead to create a public module. |
| 878 | pub 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 | ||
| 888 | fn 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; | |
| 893 | pub fn createModule(b: *Build, options: Module.CreateOptions) *Module { | |
| 894 | return Module.create(b, options); | |
| 894 | 895 | } |
| 895 | 896 | |
| 896 | 897 | /// 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 { |
| 918 | 919 | run_step.enableTestRunnerMode(); |
| 919 | 920 | } |
| 920 | 921 | |
| 921 | if (exe.vcpkg_bin_path) |path| { | |
| 922 | run_step.addPathDir(path); | |
| 923 | } | |
| 924 | ||
| 925 | 922 | return run_step; |
| 926 | 923 | } |
| 927 | 924 | |
| ... | ... | @@ -1143,7 +1140,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_ |
| 1143 | 1140 | return null; |
| 1144 | 1141 | }, |
| 1145 | 1142 | .scalar => |s| { |
| 1146 | if (Step.Compile.BuildId.parse(s)) |build_id| { | |
| 1143 | if (std.zig.BuildId.parse(s)) |build_id| { | |
| 1147 | 1144 | return build_id; |
| 1148 | 1145 | } else |err| { |
| 1149 | 1146 | log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) }); |
| ... | ... | @@ -1208,19 +1205,25 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio |
| 1208 | 1205 | } |
| 1209 | 1206 | |
| 1210 | 1207 | pub 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 = .{}, | |
| 1214 | 1210 | }; |
| 1215 | 1211 | |
| 1212 | /// Exposes standard `zig build` options for choosing a target and additionally | |
| 1213 | /// resolves the target query. | |
| 1214 | pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) ResolvedTarget { | |
| 1215 | const query = b.standardTargetOptionsQueryOnly(args); | |
| 1216 | return b.resolveTargetQuery(query); | |
| 1217 | } | |
| 1218 | ||
| 1216 | 1219 | /// Exposes standard `zig build` options for choosing a target. |
| 1217 | pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) CrossTarget { | |
| 1218 | const maybe_triple = self.option( | |
| 1220 | pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query { | |
| 1221 | const maybe_triple = b.option( | |
| 1219 | 1222 | []const u8, |
| 1220 | 1223 | "target", |
| 1221 | 1224 | "The CPU architecture, OS, and ABI to build for", |
| 1222 | 1225 | ); |
| 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"); | |
| 1224 | 1227 | |
| 1225 | 1228 | if (maybe_triple == null and mcpu == null) { |
| 1226 | 1229 | return args.default_target; |
| ... | ... | @@ -1228,8 +1231,8 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros |
| 1228 | 1231 | |
| 1229 | 1232 | const triple = maybe_triple orelse "native"; |
| 1230 | 1233 | |
| 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(.{ | |
| 1233 | 1236 | .arch_os_abi = triple, |
| 1234 | 1237 | .cpu_features = mcpu, |
| 1235 | 1238 | .diagnostics = &diags, |
| ... | ... | @@ -1242,7 +1245,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros |
| 1242 | 1245 | for (diags.arch.?.allCpuModels()) |cpu| { |
| 1243 | 1246 | log.err(" {s}", .{cpu.name}); |
| 1244 | 1247 | } |
| 1245 | self.markInvalidUserInput(); | |
| 1248 | b.markInvalidUserInput(); | |
| 1246 | 1249 | return args.default_target; |
| 1247 | 1250 | }, |
| 1248 | 1251 | error.UnknownCpuFeature => { |
| ... | ... | @@ -1257,7 +1260,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros |
| 1257 | 1260 | for (diags.arch.?.allFeaturesList()) |feature| { |
| 1258 | 1261 | log.err(" {s}: {s}", .{ feature.name, feature.description }); |
| 1259 | 1262 | } |
| 1260 | self.markInvalidUserInput(); | |
| 1263 | b.markInvalidUserInput(); | |
| 1261 | 1264 | return args.default_target; |
| 1262 | 1265 | }, |
| 1263 | 1266 | error.UnknownOperatingSystem => { |
| ... | ... | @@ -1266,83 +1269,38 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros |
| 1266 | 1269 | \\Available operating systems: |
| 1267 | 1270 | \\ |
| 1268 | 1271 | , .{diags.os_name.?}); |
| 1269 | inline for (std.meta.fields(std.Target.Os.Tag)) |field| { | |
| 1272 | inline for (std.meta.fields(Target.Os.Tag)) |field| { | |
| 1270 | 1273 | log.err(" {s}", .{field.name}); |
| 1271 | 1274 | } |
| 1272 | self.markInvalidUserInput(); | |
| 1275 | b.markInvalidUserInput(); | |
| 1273 | 1276 | return args.default_target; |
| 1274 | 1277 | }, |
| 1275 | 1278 | else => |e| { |
| 1276 | 1279 | log.err("Unable to parse target '{s}': {s}\n", .{ triple, @errorName(e) }); |
| 1277 | self.markInvalidUserInput(); | |
| 1280 | b.markInvalidUserInput(); | |
| 1278 | 1281 | return args.default_target; |
| 1279 | 1282 | }, |
| 1280 | 1283 | }; |
| 1281 | 1284 | |
| 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; | |
| 1343 | 1291 | } |
| 1344 | 1292 | |
| 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; | |
| 1346 | 1304 | } |
| 1347 | 1305 | |
| 1348 | 1306 | pub 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 { |
| 1422 | 1380 | |
| 1423 | 1381 | fn typeToEnum(comptime T: type) TypeId { |
| 1424 | 1382 | return switch (T) { |
| 1425 | Step.Compile.BuildId => .build_id, | |
| 1383 | std.zig.BuildId => .build_id, | |
| 1426 | 1384 | else => return switch (@typeInfo(T)) { |
| 1427 | 1385 | .Int => .int, |
| 1428 | 1386 | .Float => .float, |
| ... | ... | @@ -1490,7 +1448,7 @@ pub fn installFile(self: *Build, src_path: []const u8, dest_rel_path: []const u8 |
| 1490 | 1448 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .prefix, dest_rel_path).step); |
| 1491 | 1449 | } |
| 1492 | 1450 | |
| 1493 | pub fn installDirectory(self: *Build, options: InstallDirectoryOptions) void { | |
| 1451 | pub fn installDirectory(self: *Build, options: Step.InstallDir.Options) void { | |
| 1494 | 1452 | self.getInstallStep().dependOn(&self.addInstallDirectory(options).step); |
| 1495 | 1453 | } |
| 1496 | 1454 | |
| ... | ... | @@ -1536,7 +1494,7 @@ pub fn addInstallFileWithDir( |
| 1536 | 1494 | return Step.InstallFile.create(self, source.dupe(self), install_dir, dest_rel_path); |
| 1537 | 1495 | } |
| 1538 | 1496 | |
| 1539 | pub fn addInstallDirectory(self: *Build, options: InstallDirectoryOptions) *Step.InstallDir { | |
| 1497 | pub fn addInstallDirectory(self: *Build, options: Step.InstallDir.Options) *Step.InstallDir { | |
| 1540 | 1498 | return Step.InstallDir.create(self, options); |
| 1541 | 1499 | } |
| 1542 | 1500 | |
| ... | ... | @@ -1593,7 +1551,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 { |
| 1593 | 1551 | |
| 1594 | 1552 | pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 { |
| 1595 | 1553 | // TODO report error for ambiguous situations |
| 1596 | const exe_extension = @as(CrossTarget, .{}).exeFileExt(); | |
| 1554 | const exe_extension = @as(Target.Query, .{}).exeFileExt(); | |
| 1597 | 1555 | for (self.search_prefixes.items) |search_prefix| { |
| 1598 | 1556 | for (names) |name| { |
| 1599 | 1557 | if (fs.path.isAbsolute(name)) { |
| ... | ... | @@ -1895,15 +1853,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void { |
| 1895 | 1853 | } |
| 1896 | 1854 | } |
| 1897 | 1855 | |
| 1898 | pub 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 | ||
| 1907 | 1856 | /// A file that is generated by a build step. |
| 1908 | 1857 | /// This struct is an interface that is meant to be used with `@fieldParentPtr` to implement the actual path logic. |
| 1909 | 1858 | pub const GeneratedFile = struct { |
| ... | ... | @@ -2048,34 +1997,6 @@ pub fn dumpBadGetPathHelp( |
| 2048 | 1997 | tty_config.setColor(w, .reset) catch {}; |
| 2049 | 1998 | } |
| 2050 | 1999 | |
| 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. | |
| 2054 | pub 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 | ||
| 2067 | pub const VcpkgRoot = union(VcpkgRootStatus) { | |
| 2068 | unattempted: void, | |
| 2069 | not_found: void, | |
| 2070 | found: []const u8, | |
| 2071 | }; | |
| 2072 | ||
| 2073 | pub const VcpkgRootStatus = enum { | |
| 2074 | unattempted, | |
| 2075 | not_found, | |
| 2076 | found, | |
| 2077 | }; | |
| 2078 | ||
| 2079 | 2000 | pub const InstallDir = union(enum) { |
| 2080 | 2001 | prefix: void, |
| 2081 | 2002 | lib: void, |
| ... | ... | @@ -2107,34 +2028,6 @@ pub const InstalledFile = struct { |
| 2107 | 2028 | } |
| 2108 | 2029 | }; |
| 2109 | 2030 | |
| 2110 | pub 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 | ||
| 2138 | 2031 | /// This function is intended to be called in the `configure` phase only. |
| 2139 | 2032 | /// It returns an absolute directory path, which is potentially going to be a |
| 2140 | 2033 | /// 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 { |
| 2165 | 2058 | return result; |
| 2166 | 2059 | } |
| 2167 | 2060 | |
| 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. | |
| 2065 | pub 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. | |
| 2072 | pub 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 | ||
| 2084 | pub fn wantSharedLibSymLinks(target: Target) bool { | |
| 2085 | return target.os.tag != .windows; | |
| 2086 | } | |
| 2087 | ||
| 2168 | 2088 | test { |
| 2169 | 2089 | _ = Cache; |
| 2170 | 2090 | _ = Step; |
lib/std/Build/Cache.zig+15-1| ... | ... | @@ -270,7 +270,7 @@ pub const HashHelper = struct { |
| 270 | 270 | .none => {}, |
| 271 | 271 | } |
| 272 | 272 | }, |
| 273 | std.Build.Step.Compile.BuildId => switch (x) { | |
| 273 | std.zig.BuildId => switch (x) { | |
| 274 | 274 | .none, .fast, .uuid, .sha1, .md5 => hh.add(std.meta.activeTag(x)), |
| 275 | 275 | .hexstring => |hex_string| hh.addBytes(hex_string.toSlice()), |
| 276 | 276 | }, |
| ... | ... | @@ -312,6 +312,20 @@ pub const HashHelper = struct { |
| 312 | 312 | ) catch unreachable; |
| 313 | 313 | return out_digest; |
| 314 | 314 | } |
| 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 | } | |
| 315 | 329 | }; |
| 316 | 330 | |
| 317 | 331 | pub const Lock = struct { |
lib/std/Build/Module.zig created+753| ... | ... | @@ -0,0 +1,753 @@ |
| 1 | /// The one responsible for creating this module. | |
| 2 | owner: *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. | |
| 6 | depending_steps: std.AutoArrayHashMapUnmanaged(*Step.Compile, void), | |
| 7 | root_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. | |
| 11 | import_table: std.StringArrayHashMapUnmanaged(*Module), | |
| 12 | ||
| 13 | resolved_target: ?std.Build.ResolvedTarget = null, | |
| 14 | optimize: ?std.builtin.OptimizeMode = null, | |
| 15 | dwarf_format: ?std.dwarf.Format, | |
| 16 | ||
| 17 | c_macros: std.ArrayListUnmanaged([]const u8), | |
| 18 | include_dirs: std.ArrayListUnmanaged(IncludeDir), | |
| 19 | lib_paths: std.ArrayListUnmanaged(LazyPath), | |
| 20 | rpaths: std.ArrayListUnmanaged(RPath), | |
| 21 | frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions), | |
| 22 | c_std: std.Build.CStd, | |
| 23 | link_objects: std.ArrayListUnmanaged(LinkObject), | |
| 24 | ||
| 25 | strip: ?bool, | |
| 26 | unwind_tables: ?bool, | |
| 27 | single_threaded: ?bool, | |
| 28 | stack_protector: ?bool, | |
| 29 | stack_check: ?bool, | |
| 30 | sanitize_c: ?bool, | |
| 31 | sanitize_thread: ?bool, | |
| 32 | code_model: std.builtin.CodeModel, | |
| 33 | valgrind: ?bool, | |
| 34 | pic: ?bool, | |
| 35 | red_zone: ?bool, | |
| 36 | omit_frame_pointer: ?bool, | |
| 37 | error_tracing: ?bool, | |
| 38 | link_libc: ?bool, | |
| 39 | link_libcpp: ?bool, | |
| 40 | ||
| 41 | /// Symbols to be exported when compiling to WebAssembly. | |
| 42 | export_symbol_names: []const []const u8 = &.{}, | |
| 43 | ||
| 44 | pub const RPath = union(enum) { | |
| 45 | lazy_path: LazyPath, | |
| 46 | special: []const u8, | |
| 47 | }; | |
| 48 | ||
| 49 | pub 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 | ||
| 59 | pub 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 | ||
| 81 | pub 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 | ||
| 89 | pub 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 | ||
| 101 | pub 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 | ||
| 123 | pub 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 | ||
| 133 | pub 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. | |
| 140 | pub 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 | ||
| 184 | pub const Import = struct { | |
| 185 | name: []const u8, | |
| 186 | module: *Module, | |
| 187 | }; | |
| 188 | ||
| 189 | pub 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 | ||
| 239 | pub 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`. | |
| 246 | pub 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`. | |
| 257 | fn 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 | ||
| 281 | fn 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 | ||
| 290 | fn addLazyPathDependenciesOnly(m: *Module, lazy_path: LazyPath) void { | |
| 291 | for (m.depending_steps.keys()) |compile| { | |
| 292 | lazy_path.addStepDependencies(&compile.step); | |
| 293 | } | |
| 294 | } | |
| 295 | ||
| 296 | fn 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 | ||
| 305 | fn 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`. | |
| 312 | pub 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 | ||
| 317 | pub fn addOptions(m: *Module, module_name: []const u8, options: *Step.Options) void { | |
| 318 | addImport(m, module_name, options.createModule()); | |
| 319 | } | |
| 320 | ||
| 321 | pub 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 | ||
| 387 | pub 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 | ||
| 406 | pub 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 | ||
| 414 | pub 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 | ||
| 443 | pub 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 | ||
| 448 | pub 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. | |
| 457 | pub 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 | ||
| 469 | pub 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. | |
| 481 | pub 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 | ||
| 495 | pub 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 | ||
| 501 | pub 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 | ||
| 507 | pub fn addObject(m: *Module, object: *Step.Compile) void { | |
| 508 | assert(object.kind == .obj); | |
| 509 | m.linkLibraryOrObject(object); | |
| 510 | } | |
| 511 | ||
| 512 | pub fn linkLibrary(m: *Module, library: *Step.Compile) void { | |
| 513 | assert(library.kind == .lib); | |
| 514 | m.linkLibraryOrObject(library); | |
| 515 | } | |
| 516 | ||
| 517 | pub 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 | ||
| 523 | pub 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 | ||
| 529 | pub 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 | ||
| 535 | pub 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 | ||
| 541 | pub 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 | ||
| 548 | pub 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 | ||
| 555 | pub 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 | ||
| 561 | pub 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 | ||
| 578 | pub 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. | |
| 589 | pub 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 | ||
| 594 | pub 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 | ||
| 716 | fn 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 | ||
| 726 | fn 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 | ||
| 743 | fn 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 | ||
| 749 | const Module = @This(); | |
| 750 | const std = @import("std"); | |
| 751 | const assert = std.debug.assert; | |
| 752 | const LazyPath = std.Build.LazyPath; | |
| 753 | const Step = std.Build.Step; |
lib/std/Build/Step/CheckObject.zig+26-22| ... | ... | @@ -44,11 +44,11 @@ pub fn create( |
| 44 | 44 | |
| 45 | 45 | const SearchPhrase = struct { |
| 46 | 46 | string: []const u8, |
| 47 | file_source: ?std.Build.LazyPath = null, | |
| 47 | lazy_path: ?std.Build.LazyPath = null, | |
| 48 | 48 | |
| 49 | 49 | 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) }); | |
| 52 | 52 | } |
| 53 | 53 | }; |
| 54 | 54 | |
| ... | ... | @@ -321,14 +321,14 @@ pub fn checkExact(self: *CheckObject, phrase: []const u8) void { |
| 321 | 321 | |
| 322 | 322 | /// Like `checkExact()` but takes an additional argument `LazyPath` which will be |
| 323 | 323 | /// resolved to a full search query in `make()`. |
| 324 | pub fn checkExactPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void { | |
| 325 | self.checkExactInner(phrase, file_source); | |
| 324 | pub fn checkExactPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { | |
| 325 | self.checkExactInner(phrase, lazy_path); | |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.LazyPath) void { | |
| 328 | fn checkExactInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { | |
| 329 | 329 | assert(self.checks.items.len > 0); |
| 330 | 330 | 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 }); | |
| 332 | 332 | } |
| 333 | 333 | |
| 334 | 334 | /// Adds a fuzzy match phrase to the latest created Check. |
| ... | ... | @@ -336,16 +336,20 @@ pub fn checkContains(self: *CheckObject, phrase: []const u8) void { |
| 336 | 336 | self.checkContainsInner(phrase, null); |
| 337 | 337 | } |
| 338 | 338 | |
| 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 | |
| 340 | 340 | /// resolved to a full search query in `make()`. |
| 341 | pub fn checkContainsPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void { | |
| 342 | self.checkContainsInner(phrase, file_source); | |
| 341 | pub fn checkContainsPath( | |
| 342 | self: *CheckObject, | |
| 343 | phrase: []const u8, | |
| 344 | lazy_path: std.Build.LazyPath, | |
| 345 | ) void { | |
| 346 | self.checkContainsInner(phrase, lazy_path); | |
| 343 | 347 | } |
| 344 | 348 | |
| 345 | fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { | |
| 349 | fn checkContainsInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { | |
| 346 | 350 | assert(self.checks.items.len > 0); |
| 347 | 351 | 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 }); | |
| 349 | 353 | } |
| 350 | 354 | |
| 351 | 355 | /// 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 { |
| 353 | 357 | self.checkExtractInner(phrase, null); |
| 354 | 358 | } |
| 355 | 359 | |
| 356 | /// Like `checkExtract()` but takes an additional argument `FileSource` which will be | |
| 360 | /// Like `checkExtract()` but takes an additional argument `LazyPath` which will be | |
| 357 | 361 | /// resolved to a full search query in `make()`. |
| 358 | pub fn checkExtractFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void { | |
| 359 | self.checkExtractInner(phrase, file_source); | |
| 362 | pub fn checkExtractLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { | |
| 363 | self.checkExtractInner(phrase, lazy_path); | |
| 360 | 364 | } |
| 361 | 365 | |
| 362 | fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { | |
| 366 | fn checkExtractInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { | |
| 363 | 367 | assert(self.checks.items.len > 0); |
| 364 | 368 | 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 }); | |
| 366 | 370 | } |
| 367 | 371 | |
| 368 | 372 | /// Adds another searched phrase to the latest created Check |
| ... | ... | @@ -371,16 +375,16 @@ pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void { |
| 371 | 375 | self.checkNotPresentInner(phrase, null); |
| 372 | 376 | } |
| 373 | 377 | |
| 374 | /// Like `checkExtract()` but takes an additional argument `FileSource` which will be | |
| 378 | /// Like `checkExtract()` but takes an additional argument `LazyPath` which will be | |
| 375 | 379 | /// resolved to a full search query in `make()`. |
| 376 | pub fn checkNotPresentFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void { | |
| 377 | self.checkNotPresentInner(phrase, file_source); | |
| 380 | pub fn checkNotPresentLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { | |
| 381 | self.checkNotPresentInner(phrase, lazy_path); | |
| 378 | 382 | } |
| 379 | 383 | |
| 380 | fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { | |
| 384 | fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { | |
| 381 | 385 | assert(self.checks.items.len > 0); |
| 382 | 386 | 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 }); | |
| 384 | 388 | } |
| 385 | 389 | |
| 386 | 390 | /// 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; |
| 9 | 9 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 10 | 10 | const Allocator = mem.Allocator; |
| 11 | 11 | const Step = std.Build.Step; |
| 12 | const CrossTarget = std.zig.CrossTarget; | |
| 13 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; | |
| 14 | 12 | const LazyPath = std.Build.LazyPath; |
| 15 | 13 | const PkgConfigPkg = std.Build.PkgConfigPkg; |
| 16 | 14 | const PkgConfigError = std.Build.PkgConfigError; |
| 17 | 15 | const RunError = std.Build.RunError; |
| 18 | 16 | const Module = std.Build.Module; |
| 19 | const VcpkgRoot = std.Build.VcpkgRoot; | |
| 20 | 17 | const InstallDir = std.Build.InstallDir; |
| 21 | 18 | const GeneratedFile = std.Build.GeneratedFile; |
| 22 | 19 | const Compile = @This(); |
| ... | ... | @@ -24,36 +21,24 @@ const Compile = @This(); |
| 24 | 21 | pub const base_id: Step.Id = .compile; |
| 25 | 22 | |
| 26 | 23 | step: Step, |
| 24 | root_module: Module, | |
| 25 | ||
| 27 | 26 | name: []const u8, |
| 28 | target: CrossTarget, | |
| 29 | target_info: NativeTargetInfo, | |
| 30 | optimize: std.builtin.OptimizeMode, | |
| 31 | 27 | linker_script: ?LazyPath = null, |
| 32 | 28 | version_script: ?[]const u8 = null, |
| 33 | 29 | out_filename: []const u8, |
| 30 | out_lib_filename: []const u8, | |
| 34 | 31 | linkage: ?Linkage = null, |
| 35 | 32 | version: ?std.SemanticVersion, |
| 36 | 33 | kind: Kind, |
| 37 | 34 | major_only_filename: ?[]const u8, |
| 38 | 35 | name_only_filename: ?[]const u8, |
| 39 | strip: ?bool, | |
| 40 | formatted_panics: ?bool = null, | |
| 41 | unwind_tables: ?bool, | |
| 42 | 36 | // keep in sync with src/link.zig:CompressDebugSections |
| 43 | 37 | compress_debug_sections: enum { none, zlib, zstd } = .none, |
| 44 | lib_paths: ArrayList(LazyPath), | |
| 45 | rpaths: ArrayList(LazyPath), | |
| 46 | frameworks: StringHashMap(FrameworkLinkInfo), | |
| 47 | 38 | verbose_link: bool, |
| 48 | 39 | verbose_cc: bool, |
| 49 | 40 | bundle_compiler_rt: ?bool = null, |
| 50 | single_threaded: ?bool, | |
| 51 | stack_protector: ?bool = null, | |
| 52 | disable_stack_probing: bool, | |
| 53 | disable_sanitize_c: bool, | |
| 54 | sanitize_thread: bool, | |
| 55 | 41 | rdynamic: bool, |
| 56 | dwarf_format: ?std.dwarf.Format = null, | |
| 57 | 42 | import_memory: bool = false, |
| 58 | 43 | export_memory: bool = false, |
| 59 | 44 | /// For WebAssembly targets, this will allow for undefined symbols to |
| ... | ... | @@ -65,32 +50,16 @@ initial_memory: ?u64 = null, |
| 65 | 50 | max_memory: ?u64 = null, |
| 66 | 51 | shared_memory: bool = false, |
| 67 | 52 | global_base: ?u64 = null, |
| 68 | c_std: std.Build.CStd, | |
| 69 | 53 | /// Set via options; intended to be read-only after that. |
| 70 | 54 | zig_lib_dir: ?LazyPath, |
| 71 | /// Set via options; intended to be read-only after that. | |
| 72 | main_mod_path: ?LazyPath, | |
| 73 | 55 | exec_cmd_args: ?[]const ?[]const u8, |
| 74 | 56 | filter: ?[]const u8, |
| 75 | 57 | test_evented_io: bool = false, |
| 76 | 58 | test_runner: ?[]const u8, |
| 77 | 59 | test_server_mode: bool, |
| 78 | code_model: std.builtin.CodeModel = .default, | |
| 79 | 60 | wasi_exec_model: ?std.builtin.WasiExecModel = null, |
| 80 | /// Symbols to be exported when compiling to wasm | |
| 81 | export_symbol_names: []const []const u8 = &.{}, | |
| 82 | 61 | |
| 83 | root_src: ?LazyPath, | |
| 84 | out_lib_filename: []const u8, | |
| 85 | modules: std.StringArrayHashMap(*Module), | |
| 86 | ||
| 87 | link_objects: ArrayList(LinkObject), | |
| 88 | include_dirs: ArrayList(IncludeDir), | |
| 89 | c_macros: ArrayList([]const u8), | |
| 90 | 62 | installed_headers: ArrayList(*Step), |
| 91 | is_linking_libc: bool, | |
| 92 | is_linking_libcpp: bool, | |
| 93 | vcpkg_bin_path: ?[]const u8 = null, | |
| 94 | 63 | |
| 95 | 64 | // keep in sync with src/Compilation.zig:RcIncludes |
| 96 | 65 | /// Behavior of automatic detection of include directories when compiling .rc files. |
| ... | ... | @@ -111,14 +80,13 @@ image_base: ?u64 = null, |
| 111 | 80 | |
| 112 | 81 | libc_file: ?LazyPath = null, |
| 113 | 82 | |
| 114 | valgrind_support: ?bool = null, | |
| 115 | 83 | each_lib_rpath: ?bool = null, |
| 116 | 84 | /// On ELF targets, this will emit a link section called ".note.gnu.build-id" |
| 117 | 85 | /// which can be used to coordinate a stripped binary with its debug symbols. |
| 118 | 86 | /// As an example, the bloaty project refuses to work unless its inputs have |
| 119 | 87 | /// build ids, in order to prevent accidental mismatches. |
| 120 | 88 | /// The default is to not include this section because it slows down linking. |
| 121 | build_id: ?BuildId = null, | |
| 89 | build_id: ?std.zig.BuildId = null, | |
| 122 | 90 | |
| 123 | 91 | /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF |
| 124 | 92 | /// file. |
| ... | ... | @@ -177,15 +145,9 @@ headerpad_max_install_names: bool = false, |
| 177 | 145 | /// (Darwin) Remove dylibs that are unreachable by the entry point or exported symbols. |
| 178 | 146 | dead_strip_dylibs: bool = false, |
| 179 | 147 | |
| 180 | /// Position Independent Code | |
| 181 | force_pic: ?bool = null, | |
| 182 | ||
| 183 | 148 | /// Position Independent Executable |
| 184 | 149 | pie: ?bool = null, |
| 185 | 150 | |
| 186 | red_zone: ?bool = null, | |
| 187 | ||
| 188 | omit_frame_pointer: ?bool = null, | |
| 189 | 151 | dll_export_fns: ?bool = null, |
| 190 | 152 | |
| 191 | 153 | subsystem: ?std.Target.SubSystem = null, |
| ... | ... | @@ -226,91 +188,17 @@ generated_h: ?*GeneratedFile, |
| 226 | 188 | /// Defaults to `std.math.maxInt(u16)` |
| 227 | 189 | error_limit: ?u32 = null, |
| 228 | 190 | |
| 191 | /// Computed during make(). | |
| 192 | is_linking_libc: bool = false, | |
| 193 | /// Computed during make(). | |
| 194 | is_linking_libcpp: bool = false, | |
| 195 | ||
| 229 | 196 | pub const ExpectedCompileErrors = union(enum) { |
| 230 | 197 | contains: []const u8, |
| 231 | 198 | exact: []const []const u8, |
| 232 | 199 | }; |
| 233 | 200 | |
| 234 | pub 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 | ||
| 242 | pub 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 | ||
| 254 | pub 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 | ||
| 276 | pub 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 | ||
| 286 | pub 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 | ||
| 308 | const FrameworkLinkInfo = struct { | |
| 309 | needed: bool = false, | |
| 310 | weak: bool = false, | |
| 311 | }; | |
| 312 | ||
| 313 | const Entry = union(enum) { | |
| 201 | pub const Entry = union(enum) { | |
| 314 | 202 | /// Let the compiler decide whether to make an entry point and what to name |
| 315 | 203 | /// it. |
| 316 | 204 | default, |
| ... | ... | @@ -322,118 +210,24 @@ const Entry = union(enum) { |
| 322 | 210 | symbol_name: []const u8, |
| 323 | 211 | }; |
| 324 | 212 | |
| 325 | pub 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 | ||
| 335 | 213 | pub const Options = struct { |
| 336 | 214 | name: []const u8, |
| 337 | root_source_file: ?LazyPath = null, | |
| 338 | target: CrossTarget, | |
| 339 | optimize: std.builtin.OptimizeMode, | |
| 215 | root_module: Module.CreateOptions, | |
| 340 | 216 | kind: Kind, |
| 341 | 217 | linkage: ?Linkage = null, |
| 342 | 218 | version: ?std.SemanticVersion = null, |
| 343 | 219 | max_rss: usize = 0, |
| 344 | 220 | filter: ?[]const u8 = null, |
| 345 | 221 | test_runner: ?[]const u8 = null, |
| 346 | link_libc: ?bool = null, | |
| 347 | single_threaded: ?bool = null, | |
| 348 | 222 | use_llvm: ?bool = null, |
| 349 | 223 | use_lld: ?bool = null, |
| 350 | 224 | zig_lib_dir: ?LazyPath = null, |
| 351 | main_mod_path: ?LazyPath = null, | |
| 352 | 225 | /// Embed a `.manifest` file in the compilation if the object format supports it. |
| 353 | 226 | /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference |
| 354 | 227 | /// Manifest files must have the extension `.manifest`. |
| 355 | 228 | /// Can be set regardless of target. The `.manifest` file will be ignored |
| 356 | 229 | /// if the target object format does not support embedded manifests. |
| 357 | 230 | win32_manifest: ?LazyPath = null, |
| 358 | ||
| 359 | /// deprecated; use `main_mod_path`. | |
| 360 | main_pkg_path: ?LazyPath = null, | |
| 361 | }; | |
| 362 | ||
| 363 | pub 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 | } | |
| 437 | 231 | }; |
| 438 | 232 | |
| 439 | 233 | pub const Kind = enum { |
| ... | ... | @@ -447,7 +241,6 @@ pub const Linkage = enum { dynamic, static }; |
| 447 | 241 | |
| 448 | 242 | pub fn create(owner: *std.Build, options: Options) *Compile { |
| 449 | 243 | const name = owner.dupe(options.name); |
| 450 | const root_src: ?LazyPath = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null; | |
| 451 | 244 | if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { |
| 452 | 245 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); |
| 453 | 246 | } |
| ... | ... | @@ -458,6 +251,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 458 | 251 | else |
| 459 | 252 | owner.fmt("{s} ", .{name}); |
| 460 | 253 | |
| 254 | const resolved_target = options.root_module.target.?; | |
| 255 | const target = resolved_target.result; | |
| 256 | ||
| 461 | 257 | const step_name = owner.fmt("{s} {s}{s} {s}", .{ |
| 462 | 258 | switch (options.kind) { |
| 463 | 259 | .exe => "zig build-exe", |
| ... | ... | @@ -466,15 +262,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 466 | 262 | .@"test" => "zig test", |
| 467 | 263 | }, |
| 468 | 264 | 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"), | |
| 471 | 267 | }); |
| 472 | 268 | |
| 473 | const target_info = NativeTargetInfo.detect(options.target) catch @panic("unhandled error"); | |
| 474 | ||
| 475 | 269 | const out_filename = std.zig.binNameAlloc(owner.allocator, .{ |
| 476 | 270 | .root_name = name, |
| 477 | .target = target_info.target, | |
| 271 | .target = target, | |
| 478 | 272 | .output_mode = switch (options.kind) { |
| 479 | 273 | .lib => .Lib, |
| 480 | 274 | .obj => .Obj, |
| ... | ... | @@ -489,17 +283,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 489 | 283 | |
| 490 | 284 | const self = owner.allocator.create(Compile) catch @panic("OOM"); |
| 491 | 285 | self.* = .{ |
| 492 | .strip = null, | |
| 493 | .unwind_tables = null, | |
| 286 | .root_module = undefined, | |
| 494 | 287 | .verbose_link = false, |
| 495 | 288 | .verbose_cc = false, |
| 496 | .optimize = options.optimize, | |
| 497 | .target = options.target, | |
| 498 | 289 | .linkage = options.linkage, |
| 499 | 290 | .kind = options.kind, |
| 500 | .root_src = root_src, | |
| 501 | 291 | .name = name, |
| 502 | .frameworks = StringHashMap(FrameworkLinkInfo).init(owner.allocator), | |
| 503 | 292 | .step = Step.init(.{ |
| 504 | 293 | .id = base_id, |
| 505 | 294 | .name = step_name, |
| ... | ... | @@ -512,23 +301,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 512 | 301 | .out_lib_filename = undefined, |
| 513 | 302 | .major_only_filename = null, |
| 514 | 303 | .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), | |
| 521 | 304 | .installed_headers = ArrayList(*Step).init(owner.allocator), |
| 522 | .c_std = std.Build.CStd.C99, | |
| 523 | 305 | .zig_lib_dir = null, |
| 524 | .main_mod_path = null, | |
| 525 | 306 | .exec_cmd_args = null, |
| 526 | 307 | .filter = options.filter, |
| 527 | 308 | .test_runner = options.test_runner, |
| 528 | 309 | .test_server_mode = options.test_runner == null, |
| 529 | .disable_stack_probing = false, | |
| 530 | .disable_sanitize_c = false, | |
| 531 | .sanitize_thread = false, | |
| 532 | 310 | .rdynamic = false, |
| 533 | 311 | .installed_path = null, |
| 534 | 312 | .force_undefined_symbols = StringHashMap(void).init(owner.allocator), |
| ... | ... | @@ -543,28 +321,20 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 543 | 321 | .generated_llvm_ir = null, |
| 544 | 322 | .generated_h = null, |
| 545 | 323 | |
| 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, | |
| 551 | 324 | .use_llvm = options.use_llvm, |
| 552 | 325 | .use_lld = options.use_lld, |
| 553 | 326 | }; |
| 554 | 327 | |
| 328 | self.root_module.init(owner, options.root_module, self); | |
| 329 | ||
| 555 | 330 | if (options.zig_lib_dir) |lp| { |
| 556 | 331 | self.zig_lib_dir = lp.dupe(self.step.owner); |
| 557 | 332 | lp.addStepDependencies(&self.step); |
| 558 | 333 | } |
| 559 | 334 | |
| 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 | ||
| 565 | 335 | // Only the PE/COFF format has a Resource Table which is where the manifest |
| 566 | 336 | // gets embedded, so for any other target the manifest file is just ignored. |
| 567 | if (self.target.getObjectFormat() == .coff) { | |
| 337 | if (target.ofmt == .coff) { | |
| 568 | 338 | if (options.win32_manifest) |lp| { |
| 569 | 339 | self.win32_manifest = lp.dupe(self.step.owner); |
| 570 | 340 | lp.addStepDependencies(&self.step); |
| ... | ... | @@ -575,14 +345,14 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 575 | 345 | if (self.linkage != null and self.linkage.? == .static) { |
| 576 | 346 | self.out_lib_filename = self.out_filename; |
| 577 | 347 | } else if (self.version) |version| { |
| 578 | if (target_info.target.isDarwin()) { | |
| 348 | if (target.isDarwin()) { | |
| 579 | 349 | self.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{ |
| 580 | 350 | self.name, |
| 581 | 351 | version.major, |
| 582 | 352 | }); |
| 583 | 353 | self.name_only_filename = owner.fmt("lib{s}.dylib", .{self.name}); |
| 584 | 354 | self.out_lib_filename = self.out_filename; |
| 585 | } else if (target_info.target.os.tag == .windows) { | |
| 355 | } else if (target.os.tag == .windows) { | |
| 586 | 356 | self.out_lib_filename = owner.fmt("{s}.lib", .{self.name}); |
| 587 | 357 | } else { |
| 588 | 358 | 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 { |
| 590 | 360 | self.out_lib_filename = self.out_filename; |
| 591 | 361 | } |
| 592 | 362 | } else { |
| 593 | if (target_info.target.isDarwin()) { | |
| 363 | if (target.isDarwin()) { | |
| 594 | 364 | self.out_lib_filename = self.out_filename; |
| 595 | } else if (target_info.target.os.tag == .windows) { | |
| 365 | } else if (target.os.tag == .windows) { | |
| 596 | 366 | self.out_lib_filename = owner.fmt("{s}.lib", .{self.name}); |
| 597 | 367 | } else { |
| 598 | 368 | self.out_lib_filename = self.out_filename; |
| ... | ... | @@ -600,8 +370,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 600 | 370 | } |
| 601 | 371 | } |
| 602 | 372 | |
| 603 | if (root_src) |rs| rs.addStepDependencies(&self.step); | |
| 604 | ||
| 605 | 373 | return self; |
| 606 | 374 | } |
| 607 | 375 | |
| ... | ... | @@ -701,7 +469,7 @@ pub const run = @compileError("deprecated; use std.Build.addRunArtifact"); |
| 701 | 469 | pub const install = @compileError("deprecated; use std.Build.installArtifact"); |
| 702 | 470 | |
| 703 | 471 | pub 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); | |
| 705 | 473 | } |
| 706 | 474 | |
| 707 | 475 | /// deprecated: use `setLinkerScript` |
| ... | ... | @@ -718,113 +486,75 @@ pub fn forceUndefinedSymbol(self: *Compile, symbol_name: []const u8) void { |
| 718 | 486 | self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM"); |
| 719 | 487 | } |
| 720 | 488 | |
| 721 | pub 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 | ||
| 726 | pub 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 | ||
| 733 | pub 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 | ||
| 740 | 489 | /// Returns whether the library, executable, or object depends on a particular system library. |
| 741 | pub fn dependsOnSystemLibrary(self: Compile, name: []const u8) bool { | |
| 742 | if (isLibCLibrary(name)) { | |
| 743 | return self.is_linking_libc; | |
| 490 | /// Includes transitive dependencies. | |
| 491 | pub 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; | |
| 744 | 505 | } |
| 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; | |
| 747 | 509 | } |
| 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; | |
| 753 | 513 | } |
| 754 | return false; | |
| 755 | } | |
| 756 | 514 | |
| 757 | pub fn linkLibrary(self: *Compile, lib: *Compile) void { | |
| 758 | assert(lib.kind == .lib); | |
| 759 | self.linkLibraryOrObject(lib); | |
| 515 | return false; | |
| 760 | 516 | } |
| 761 | 517 | |
| 762 | pub fn isDynamicLibrary(self: *Compile) bool { | |
| 518 | pub fn isDynamicLibrary(self: *const Compile) bool { | |
| 763 | 519 | return self.kind == .lib and self.linkage == Linkage.dynamic; |
| 764 | 520 | } |
| 765 | 521 | |
| 766 | pub fn isStaticLibrary(self: *Compile) bool { | |
| 522 | pub fn isStaticLibrary(self: *const Compile) bool { | |
| 767 | 523 | return self.kind == .lib and self.linkage != Linkage.dynamic; |
| 768 | 524 | } |
| 769 | 525 | |
| 770 | 526 | pub fn producesPdbFile(self: *Compile) bool { |
| 527 | const target = self.rootModuleTarget(); | |
| 771 | 528 | // TODO: Is this right? Isn't PDB for *any* PE/COFF file? |
| 772 | 529 | // 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 | } | |
| 776 | 540 | return self.isDynamicLibrary() or self.kind == .exe or self.kind == .@"test"; |
| 777 | 541 | } |
| 778 | 542 | |
| 779 | 543 | pub fn producesImplib(self: *Compile) bool { |
| 780 | return self.isDynamicLibrary() and self.target.isWindows(); | |
| 544 | return self.isDynamicLibrary() and self.rootModuleTarget().os.tag == .windows; | |
| 781 | 545 | } |
| 782 | 546 | |
| 783 | 547 | pub fn linkLibC(self: *Compile) void { |
| 784 | self.is_linking_libc = true; | |
| 548 | self.root_module.link_libc = true; | |
| 785 | 549 | } |
| 786 | 550 | |
| 787 | 551 | pub 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. | |
| 793 | pub 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. | |
| 800 | pub 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 | |
| 806 | pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void { | |
| 807 | return linkSystemLibrary2(self, name, .{ .use_pkg_config = .no }); | |
| 808 | } | |
| 809 | ||
| 810 | /// deprecated: use linkSystemLibrary2 | |
| 811 | pub 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; | |
| 813 | 553 | } |
| 814 | 554 | |
| 815 | /// deprecated: use linkSystemLibrary2 | |
| 816 | pub 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 | |
| 821 | pub 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 | |
| 826 | pub 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`. | |
| 556 | pub fn defineCMacro(c: *Compile, name: []const u8, value: ?[]const u8) void { | |
| 557 | c.root_module.addCMacro(name, value orelse "1"); | |
| 828 | 558 | } |
| 829 | 559 | |
| 830 | 560 | /// 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 { |
| 924 | 654 | } |
| 925 | 655 | |
| 926 | 656 | pub fn linkSystemLibrary(self: *Compile, name: []const u8) void { |
| 927 | self.linkSystemLibrary2(name, .{}); | |
| 928 | } | |
| 929 | ||
| 930 | /// deprecated: use linkSystemLibrary2 | |
| 931 | pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void { | |
| 932 | return linkSystemLibrary2(self, name, .{ .needed = true }); | |
| 657 | return self.root_module.linkSystemLibrary(name, .{}); | |
| 933 | 658 | } |
| 934 | 659 | |
| 935 | /// deprecated: use linkSystemLibrary2 | |
| 936 | pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void { | |
| 937 | return linkSystemLibrary2(self, name, .{ .weak = true }); | |
| 938 | } | |
| 939 | ||
| 940 | pub 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 | ||
| 948 | 660 | pub fn linkSystemLibrary2( |
| 949 | 661 | self: *Compile, |
| 950 | 662 | name: []const u8, |
| 951 | options: LinkSystemLibraryOptions, | |
| 663 | options: Module.LinkSystemLibraryOptions, | |
| 952 | 664 | ) 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); | |
| 973 | 666 | } |
| 974 | 667 | |
| 975 | pub 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 | }; | |
| 668 | pub fn linkFramework(c: *Compile, name: []const u8) void { | |
| 669 | c.root_module.linkFramework(name, .{}); | |
| 670 | } | |
| 981 | 671 | |
| 982 | /// Handy when you have many C/C++ source files and want them all to have the same flags. | |
| 983 | pub 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`. | |
| 673 | pub fn linkFrameworkNeeded(c: *Compile, name: []const u8) void { | |
| 674 | c.root_module.linkFramework(name, .{ .needed = true }); | |
| 675 | } | |
| 986 | 676 | |
| 987 | const files_copy = b.dupeStrings(options.files); | |
| 988 | const flags_copy = b.dupeStrings(options.flags); | |
| 677 | /// Deprecated. Use `c.root_module.linkFramework`. | |
| 678 | pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void { | |
| 679 | c.root_module.linkFramework(name, .{ .weak = true }); | |
| 680 | } | |
| 989 | 681 | |
| 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. | |
| 683 | pub fn addCSourceFiles(self: *Compile, options: Module.AddCSourceFilesOptions) void { | |
| 684 | self.root_module.addCSourceFiles(options); | |
| 996 | 685 | } |
| 997 | 686 | |
| 998 | pub 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); | |
| 687 | pub fn addCSourceFile(self: *Compile, source: Module.CSourceFile) void { | |
| 688 | self.root_module.addCSourceFile(source); | |
| 1004 | 689 | } |
| 1005 | 690 | |
| 1006 | 691 | /// Resource files must have the extension `.rc`. |
| 1007 | 692 | /// Can be called regardless of target. The .rc file will be ignored |
| 1008 | 693 | /// if the target object format does not support embedded resources. |
| 1009 | pub 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); | |
| 694 | pub fn addWin32ResourceFile(self: *Compile, source: Module.RcSourceFile) void { | |
| 695 | self.root_module.addWin32ResourceFile(source); | |
| 1019 | 696 | } |
| 1020 | 697 | |
| 1021 | 698 | pub fn setVerboseLink(self: *Compile, value: bool) void { |
| ... | ... | @@ -1042,27 +719,18 @@ fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath |
| 1042 | 719 | return .{ .generated = generated_file }; |
| 1043 | 720 | } |
| 1044 | 721 | |
| 1045 | /// deprecated: use `getEmittedBinDirectory` | |
| 1046 | pub const getOutputDirectorySource = getEmittedBinDirectory; | |
| 1047 | ||
| 1048 | 722 | /// Returns the path to the directory that contains the emitted binary file. |
| 1049 | 723 | pub fn getEmittedBinDirectory(self: *Compile) LazyPath { |
| 1050 | 724 | _ = self.getEmittedBin(); |
| 1051 | 725 | return self.getEmittedFileGeneric(&self.emit_directory); |
| 1052 | 726 | } |
| 1053 | 727 | |
| 1054 | /// deprecated: use `getEmittedBin` | |
| 1055 | pub const getOutputSource = getEmittedBin; | |
| 1056 | ||
| 1057 | 728 | /// Returns the path to the generated executable, library or object file. |
| 1058 | 729 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. |
| 1059 | 730 | pub fn getEmittedBin(self: *Compile) LazyPath { |
| 1060 | 731 | return self.getEmittedFileGeneric(&self.generated_bin); |
| 1061 | 732 | } |
| 1062 | 733 | |
| 1063 | /// deprecated: use `getEmittedImplib` | |
| 1064 | pub const getOutputLibSource = getEmittedImplib; | |
| 1065 | ||
| 1066 | 734 | /// Returns the path to the generated import library. |
| 1067 | 735 | /// This function can only be called for libraries. |
| 1068 | 736 | pub fn getEmittedImplib(self: *Compile) LazyPath { |
| ... | ... | @@ -1070,9 +738,6 @@ pub fn getEmittedImplib(self: *Compile) LazyPath { |
| 1070 | 738 | return self.getEmittedFileGeneric(&self.generated_implib); |
| 1071 | 739 | } |
| 1072 | 740 | |
| 1073 | /// deprecated: use `getEmittedH` | |
| 1074 | pub const getOutputHSource = getEmittedH; | |
| 1075 | ||
| 1076 | 741 | /// Returns the path to the generated header file. |
| 1077 | 742 | /// This function can only be called for libraries or objects. |
| 1078 | 743 | pub fn getEmittedH(self: *Compile) LazyPath { |
| ... | ... | @@ -1080,9 +745,6 @@ pub fn getEmittedH(self: *Compile) LazyPath { |
| 1080 | 745 | return self.getEmittedFileGeneric(&self.generated_h); |
| 1081 | 746 | } |
| 1082 | 747 | |
| 1083 | /// deprecated: use `getEmittedPdb`. | |
| 1084 | pub const getOutputPdbSource = getEmittedPdb; | |
| 1085 | ||
| 1086 | 748 | /// Returns the generated PDB file. |
| 1087 | 749 | /// If the compilation does not produce a PDB file, this causes a FileNotFound error |
| 1088 | 750 | /// at build time. |
| ... | ... | @@ -1112,138 +774,51 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath { |
| 1112 | 774 | } |
| 1113 | 775 | |
| 1114 | 776 | pub 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); | |
| 1119 | 778 | } |
| 1120 | 779 | |
| 1121 | 780 | pub 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 | ||
| 1127 | pub fn addObject(self: *Compile, obj: *Compile) void { | |
| 1128 | assert(obj.kind == .obj); | |
| 1129 | self.linkLibraryOrObject(obj); | |
| 781 | self.root_module.addObjectFile(source); | |
| 1130 | 782 | } |
| 1131 | 783 | |
| 1132 | pub 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 | ||
| 1138 | pub 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); | |
| 784 | pub fn addObject(self: *Compile, object: *Compile) void { | |
| 785 | self.root_module.addObject(object); | |
| 1142 | 786 | } |
| 1143 | 787 | |
| 1144 | pub 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 | ||
| 1150 | pub 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 | ||
| 1155 | pub 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); | |
| 788 | pub fn linkLibrary(self: *Compile, library: *Compile) void { | |
| 789 | self.root_module.linkLibrary(library); | |
| 1159 | 790 | } |
| 1160 | 791 | |
| 1161 | pub 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); | |
| 792 | pub fn addAfterIncludePath(self: *Compile, lazy_path: LazyPath) void { | |
| 793 | self.root_module.addAfterIncludePath(lazy_path); | |
| 1165 | 794 | } |
| 1166 | 795 | |
| 1167 | pub 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); | |
| 796 | pub fn addSystemIncludePath(self: *Compile, lazy_path: LazyPath) void { | |
| 797 | self.root_module.addSystemIncludePath(lazy_path); | |
| 1171 | 798 | } |
| 1172 | 799 | |
| 1173 | pub 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); | |
| 800 | pub fn addIncludePath(self: *Compile, lazy_path: LazyPath) void { | |
| 801 | self.root_module.addIncludePath(lazy_path); | |
| 1177 | 802 | } |
| 1178 | 803 | |
| 1179 | /// Adds a module to be used with `@import` and exposing it in the current | |
| 1180 | /// package's module table using `name`. | |
| 1181 | pub 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"); | |
| 804 | pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void { | |
| 805 | self.root_module.addConfigHeader(config_header); | |
| 1188 | 806 | } |
| 1189 | 807 | |
| 1190 | /// Adds a module to be used with `@import` without exposing it in the current | |
| 1191 | /// package's module table. | |
| 1192 | pub 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); | |
| 808 | pub fn addLibraryPath(self: *Compile, directory_path: LazyPath) void { | |
| 809 | self.root_module.addLibraryPath(directory_path); | |
| 1196 | 810 | } |
| 1197 | 811 | |
| 1198 | pub fn addOptions(cs: *Compile, module_name: []const u8, options: *Step.Options) void { | |
| 1199 | addModule(cs, module_name, options.createModule()); | |
| 812 | pub fn addRPath(self: *Compile, directory_path: LazyPath) void { | |
| 813 | self.root_module.addRPath(directory_path); | |
| 1200 | 814 | } |
| 1201 | 815 | |
| 1202 | fn 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 | } | |
| 816 | pub fn addSystemFrameworkPath(self: *Compile, directory_path: LazyPath) void { | |
| 817 | self.root_module.addSystemFrameworkPath(directory_path); | |
| 1209 | 818 | } |
| 1210 | 819 | |
| 1211 | /// If Vcpkg was found on the system, it will be added to include and lib | |
| 1212 | /// paths for the specified target. | |
| 1213 | pub 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 | } | |
| 820 | pub fn addFrameworkPath(self: *Compile, directory_path: LazyPath) void { | |
| 821 | self.root_module.addFrameworkPath(directory_path); | |
| 1247 | 822 | } |
| 1248 | 823 | |
| 1249 | 824 | pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { |
| ... | ... | @@ -1256,129 +831,42 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { |
| 1256 | 831 | self.exec_cmd_args = duped_args; |
| 1257 | 832 | } |
| 1258 | 833 | |
| 1259 | fn 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 | } | |
| 834 | const CliNamedModules = struct { | |
| 835 | modules: std.AutoArrayHashMapUnmanaged(*Module, void), | |
| 836 | names: std.StringArrayHashMapUnmanaged(void), | |
| 1264 | 837 | |
| 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 | ||
| 1273 | fn 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", {}); | |
| 1317 | 853 | } |
| 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; | |
| 1327 | 865 | } |
| 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 | ||
| 1360 | fn 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 }); | |
| 1374 | 866 | } |
| 867 | return self; | |
| 1375 | 868 | } |
| 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 | }; | |
| 1382 | 870 | |
| 1383 | 871 | fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 { |
| 1384 | 872 | const maybe_path: ?*GeneratedFile = @field(self, tag_name); |
| ... | ... | @@ -1406,13 +894,10 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st |
| 1406 | 894 | |
| 1407 | 895 | fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1408 | 896 | const b = step.owner; |
| 897 | const arena = b.allocator; | |
| 1409 | 898 | const self = @fieldParentPtr(Compile, "step", step); |
| 1410 | 899 | |
| 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); | |
| 1416 | 901 | defer zig_args.deinit(); |
| 1417 | 902 | |
| 1418 | 903 | try zig_args.append(b.zig_exe); |
| ... | ... | @@ -1426,14 +911,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1426 | 911 | try zig_args.append(cmd); |
| 1427 | 912 | |
| 1428 | 913 | 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})); | |
| 1430 | 915 | } |
| 1431 | 916 | |
| 1432 | 917 | try addFlag(&zig_args, "llvm", self.use_llvm); |
| 1433 | 918 | try addFlag(&zig_args, "lld", self.use_lld); |
| 1434 | 919 | |
| 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)})); | |
| 1437 | 922 | } |
| 1438 | 923 | |
| 1439 | 924 | switch (self.entry) { |
| ... | ... | @@ -1441,7 +926,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1441 | 926 | .disabled => try zig_args.append("-fno-entry"), |
| 1442 | 927 | .enabled => try zig_args.append("-fentry"), |
| 1443 | 928 | .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})); | |
| 1445 | 930 | }, |
| 1446 | 931 | } |
| 1447 | 932 | |
| ... | ... | @@ -1455,207 +940,316 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1455 | 940 | |
| 1456 | 941 | if (self.stack_size) |stack_size| { |
| 1457 | 942 | 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})); | |
| 1459 | 944 | } |
| 1460 | 945 | |
| 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 | } | |
| 1462 | 967 | |
| 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); | |
| 1474 | 969 | |
| 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); | |
| 1498 | 973 | |
| 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.?; | |
| 1515 | 977 | |
| 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); | |
| 1537 | 988 | } |
| 989 | } | |
| 1538 | 990 | |
| 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"), | |
| 1563 | 1019 | }, |
| 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"), | |
| 1566 | 1023 | }, |
| 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 | } | |
| 1568 | 1062 | }, |
| 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; | |
| 1569 | 1110 | |
| 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; | |
| 1571 | 1115 | } |
| 1116 | try zig_args.append(asm_file.getPath(b)); | |
| 1117 | total_linker_objects += 1; | |
| 1572 | 1118 | }, |
| 1573 | } | |
| 1574 | }, | |
| 1575 | 1119 | |
| 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 | }, | |
| 1584 | 1140 | |
| 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 | } | |
| 1602 | 1158 | |
| 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 | }, | |
| 1617 | 1191 | } |
| 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 })); | |
| 1625 | 1211 | } |
| 1626 | 1212 | } |
| 1627 | }, | |
| 1628 | 1213 | |
| 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 }); | |
| 1643 | 1223 | } |
| 1644 | try zig_args.append(rc_source_file.file.getPath(b)); | |
| 1645 | }, | |
| 1224 | } | |
| 1646 | 1225 | } |
| 1647 | } | |
| 1648 | 1226 | |
| 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 | } | |
| 1652 | 1230 | |
| 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 | } | |
| 1655 | 1249 | } |
| 1656 | 1250 | |
| 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)); | |
| 1659 | 1253 | } |
| 1660 | 1254 | |
| 1661 | 1255 | if (self.image_base) |image_base| { |
| ... | ... | @@ -1702,17 +1296,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1702 | 1296 | if (self.generated_llvm_ir != null) try zig_args.append("-femit-llvm-ir"); |
| 1703 | 1297 | if (self.generated_h != null) try zig_args.append("-femit-h"); |
| 1704 | 1298 | |
| 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 | ||
| 1716 | 1299 | switch (self.compress_debug_sections) { |
| 1717 | 1300 | .none => {}, |
| 1718 | 1301 | .zlib => try zig_args.append("--compress-debug-sections=zlib"), |
| ... | ... | @@ -1769,11 +1352,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1769 | 1352 | try zig_args.append(libc_file); |
| 1770 | 1353 | } |
| 1771 | 1354 | |
| 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 | ||
| 1777 | 1355 | try zig_args.append("--cache-dir"); |
| 1778 | 1356 | try zig_args.append(b.cache_root.path orelse "."); |
| 1779 | 1357 | |
| ... | ... | @@ -1793,11 +1371,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1793 | 1371 | try zig_args.append(b.fmt("{}", .{version})); |
| 1794 | 1372 | } |
| 1795 | 1373 | |
| 1796 | if (self.target.isDarwin()) { | |
| 1374 | if (self.rootModuleTarget().isDarwin()) { | |
| 1797 | 1375 | const install_name = self.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{ |
| 1798 | self.target.libPrefix(), | |
| 1376 | self.rootModuleTarget().libPrefix(), | |
| 1799 | 1377 | self.name, |
| 1800 | self.target.dynamicLibSuffix(), | |
| 1378 | self.rootModuleTarget().dynamicLibSuffix(), | |
| 1801 | 1379 | }); |
| 1802 | 1380 | try zig_args.append("-install_name"); |
| 1803 | 1381 | try zig_args.append(install_name); |
| ... | ... | @@ -1808,11 +1386,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1808 | 1386 | try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements }); |
| 1809 | 1387 | } |
| 1810 | 1388 | 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}); | |
| 1812 | 1390 | try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size }); |
| 1813 | 1391 | } |
| 1814 | 1392 | 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}); | |
| 1816 | 1394 | try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size }); |
| 1817 | 1395 | } |
| 1818 | 1396 | if (self.headerpad_max_install_names) { |
| ... | ... | @@ -1823,27 +1401,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1823 | 1401 | } |
| 1824 | 1402 | |
| 1825 | 1403 | 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); | |
| 1839 | 1404 | 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 | } | |
| 1847 | 1405 | if (self.rdynamic) { |
| 1848 | 1406 | try zig_args.append("-rdynamic"); |
| 1849 | 1407 | } |
| ... | ... | @@ -1875,29 +1433,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1875 | 1433 | try zig_args.append(b.fmt("--global-base={d}", .{global_base})); |
| 1876 | 1434 | } |
| 1877 | 1435 | |
| 1878 | if (self.code_model != .default) { | |
| 1879 | try zig_args.append("-mcmodel"); | |
| 1880 | try zig_args.append(@tagName(self.code_model)); | |
| 1881 | } | |
| 1882 | 1436 | if (self.wasi_exec_model) |model| { |
| 1883 | 1437 | try zig_args.append(b.fmt("-mexec-model={s}", .{@tagName(model)})); |
| 1884 | 1438 | } |
| 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 | ||
| 1901 | 1439 | if (self.linker_script) |linker_script| { |
| 1902 | 1440 | try zig_args.append("--script"); |
| 1903 | 1441 | try zig_args.append(linker_script.getPath(b)); |
| ... | ... | @@ -1921,103 +1459,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1921 | 1459 | } |
| 1922 | 1460 | } |
| 1923 | 1461 | |
| 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 | ||
| 2017 | 1462 | if (b.sysroot) |sysroot| { |
| 2018 | 1463 | try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot }); |
| 2019 | 1464 | } |
| 2020 | 1465 | |
| 1466 | // -I and -L arguments that appear after the last --mod argument apply to all modules. | |
| 2021 | 1467 | for (b.search_prefixes.items) |search_prefix| { |
| 2022 | 1468 | var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| { |
| 2023 | 1469 | return step.fail("unable to open prefix directory '{s}': {s}", .{ |
| ... | ... | @@ -2032,7 +1478,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2032 | 1478 | |
| 2033 | 1479 | if (prefix_dir.accessZ("lib", .{})) |_| { |
| 2034 | 1480 | 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" }), | |
| 2036 | 1482 | }); |
| 2037 | 1483 | } else |err| switch (err) { |
| 2038 | 1484 | error.FileNotFound => {}, |
| ... | ... | @@ -2043,7 +1489,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2043 | 1489 | |
| 2044 | 1490 | if (prefix_dir.accessZ("include", .{})) |_| { |
| 2045 | 1491 | 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" }), | |
| 2047 | 1493 | }); |
| 2048 | 1494 | } else |err| switch (err) { |
| 2049 | 1495 | error.FileNotFound => {}, |
| ... | ... | @@ -2058,7 +1504,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2058 | 1504 | try zig_args.append(@tagName(self.rc_includes)); |
| 2059 | 1505 | } |
| 2060 | 1506 | |
| 2061 | try addFlag(&zig_args, "valgrind", self.valgrind_support); | |
| 2062 | 1507 | try addFlag(&zig_args, "each-lib-rpath", self.each_lib_rpath); |
| 2063 | 1508 | |
| 2064 | 1509 | if (self.build_id) |build_id| { |
| ... | ... | @@ -2075,12 +1520,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2075 | 1520 | try zig_args.append(dir.getPath(b)); |
| 2076 | 1521 | } |
| 2077 | 1522 | |
| 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); | |
| 2084 | 1523 | try addFlag(&zig_args, "PIE", self.pie); |
| 2085 | 1524 | try addFlag(&zig_args, "lto", self.want_lto); |
| 2086 | 1525 | |
| ... | ... | @@ -2117,12 +1556,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2117 | 1556 | try b.cache_root.handle.makePath("args"); |
| 2118 | 1557 | |
| 2119 | 1558 | 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); | |
| 2121 | 1560 | arg_blk: for (args_to_escape) |arg| { |
| 2122 | 1561 | for (arg, 0..) |c, arg_idx| { |
| 2123 | 1562 | if (c == '\\' or c == '"') { |
| 2124 | 1563 | // 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); | |
| 2126 | 1565 | const writer = escaped.writer(); |
| 2127 | 1566 | try writer.writeAll(arg[0..arg_idx]); |
| 2128 | 1567 | for (arg[arg_idx..]) |to_escape| { |
| ... | ... | @@ -2138,8 +1577,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2138 | 1577 | |
| 2139 | 1578 | // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with |
| 2140 | 1579 | // 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, "\"" }); | |
| 2143 | 1582 | |
| 2144 | 1583 | var args_hash: [Sha256.digest_length]u8 = undefined; |
| 2145 | 1584 | Sha256.hash(args, &args_hash, .{}); |
| ... | ... | @@ -2153,9 +1592,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2153 | 1592 | const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash; |
| 2154 | 1593 | try b.cache_root.handle.writeFile(args_file, args); |
| 2155 | 1594 | |
| 2156 | const resolved_args_file = try mem.concat(b.allocator, u8, &.{ | |
| 1595 | const resolved_args_file = try mem.concat(arena, u8, &.{ | |
| 2157 | 1596 | "@", |
| 2158 | try b.cache_root.join(b.allocator, &.{args_file}), | |
| 1597 | try b.cache_root.join(arena, &.{args_file}), | |
| 2159 | 1598 | }); |
| 2160 | 1599 | |
| 2161 | 1600 | zig_args.shrinkRetainingCapacity(2); |
| ... | ... | @@ -2223,7 +1662,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2223 | 1662 | } |
| 2224 | 1663 | |
| 2225 | 1664 | 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())) | |
| 2227 | 1666 | { |
| 2228 | 1667 | try doAtomicSymLinks( |
| 2229 | 1668 | step, |
| ... | ... | @@ -2234,43 +1673,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 2234 | 1673 | } |
| 2235 | 1674 | } |
| 2236 | 1675 | |
| 2237 | fn 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 | ||
| 2246 | fn 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. | |
| 2256 | fn 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 | ||
| 2274 | 1676 | pub fn doAtomicSymLinks( |
| 2275 | 1677 | step: *Step, |
| 2276 | 1678 | output_path: []const u8, |
| ... | ... | @@ -2345,67 +1747,6 @@ fn addFlag(args: *ArrayList([]const u8), comptime name: []const u8, opt: ?bool) |
| 2345 | 1747 | } |
| 2346 | 1748 | } |
| 2347 | 1749 | |
| 2348 | const 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 | ||
| 2409 | 1750 | fn checkCompileErrors(self: *Compile) !void { |
| 2410 | 1751 | // Clear this field so that it does not get printed by the build runner. |
| 2411 | 1752 | const actual_eb = self.step.result_error_bundle; |
| ... | ... | @@ -2490,3 +1831,8 @@ fn matchCompileError(actual: []const u8, expected: []const u8) bool { |
| 2490 | 1831 | } |
| 2491 | 1832 | return false; |
| 2492 | 1833 | } |
| 1834 | ||
| 1835 | pub 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) { |
| 15 | 15 | /// Start with nothing, like blank, and output a nasm .asm file. |
| 16 | 16 | nasm, |
| 17 | 17 | |
| 18 | /// deprecated: use `getPath` | |
| 19 | pub const getFileSource = getPath; | |
| 20 | ||
| 21 | 18 | pub fn getPath(style: Style) ?std.Build.LazyPath { |
| 22 | 19 | switch (style) { |
| 23 | 20 | .autoconf, .cmake => |s| return s, |
| ... | ... | @@ -107,9 +104,6 @@ pub fn addValues(self: *ConfigHeader, values: anytype) void { |
| 107 | 104 | return addValuesInner(self, values) catch @panic("OOM"); |
| 108 | 105 | } |
| 109 | 106 | |
| 110 | /// deprecated: use `getOutput` | |
| 111 | pub const getFileSource = getOutput; | |
| 112 | ||
| 113 | 107 | pub fn getOutput(self: *ConfigHeader) std.Build.LazyPath { |
| 114 | 108 | return .{ .generated = &self.output_file }; |
| 115 | 109 | } |
lib/std/Build/Step/InstallArtifact.zig+1-1| ... | ... | @@ -94,7 +94,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins |
| 94 | 94 | .dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and |
| 95 | 95 | artifact.isDynamicLibrary() and |
| 96 | 96 | artifact.version != null and |
| 97 | artifact.target.wantSharedLibSymLinks())) .{ | |
| 97 | std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{ | |
| 98 | 98 | .major_only_filename = artifact.major_only_filename.?, |
| 99 | 99 | .name_only_filename = artifact.name_only_filename.?, |
| 100 | 100 | } else null, |
lib/std/Build/Step/Options.zig+5-6| ... | ... | @@ -165,9 +165,6 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void { |
| 165 | 165 | } |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | /// deprecated: use `addOptionPath` | |
| 169 | pub const addOptionFileSource = addOptionPath; | |
| 170 | ||
| 171 | 168 | /// The value is the path in the cache dir. |
| 172 | 169 | /// Adds a dependency automatically. |
| 173 | 170 | pub fn addOptionPath( |
| ... | ... | @@ -189,8 +186,7 @@ pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compi |
| 189 | 186 | |
| 190 | 187 | pub fn createModule(self: *Options) *std.Build.Module { |
| 191 | 188 | return self.step.owner.createModule(.{ |
| 192 | .source_file = self.getOutput(), | |
| 193 | .dependencies = &.{}, | |
| 189 | .root_source_file = self.getOutput(), | |
| 194 | 190 | }); |
| 195 | 191 | } |
| 196 | 192 | |
| ... | ... | @@ -298,7 +294,10 @@ test Options { |
| 298 | 294 | var arena = std.heap.ArenaAllocator.init(std.testing.allocator); |
| 299 | 295 | defer arena.deinit(); |
| 300 | 296 | |
| 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 | }; | |
| 302 | 301 | |
| 303 | 302 | var cache: std.Build.Cache = .{ |
| 304 | 303 | .gpa = arena.allocator(), |
lib/std/Build/Step/Run.zig+23-27| ... | ... | @@ -197,16 +197,10 @@ pub fn addPrefixedOutputFileArg( |
| 197 | 197 | return .{ .generated = &output.generated_file }; |
| 198 | 198 | } |
| 199 | 199 | |
| 200 | /// deprecated: use `addFileArg` | |
| 201 | pub const addFileSourceArg = addFileArg; | |
| 202 | ||
| 203 | 200 | pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void { |
| 204 | 201 | self.addPrefixedFileArg("", lp); |
| 205 | 202 | } |
| 206 | 203 | |
| 207 | // deprecated: use `addPrefixedFileArg` | |
| 208 | pub const addPrefixedFileSourceArg = addPrefixedFileArg; | |
| 209 | ||
| 210 | 204 | pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { |
| 211 | 205 | const b = self.step.owner; |
| 212 | 206 | |
| ... | ... | @@ -488,7 +482,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 488 | 482 | man.hash.addBytes(file_path); |
| 489 | 483 | }, |
| 490 | 484 | .artifact => |artifact| { |
| 491 | if (artifact.target.isWindows()) { | |
| 485 | if (artifact.rootModuleTarget().os.tag == .windows) { | |
| 492 | 486 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 493 | 487 | self.addPathForDynLibs(artifact); |
| 494 | 488 | } |
| ... | ... | @@ -682,8 +676,10 @@ fn runCommand( |
| 682 | 676 | else => break :interpret, |
| 683 | 677 | } |
| 684 | 678 | |
| 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, .{ | |
| 687 | 683 | .qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null, |
| 688 | 684 | .link_libc = exe.is_linking_libc, |
| 689 | 685 | })) { |
| ... | ... | @@ -714,9 +710,9 @@ fn runCommand( |
| 714 | 710 | // needs the directory to be called "i686" rather than |
| 715 | 711 | // "x86" which is why we do it manually here. |
| 716 | 712 | 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; | |
| 720 | 716 | const cpu_arch_name: []const u8 = if (cpu_arch == .x86) |
| 721 | 717 | "i686" |
| 722 | 718 | else |
| ... | ... | @@ -756,7 +752,7 @@ fn runCommand( |
| 756 | 752 | .bad_dl => |foreign_dl| { |
| 757 | 753 | if (allow_skip) return error.MakeSkipped; |
| 758 | 754 | |
| 759 | const host_dl = b.host.dynamic_linker.get() orelse "(none)"; | |
| 755 | const host_dl = b.host.result.dynamic_linker.get() orelse "(none)"; | |
| 760 | 756 | |
| 761 | 757 | return step.fail( |
| 762 | 758 | \\the host system is unable to execute binaries from the target |
| ... | ... | @@ -768,8 +764,8 @@ fn runCommand( |
| 768 | 764 | .bad_os_or_cpu => { |
| 769 | 765 | if (allow_skip) return error.MakeSkipped; |
| 770 | 766 | |
| 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); | |
| 773 | 769 | |
| 774 | 770 | return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{ |
| 775 | 771 | host_name, foreign_name, |
| ... | ... | @@ -777,7 +773,7 @@ fn runCommand( |
| 777 | 773 | }, |
| 778 | 774 | } |
| 779 | 775 | |
| 780 | if (exe.target.isWindows()) { | |
| 776 | if (exe.rootModuleTarget().os.tag == .windows) { | |
| 781 | 777 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 782 | 778 | self.addPathForDynLibs(exe); |
| 783 | 779 | } |
| ... | ... | @@ -1295,15 +1291,15 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult { |
| 1295 | 1291 | |
| 1296 | 1292 | fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void { |
| 1297 | 1293 | 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 | } | |
| 1307 | 1303 | } |
| 1308 | 1304 | } |
| 1309 | 1305 | } |
| ... | ... | @@ -1320,8 +1316,8 @@ fn failForeign( |
| 1320 | 1316 | return error.MakeSkipped; |
| 1321 | 1317 | |
| 1322 | 1318 | 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); | |
| 1325 | 1321 | |
| 1326 | 1322 | return self.step.fail( |
| 1327 | 1323 | \\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"); |
| 2 | 2 | const Step = std.Build.Step; |
| 3 | 3 | const fs = std.fs; |
| 4 | 4 | const mem = std.mem; |
| 5 | const CrossTarget = std.zig.CrossTarget; | |
| 6 | 5 | |
| 7 | 6 | const TranslateC = @This(); |
| 8 | 7 | |
| ... | ... | @@ -13,7 +12,7 @@ source: std.Build.LazyPath, |
| 13 | 12 | include_dirs: std.ArrayList([]const u8), |
| 14 | 13 | c_macros: std.ArrayList([]const u8), |
| 15 | 14 | out_basename: []const u8, |
| 16 | target: CrossTarget, | |
| 15 | target: std.Build.ResolvedTarget, | |
| 17 | 16 | optimize: std.builtin.OptimizeMode, |
| 18 | 17 | output_file: std.Build.GeneratedFile, |
| 19 | 18 | link_libc: bool, |
| ... | ... | @@ -21,7 +20,7 @@ use_clang: bool, |
| 21 | 20 | |
| 22 | 21 | pub const Options = struct { |
| 23 | 22 | source_file: std.Build.LazyPath, |
| 24 | target: CrossTarget, | |
| 23 | target: std.Build.ResolvedTarget, | |
| 25 | 24 | optimize: std.builtin.OptimizeMode, |
| 26 | 25 | link_libc: bool = true, |
| 27 | 26 | use_clang: bool = true, |
| ... | ... | @@ -54,7 +53,7 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC { |
| 54 | 53 | pub const AddExecutableOptions = struct { |
| 55 | 54 | name: ?[]const u8 = null, |
| 56 | 55 | version: ?std.SemanticVersion = null, |
| 57 | target: ?CrossTarget = null, | |
| 56 | target: ?std.Build.ResolvedTarget = null, | |
| 58 | 57 | optimize: ?std.builtin.OptimizeMode = null, |
| 59 | 58 | linkage: ?Step.Compile.Linkage = null, |
| 60 | 59 | }; |
| ... | ... | @@ -139,9 +138,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 139 | 138 | |
| 140 | 139 | try argv_list.append("--listen=-"); |
| 141 | 140 | |
| 142 | if (!self.target.isNative()) { | |
| 141 | if (!self.target.query.isNative()) { | |
| 143 | 142 | 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)); | |
| 145 | 144 | } |
| 146 | 145 | |
| 147 | 146 | switch (self.optimize) { |
lib/std/Build/Step/WriteFile.zig-7| ... | ... | @@ -28,9 +28,6 @@ pub const File = struct { |
| 28 | 28 | sub_path: []const u8, |
| 29 | 29 | contents: Contents, |
| 30 | 30 | |
| 31 | /// deprecated: use `getPath` | |
| 32 | pub const getFileSource = getPath; | |
| 33 | ||
| 34 | 31 | pub fn getPath(self: *File) std.Build.LazyPath { |
| 35 | 32 | return .{ .generated = &self.generated_file }; |
| 36 | 33 | } |
| ... | ... | @@ -126,10 +123,6 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8) |
| 126 | 123 | }) catch @panic("OOM"); |
| 127 | 124 | } |
| 128 | 125 | |
| 129 | pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getPath()"); | |
| 130 | ||
| 131 | pub const getDirectorySource = getDirectory; | |
| 132 | ||
| 133 | 126 | /// Returns a `LazyPath` representing the base directory that contains all the |
| 134 | 127 | /// files from this `WriteFile`. |
| 135 | 128 | pub 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 | ||
| 6 | cpu: Cpu, | |
| 7 | os: Os, | |
| 8 | abi: Abi, | |
| 9 | ofmt: ObjectFormat, | |
| 10 | dynamic_linker: DynamicLinker = DynamicLinker.none, | |
| 11 | ||
| 12 | pub const Query = @import("Target/Query.zig"); | |
| 13 | ||
| 14 | pub 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 | ||
| 463 | pub const aarch64 = @import("Target/aarch64.zig"); | |
| 464 | pub const arc = @import("Target/arc.zig"); | |
| 465 | pub const amdgpu = @import("Target/amdgpu.zig"); | |
| 466 | pub const arm = @import("Target/arm.zig"); | |
| 467 | pub const avr = @import("Target/avr.zig"); | |
| 468 | pub const bpf = @import("Target/bpf.zig"); | |
| 469 | pub const csky = @import("Target/csky.zig"); | |
| 470 | pub const hexagon = @import("Target/hexagon.zig"); | |
| 471 | pub const loongarch = @import("Target/loongarch.zig"); | |
| 472 | pub const m68k = @import("Target/m68k.zig"); | |
| 473 | pub const mips = @import("Target/mips.zig"); | |
| 474 | pub const msp430 = @import("Target/msp430.zig"); | |
| 475 | pub const nvptx = @import("Target/nvptx.zig"); | |
| 476 | pub const powerpc = @import("Target/powerpc.zig"); | |
| 477 | pub const riscv = @import("Target/riscv.zig"); | |
| 478 | pub const sparc = @import("Target/sparc.zig"); | |
| 479 | pub const spirv = @import("Target/spirv.zig"); | |
| 480 | pub const s390x = @import("Target/s390x.zig"); | |
| 481 | pub const ve = @import("Target/ve.zig"); | |
| 482 | pub const wasm = @import("Target/wasm.zig"); | |
| 483 | pub const x86 = @import("Target/x86.zig"); | |
| 484 | pub const xtensa = @import("Target/xtensa.zig"); | |
| 485 | ||
| 486 | pub 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 | ||
| 611 | pub 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 | ||
| 664 | pub const SubSystem = enum { | |
| 665 | Console, | |
| 666 | Windows, | |
| 667 | Posix, | |
| 668 | Native, | |
| 669 | EfiApplication, | |
| 670 | EfiBootServiceDriver, | |
| 671 | EfiRom, | |
| 672 | EfiRuntimeDriver, | |
| 673 | }; | |
| 674 | ||
| 675 | pub 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 | ||
| 1397 | pub fn zigTriple(self: Target, allocator: Allocator) Allocator.Error![]u8 { | |
| 1398 | return Query.fromTarget(self).zigTriple(allocator); | |
| 1399 | } | |
| 1400 | ||
| 1401 | pub 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 | ||
| 1405 | pub fn linuxTriple(self: Target, allocator: Allocator) ![]u8 { | |
| 1406 | return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi); | |
| 1407 | } | |
| 1408 | ||
| 1409 | pub 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 | ||
| 1421 | pub fn exeFileExt(self: Target) [:0]const u8 { | |
| 1422 | return exeFileExtSimple(self.cpu.arch, self.os.tag); | |
| 1423 | } | |
| 1424 | ||
| 1425 | pub 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 | ||
| 1435 | pub fn staticLibSuffix(self: Target) [:0]const u8 { | |
| 1436 | return staticLibSuffix_os_abi(self.os.tag, self.abi); | |
| 1437 | } | |
| 1438 | ||
| 1439 | pub fn dynamicLibSuffix(self: Target) [:0]const u8 { | |
| 1440 | return self.os.tag.dynamicLibSuffix(); | |
| 1441 | } | |
| 1442 | ||
| 1443 | pub 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 | ||
| 1453 | pub fn libPrefix(self: Target) [:0]const u8 { | |
| 1454 | return libPrefix_os_abi(self.os.tag, self.abi); | |
| 1455 | } | |
| 1456 | ||
| 1457 | pub inline fn isMinGW(self: Target) bool { | |
| 1458 | return self.os.tag == .windows and self.isGnu(); | |
| 1459 | } | |
| 1460 | ||
| 1461 | pub inline fn isGnu(self: Target) bool { | |
| 1462 | return self.abi.isGnu(); | |
| 1463 | } | |
| 1464 | ||
| 1465 | pub inline fn isMusl(self: Target) bool { | |
| 1466 | return self.abi.isMusl(); | |
| 1467 | } | |
| 1468 | ||
| 1469 | pub inline fn isAndroid(self: Target) bool { | |
| 1470 | return self.abi == .android; | |
| 1471 | } | |
| 1472 | ||
| 1473 | pub inline fn isWasm(self: Target) bool { | |
| 1474 | return self.cpu.arch.isWasm(); | |
| 1475 | } | |
| 1476 | ||
| 1477 | pub inline fn isDarwin(self: Target) bool { | |
| 1478 | return self.os.tag.isDarwin(); | |
| 1479 | } | |
| 1480 | ||
| 1481 | pub inline fn isBSD(self: Target) bool { | |
| 1482 | return self.os.tag.isBSD(); | |
| 1483 | } | |
| 1484 | ||
| 1485 | pub inline fn isBpfFreestanding(self: Target) bool { | |
| 1486 | return self.cpu.arch.isBpf() and self.os.tag == .freestanding; | |
| 1487 | } | |
| 1488 | ||
| 1489 | pub inline fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool { | |
| 1490 | return os_tag == .linux and abi.isGnu(); | |
| 1491 | } | |
| 1492 | ||
| 1493 | pub inline fn isGnuLibC(self: Target) bool { | |
| 1494 | return isGnuLibC_os_tag_abi(self.os.tag, self.abi); | |
| 1495 | } | |
| 1496 | ||
| 1497 | pub inline fn supportsNewStackCall(self: Target) bool { | |
| 1498 | return !self.cpu.arch.isWasm(); | |
| 1499 | } | |
| 1500 | ||
| 1501 | pub inline fn isSpirV(self: Target) bool { | |
| 1502 | return self.cpu.arch.isSpirV(); | |
| 1503 | } | |
| 1504 | ||
| 1505 | pub const FloatAbi = enum { | |
| 1506 | hard, | |
| 1507 | soft, | |
| 1508 | }; | |
| 1509 | ||
| 1510 | pub inline fn getFloatAbi(self: Target) FloatAbi { | |
| 1511 | return self.abi.floatAbi(); | |
| 1512 | } | |
| 1513 | ||
| 1514 | pub 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 | ||
| 1537 | pub 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 | ||
| 1585 | pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { | |
| 1586 | return standardDynamicLinkerPath_cpu_os_abi(target.cpu, target.os.tag, target.abi); | |
| 1587 | } | |
| 1588 | ||
| 1589 | pub 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 | |
| 1786 | pub 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 | ||
| 1800 | pub 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 | ||
| 1890 | pub 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 | ||
| 1967 | pub fn ptrBitWidth(target: Target) u16 { | |
| 1968 | return ptrBitWidth_cpu_abi(target.cpu, target.abi); | |
| 1969 | } | |
| 1970 | ||
| 1971 | pub 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 | |
| 2016 | pub 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 | ||
| 2040 | pub 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 | ||
| 2055 | pub 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 | ||
| 2081 | pub 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 | ||
| 2397 | pub 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 | ||
| 2504 | pub 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 | ||
| 2630 | pub 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 | ||
| 2704 | pub 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 | ||
| 2712 | fn 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 | ||
| 2720 | const Target = @This(); | |
| 2721 | const std = @import("std.zig"); | |
| 2722 | const builtin = @import("builtin"); | |
| 2723 | const Allocator = std.mem.Allocator; | |
| 2724 | ||
| 2725 | test { | |
| 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. | |
| 7 | cpu_arch: ?Target.Cpu.Arch = null, | |
| 8 | ||
| 9 | cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, | |
| 10 | ||
| 11 | /// Sparse set of CPU features to add to the set from `cpu_model`. | |
| 12 | cpu_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`. | |
| 15 | cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | |
| 16 | ||
| 17 | /// `null` means native. | |
| 18 | os_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. | |
| 22 | os_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. | |
| 26 | os_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. | |
| 30 | glibc_version: ?SemanticVersion = null, | |
| 31 | ||
| 32 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | |
| 33 | abi: ?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`. | |
| 37 | dynamic_linker: Target.DynamicLinker = Target.DynamicLinker.none, | |
| 38 | ||
| 39 | /// `null` means default for the cpu/arch/os combo. | |
| 40 | ofmt: ?Target.ObjectFormat = null, | |
| 41 | ||
| 42 | pub 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 | ||
| 67 | pub 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 | ||
| 91 | pub const SemanticVersion = std.SemanticVersion; | |
| 92 | ||
| 93 | pub 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 | ||
| 126 | fn 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 | ||
| 194 | pub 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 | ||
| 247 | pub 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`. | |
| 357 | pub 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. | |
| 371 | pub 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 | ||
| 392 | test 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 | ||
| 399 | pub 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 | ||
| 405 | pub 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 | ||
| 410 | pub fn isNativeAbi(self: Query) bool { | |
| 411 | return self.os_tag == null and self.abi == null; | |
| 412 | } | |
| 413 | ||
| 414 | pub 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. | |
| 420 | fn 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 | ||
| 428 | pub 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`. | |
| 490 | pub 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 | ||
| 532 | pub 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 | ||
| 538 | pub 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 | ||
| 544 | pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { | |
| 545 | self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; | |
| 546 | } | |
| 547 | ||
| 548 | fn 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 | ||
| 645 | pub 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 | ||
| 661 | fn 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 | ||
| 667 | const Query = @This(); | |
| 668 | const std = @import("../std.zig"); | |
| 669 | const builtin = @import("builtin"); | |
| 670 | const assert = std.debug.assert; | |
| 671 | const Target = std.Target; | |
| 672 | const mem = std.mem; | |
| 673 | const Allocator = std.mem.Allocator; | |
| 674 | ||
| 675 | test 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 213 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 214 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 215 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 216 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 217 | ||
| 218 | pub 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 | ||
| 1483 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 162 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 163 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 164 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 165 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 166 | ||
| 167 | pub 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 | ||
| 1126 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | norm, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 209 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 210 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 211 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 212 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 213 | ||
| 214 | pub 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 | ||
| 1718 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 46 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 47 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 48 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 49 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 50 | ||
| 51 | pub 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 | ||
| 348 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | alu32, | |
| 9 | dummy, | |
| 10 | dwarfris, | |
| 11 | }; | |
| 12 | ||
| 13 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 14 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 15 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 16 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 17 | ||
| 18 | pub 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 | ||
| 45 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 73 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 74 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 75 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 76 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 77 | ||
| 78 | pub 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 | ||
| 426 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 52 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 53 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 54 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 55 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 56 | ||
| 57 | pub 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 | ||
| 306 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 22 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 23 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 24 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 25 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 26 | ||
| 27 | pub 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 | ||
| 105 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 33 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 34 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 35 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 36 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 37 | ||
| 38 | pub 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 | ||
| 178 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 62 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 63 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 64 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 65 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 66 | ||
| 67 | pub 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 | ||
| 397 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | ext, | |
| 9 | hwmult16, | |
| 10 | hwmult32, | |
| 11 | hwmultf5, | |
| 12 | }; | |
| 13 | ||
| 14 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 15 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 16 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 17 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 18 | ||
| 19 | pub 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 | ||
| 51 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 52 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 53 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 54 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 55 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 56 | ||
| 57 | pub 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 | ||
| 279 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 91 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 92 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 93 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 94 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 95 | ||
| 96 | pub 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 | ||
| 608 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 166 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 167 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 168 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 169 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 170 | ||
| 171 | pub 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 | ||
| 1074 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 51 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 52 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 53 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 54 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 55 | ||
| 56 | pub 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 | ||
| 273 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 29 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 30 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 31 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 32 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 33 | ||
| 34 | pub 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 | ||
| 141 | pub 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 | ||
| 6 | const std = @import("../std.zig"); | |
| 7 | const CpuFeature = std.Target.Cpu.Feature; | |
| 8 | const CpuModel = std.Target.Cpu.Model; | |
| 9 | ||
| 10 | pub 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 | ||
| 297 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 298 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 299 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 300 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 301 | ||
| 302 | pub 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 | ||
| 2085 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | vpu, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 22 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 23 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 24 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 25 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 26 | ||
| 27 | pub 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 | ||
| 99 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 184 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 185 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 186 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 187 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 188 | ||
| 189 | pub 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 | ||
| 1193 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | density, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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"); |
| 6 | 6 | const testing = std.testing; |
| 7 | 7 | |
| 8 | 8 | scheme: []const u8, |
| 9 | user: ?[]const u8, | |
| 10 | password: ?[]const u8, | |
| 11 | host: ?[]const u8, | |
| 12 | port: ?u16, | |
| 9 | user: ?[]const u8 = null, | |
| 10 | password: ?[]const u8 = null, | |
| 11 | host: ?[]const u8 = null, | |
| 12 | port: ?u16 = null, | |
| 13 | 13 | path: []const u8, |
| 14 | query: ?[]const u8, | |
| 15 | fragment: ?[]const u8, | |
| 14 | query: ?[]const u8 = null, | |
| 15 | fragment: ?[]const u8 = null, | |
| 16 | 16 | |
| 17 | 17 | /// Applies URI encoding and replaces all reserved characters with their respective %XX code. |
| 18 | 18 | pub 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 { |
| 65 | 65 | |
| 66 | 66 | pub const FinishError = posix.RenameError; |
| 67 | 67 | |
| 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). | |
| 68 | 72 | pub fn finish(self: *AtomicFile) FinishError!void { |
| 69 | 73 | assert(self.file_exists); |
| 70 | 74 | 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 |
| 2416 | 2416 | |
| 2417 | 2417 | pub const AtomicFileOptions = struct { |
| 2418 | 2418 | mode: File.Mode = File.default_mode, |
| 2419 | make_path: bool = false, | |
| 2419 | 2420 | }; |
| 2420 | 2421 | |
| 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. | |
| 2425 | 2427 | pub fn atomicFile(self: Dir, dest_path: []const u8, options: AtomicFileOptions) !AtomicFile { |
| 2426 | 2428 | 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 | ||
| 2428 | 2434 | return AtomicFile.init(fs.path.basename(dest_path), options.mode, dir, true); |
| 2429 | 2435 | } else { |
| 2430 | 2436 | return AtomicFile.init(dest_path, options.mode, self, false); |
lib/std/os/test.zig+5| ... | ... | @@ -752,6 +752,11 @@ test "fsync" { |
| 752 | 752 | } |
| 753 | 753 | |
| 754 | 754 | test "getrlimit and setrlimit" { |
| 755 | if (builtin.target.os.tag == .macos) { | |
| 756 | // https://github.com/ziglang/zig/issues/18395 | |
| 757 | return error.SkipZigTest; | |
| 758 | } | |
| 759 | ||
| 755 | 760 | if (!@hasDecl(os.system, "rlimit")) { |
| 756 | 761 | return error.SkipZigTest; |
| 757 | 762 | } |
lib/std/std.zig+1-4| ... | ... | @@ -47,7 +47,7 @@ pub const StringArrayHashMap = array_hash_map.StringArrayHashMap; |
| 47 | 47 | pub const StringArrayHashMapUnmanaged = array_hash_map.StringArrayHashMapUnmanaged; |
| 48 | 48 | /// deprecated: use `DoublyLinkedList`. |
| 49 | 49 | pub const TailQueue = DoublyLinkedList; |
| 50 | pub const Target = @import("target.zig").Target; | |
| 50 | pub const Target = @import("Target.zig"); | |
| 51 | 51 | pub const Thread = @import("Thread.zig"); |
| 52 | 52 | pub const Treap = @import("treap.zig").Treap; |
| 53 | 53 | pub const Tz = tz.Tz; |
| ... | ... | @@ -194,9 +194,6 @@ pub const zig = @import("zig.zig"); |
| 194 | 194 | |
| 195 | 195 | pub const start = @import("start.zig"); |
| 196 | 196 | |
| 197 | /// deprecated: use `Build`. | |
| 198 | pub const build = Build; | |
| 199 | ||
| 200 | 197 | const root = @import("root"); |
| 201 | 198 | const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {}; |
| 202 | 199 |
lib/std/target.zig deleted-2608| ... | ... | @@ -1,2608 +0,0 @@ |
| 1 | const std = @import("std.zig"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const Version = std.SemanticVersion; | |
| 5 | ||
| 6 | pub 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 | ||
| 2606 | test { | |
| 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 213 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 214 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 215 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 216 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 217 | ||
| 218 | pub 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 | ||
| 1483 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 162 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 163 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 164 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 165 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 166 | ||
| 167 | pub 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 | ||
| 1126 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | norm, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 209 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 210 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 211 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 212 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 213 | ||
| 214 | pub 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 | ||
| 1718 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 46 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 47 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 48 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 49 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 50 | ||
| 51 | pub 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 | ||
| 348 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | alu32, | |
| 9 | dummy, | |
| 10 | dwarfris, | |
| 11 | }; | |
| 12 | ||
| 13 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 14 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 15 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 16 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 17 | ||
| 18 | pub 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 | ||
| 45 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 73 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 74 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 75 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 76 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 77 | ||
| 78 | pub 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 | ||
| 426 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 52 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 53 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 54 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 55 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 56 | ||
| 57 | pub 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 | ||
| 306 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 22 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 23 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 24 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 25 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 26 | ||
| 27 | pub 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 | ||
| 105 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 33 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 34 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 35 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 36 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 37 | ||
| 38 | pub 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 | ||
| 178 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 62 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 63 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 64 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 65 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 66 | ||
| 67 | pub 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 | ||
| 397 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | ext, | |
| 9 | hwmult16, | |
| 10 | hwmult32, | |
| 11 | hwmultf5, | |
| 12 | }; | |
| 13 | ||
| 14 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 15 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 16 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 17 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 18 | ||
| 19 | pub 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 | ||
| 51 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 52 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 53 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 54 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 55 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 56 | ||
| 57 | pub 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 | ||
| 279 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 91 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 92 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 93 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 94 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 95 | ||
| 96 | pub 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 | ||
| 608 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 166 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 167 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 168 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 169 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 170 | ||
| 171 | pub 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 | ||
| 1074 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 51 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 52 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 53 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 54 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 55 | ||
| 56 | pub 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 | ||
| 273 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 29 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 30 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 31 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 32 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 33 | ||
| 34 | pub 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 | ||
| 141 | pub 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 | ||
| 6 | const std = @import("../std.zig"); | |
| 7 | const CpuFeature = std.Target.Cpu.Feature; | |
| 8 | const CpuModel = std.Target.Cpu.Model; | |
| 9 | ||
| 10 | pub 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 | ||
| 297 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 298 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 299 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 300 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 301 | ||
| 302 | pub 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 | ||
| 2085 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | vpu, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 22 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 23 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 24 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 25 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 26 | ||
| 27 | pub 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 | ||
| 99 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub 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 | ||
| 184 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 185 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 186 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 187 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 188 | ||
| 189 | pub 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 | ||
| 1193 | pub 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 | ||
| 3 | const std = @import("../std.zig"); | |
| 4 | const CpuFeature = std.Target.Cpu.Feature; | |
| 5 | const CpuModel = std.Target.Cpu.Model; | |
| 6 | ||
| 7 | pub const Feature = enum { | |
| 8 | density, | |
| 9 | }; | |
| 10 | ||
| 11 | pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; | |
| 12 | pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; | |
| 13 | pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; | |
| 14 | pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; | |
| 15 | ||
| 16 | pub 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 | ||
| 33 | pub 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 @@ |
| 1 | const std = @import("std.zig"); | |
| 2 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 3 | 1 | pub const fmt = @import("zig/fmt.zig"); |
| 4 | const assert = std.debug.assert; | |
| 5 | 2 | |
| 6 | 3 | pub const ErrorBundle = @import("zig/ErrorBundle.zig"); |
| 7 | 4 | pub const Server = @import("zig/Server.zig"); |
| ... | ... | @@ -16,7 +13,8 @@ pub const number_literal = @import("zig/number_literal.zig"); |
| 16 | 13 | pub const primitives = @import("zig/primitives.zig"); |
| 17 | 14 | pub const Ast = @import("zig/Ast.zig"); |
| 18 | 15 | pub const system = @import("zig/system.zig"); |
| 19 | pub const CrossTarget = @import("zig/CrossTarget.zig"); | |
| 16 | /// Deprecated: use `std.Target.Query`. | |
| 17 | pub const CrossTarget = std.Target.Query; | |
| 20 | 18 | pub const BuiltinFn = @import("zig/BuiltinFn.zig"); |
| 21 | 19 | pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig"); |
| 22 | 20 | |
| ... | ... | @@ -114,7 +112,7 @@ pub const BinNameOptions = struct { |
| 114 | 112 | }; |
| 115 | 113 | |
| 116 | 114 | /// Returns the standard file system basename of a binary generated by the Zig compiler. |
| 117 | pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { | |
| 115 | pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { | |
| 118 | 116 | const root_name = options.root_name; |
| 119 | 117 | const target = options.target; |
| 120 | 118 | switch (target.ofmt) { |
| ... | ... | @@ -203,6 +201,124 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error |
| 203 | 201 | } |
| 204 | 202 | } |
| 205 | 203 | |
| 204 | pub 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`. | |
| 284 | pub 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 | ||
| 311 | pub 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 | ||
| 317 | const std = @import("std.zig"); | |
| 318 | const tokenizer = @import("zig/tokenizer.zig"); | |
| 319 | const assert = std.debug.assert; | |
| 320 | const Allocator = std.mem.Allocator; | |
| 321 | ||
| 206 | 322 | test { |
| 207 | 323 | @import("std").testing.refAllDecls(@This()); |
| 208 | 324 | } |
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 | ||
| 5 | const CrossTarget = @This(); | |
| 6 | const std = @import("../std.zig"); | |
| 7 | const builtin = @import("builtin"); | |
| 8 | const assert = std.debug.assert; | |
| 9 | const Target = std.Target; | |
| 10 | const mem = std.mem; | |
| 11 | ||
| 12 | /// `null` means native. | |
| 13 | cpu_arch: ?Target.Cpu.Arch = null, | |
| 14 | ||
| 15 | cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, | |
| 16 | ||
| 17 | /// Sparse set of CPU features to add to the set from `cpu_model`. | |
| 18 | cpu_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`. | |
| 21 | cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | |
| 22 | ||
| 23 | /// `null` means native. | |
| 24 | os_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. | |
| 28 | os_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. | |
| 32 | os_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. | |
| 36 | glibc_version: ?SemanticVersion = null, | |
| 37 | ||
| 38 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | |
| 39 | abi: ?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`. | |
| 43 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 44 | ||
| 45 | /// `null` means default for the cpu/arch/os combo. | |
| 46 | ofmt: ?Target.ObjectFormat = null, | |
| 47 | ||
| 48 | pub 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 | ||
| 62 | pub const OsVersion = union(enum) { | |
| 63 | none: void, | |
| 64 | semver: SemanticVersion, | |
| 65 | windows: Target.Os.WindowsVersion, | |
| 66 | }; | |
| 67 | ||
| 68 | pub const SemanticVersion = std.SemanticVersion; | |
| 69 | ||
| 70 | pub const DynamicLinker = Target.DynamicLinker; | |
| 71 | ||
| 72 | pub 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 | ||
| 105 | fn 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`. | |
| 174 | pub 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 | ||
| 183 | pub 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 | ||
| 236 | pub 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`. | |
| 346 | pub 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. | |
| 360 | pub 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 | ||
| 381 | test 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`. | |
| 389 | pub 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 | ||
| 420 | pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch { | |
| 421 | return self.cpu_arch orelse builtin.cpu.arch; | |
| 422 | } | |
| 423 | ||
| 424 | pub 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 | ||
| 431 | pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set { | |
| 432 | return self.getCpu().features; | |
| 433 | } | |
| 434 | ||
| 435 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | |
| 436 | pub 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 | ||
| 468 | pub 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`. | |
| 473 | pub 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`. | |
| 481 | pub 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`. | |
| 489 | pub 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 | ||
| 502 | pub fn isFreeBSD(self: CrossTarget) bool { | |
| 503 | return self.getOsTag() == .freebsd; | |
| 504 | } | |
| 505 | ||
| 506 | pub fn isDarwin(self: CrossTarget) bool { | |
| 507 | return self.getOsTag().isDarwin(); | |
| 508 | } | |
| 509 | ||
| 510 | pub fn isNetBSD(self: CrossTarget) bool { | |
| 511 | return self.getOsTag() == .netbsd; | |
| 512 | } | |
| 513 | ||
| 514 | pub fn isOpenBSD(self: CrossTarget) bool { | |
| 515 | return self.getOsTag() == .openbsd; | |
| 516 | } | |
| 517 | ||
| 518 | pub fn isUefi(self: CrossTarget) bool { | |
| 519 | return self.getOsTag() == .uefi; | |
| 520 | } | |
| 521 | ||
| 522 | pub fn isDragonFlyBSD(self: CrossTarget) bool { | |
| 523 | return self.getOsTag() == .dragonfly; | |
| 524 | } | |
| 525 | ||
| 526 | pub fn isLinux(self: CrossTarget) bool { | |
| 527 | return self.getOsTag() == .linux; | |
| 528 | } | |
| 529 | ||
| 530 | pub fn isWindows(self: CrossTarget) bool { | |
| 531 | return self.getOsTag() == .windows; | |
| 532 | } | |
| 533 | ||
| 534 | pub fn exeFileExt(self: CrossTarget) [:0]const u8 { | |
| 535 | return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); | |
| 536 | } | |
| 537 | ||
| 538 | pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 { | |
| 539 | return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); | |
| 540 | } | |
| 541 | ||
| 542 | pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 { | |
| 543 | return self.getOsTag().dynamicLibSuffix(); | |
| 544 | } | |
| 545 | ||
| 546 | pub fn libPrefix(self: CrossTarget) [:0]const u8 { | |
| 547 | return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); | |
| 548 | } | |
| 549 | ||
| 550 | pub 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 | ||
| 556 | pub 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 | ||
| 561 | pub fn isNativeAbi(self: CrossTarget) bool { | |
| 562 | return self.os_tag == null and self.abi == null; | |
| 563 | } | |
| 564 | ||
| 565 | pub 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. | |
| 571 | fn 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 | ||
| 579 | pub 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 | ||
| 625 | pub 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 | ||
| 631 | pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 { | |
| 632 | return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); | |
| 633 | } | |
| 634 | ||
| 635 | pub fn wantSharedLibSymLinks(self: CrossTarget) bool { | |
| 636 | return self.getOsTag() != .windows; | |
| 637 | } | |
| 638 | ||
| 639 | pub const VcpkgLinkage = std.builtin.LinkMode; | |
| 640 | ||
| 641 | /// Returned slice must be freed by the caller. | |
| 642 | pub 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 | ||
| 676 | pub fn isGnuLibC(self: CrossTarget) bool { | |
| 677 | return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); | |
| 678 | } | |
| 679 | ||
| 680 | pub 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 | ||
| 685 | pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat { | |
| 686 | return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); | |
| 687 | } | |
| 688 | ||
| 689 | pub 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 | ||
| 696 | fn 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 | ||
| 793 | test "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 @@ |
| 1 | 1 | pub const NativePaths = @import("system/NativePaths.zig"); |
| 2 | pub const NativeTargetInfo = @import("system/NativeTargetInfo.zig"); | |
| 3 | 2 | |
| 4 | 3 | pub const windows = @import("system/windows.zig"); |
| 5 | 4 | pub const darwin = @import("system/darwin.zig"); |
| 6 | 5 | pub const linux = @import("system/linux.zig"); |
| 7 | 6 | |
| 7 | pub 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 | ||
| 18 | pub 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. | |
| 30 | pub 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 | ||
| 149 | pub 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. | |
| 165 | pub 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 | ||
| 373 | fn 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 | ||
| 385 | fn 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 | ||
| 408 | pub 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 | ||
| 425 | pub 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 | ||
| 703 | fn 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 | ||
| 719 | test 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 | ||
| 730 | fn 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 | ||
| 813 | fn 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. | |
| 923 | fn 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 | ||
| 1071 | fn 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 | ||
| 1085 | const LdInfo = struct { | |
| 1086 | ld: Target.DynamicLinker, | |
| 1087 | abi: Target.Abi, | |
| 1088 | }; | |
| 1089 | ||
| 1090 | fn 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 | ||
| 1115 | fn 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 | ||
| 1131 | const builtin = @import("builtin"); | |
| 1132 | const std = @import("../std.zig"); | |
| 1133 | const mem = std.mem; | |
| 1134 | const elf = std.elf; | |
| 1135 | const fs = std.fs; | |
| 1136 | const assert = std.debug.assert; | |
| 1137 | const Target = std.Target; | |
| 1138 | const native_endian = builtin.cpu.arch.endian(); | |
| 1139 | ||
| 8 | 1140 | test { |
| 9 | 1141 | _ = NativePaths; |
| 10 | _ = NativeTargetInfo; | |
| 11 | 1142 | |
| 12 | 1143 | _ = darwin; |
| 13 | 1144 | _ = linux; |
lib/std/zig/system/NativePaths.zig+1-3| ... | ... | @@ -5,7 +5,6 @@ const process = std.process; |
| 5 | 5 | const mem = std.mem; |
| 6 | 6 | |
| 7 | 7 | const NativePaths = @This(); |
| 8 | const NativeTargetInfo = std.zig.system.NativeTargetInfo; | |
| 9 | 8 | |
| 10 | 9 | arena: Allocator, |
| 11 | 10 | include_dirs: std.ArrayListUnmanaged([]const u8) = .{}, |
| ... | ... | @@ -14,8 +13,7 @@ framework_dirs: std.ArrayListUnmanaged([]const u8) = .{}, |
| 14 | 13 | rpaths: std.ArrayListUnmanaged([]const u8) = .{}, |
| 15 | 14 | warnings: std.ArrayListUnmanaged([]const u8) = .{}, |
| 16 | 15 | |
| 17 | pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { | |
| 18 | const native_target = native_info.target; | |
| 16 | pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths { | |
| 19 | 17 | var self: NativePaths = .{ .arena = arena }; |
| 20 | 18 | var is_nix = false; |
| 21 | 19 | if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { |
lib/std/zig/system/NativeTargetInfo.zig deleted-1130| ... | ... | @@ -1,1130 +0,0 @@ |
| 1 | const std = @import("../../std.zig"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const assert = std.debug.assert; | |
| 5 | const fs = std.fs; | |
| 6 | const elf = std.elf; | |
| 7 | const native_endian = builtin.cpu.arch.endian(); | |
| 8 | ||
| 9 | const NativeTargetInfo = @This(); | |
| 10 | const Target = std.Target; | |
| 11 | const Allocator = std.mem.Allocator; | |
| 12 | const CrossTarget = std.zig.CrossTarget; | |
| 13 | const windows = std.zig.system.windows; | |
| 14 | const darwin = std.zig.system.darwin; | |
| 15 | const linux = std.zig.system.linux; | |
| 16 | ||
| 17 | target: Target, | |
| 18 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 19 | ||
| 20 | pub const DynamicLinker = Target.DynamicLinker; | |
| 21 | ||
| 22 | pub 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. | |
| 37 | pub 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. | |
| 253 | fn 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 | ||
| 401 | fn 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 | ||
| 484 | fn 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 | ||
| 581 | fn 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 | ||
| 597 | test 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 | ||
| 608 | pub 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 | ||
| 625 | pub 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 | ||
| 905 | fn 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 | ||
| 930 | fn 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 | ||
| 946 | pub const LdInfo = struct { | |
| 947 | ld: DynamicLinker, | |
| 948 | abi: Target.Abi, | |
| 949 | }; | |
| 950 | ||
| 951 | pub 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 | ||
| 967 | fn 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 | ||
| 990 | pub 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 | ||
| 1001 | pub 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. | |
| 1013 | pub 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 { |
| 87 | 87 | const ver = try svt.expectContent(); |
| 88 | 88 | try svt.skipUntilTag(.end, "string"); |
| 89 | 89 | |
| 90 | return try std.zig.CrossTarget.parseVersion(ver); | |
| 90 | return try std.Target.Query.parseVersion(ver); | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | const SystemVersionTokenizer = struct { |
lib/std/zig/system/linux.zig-3| ... | ... | @@ -5,10 +5,7 @@ const io = std.io; |
| 5 | 5 | const fs = std.fs; |
| 6 | 6 | const fmt = std.fmt; |
| 7 | 7 | const testing = std.testing; |
| 8 | ||
| 9 | 8 | const Target = std.Target; |
| 10 | const CrossTarget = std.zig.CrossTarget; | |
| 11 | ||
| 12 | 9 | const assert = std.debug.assert; |
| 13 | 10 | |
| 14 | 11 | const SparcCpuinfoImpl = struct { |
lib/std/zig/system/x86.zig+2-3| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const Target = std.Target; |
| 4 | const CrossTarget = std.zig.CrossTarget; | |
| 5 | 4 | |
| 6 | 5 | const XCR0_XMM = 0x02; |
| 7 | 6 | const XCR0_YMM = 0x04; |
| ... | ... | @@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool { |
| 23 | 22 | return (input & mask) == mask; |
| 24 | 23 | } |
| 25 | 24 | |
| 26 | pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) Target.Cpu { | |
| 27 | _ = cross_target; | |
| 25 | pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) Target.Cpu { | |
| 26 | _ = query; | |
| 28 | 27 | var cpu = Target.Cpu{ |
| 29 | 28 | .arch = arch, |
| 30 | 29 | .model = Target.Cpu.Model.generic(arch), |
src/Builtin.zig created+314| ... | ... | @@ -0,0 +1,314 @@ |
| 1 | target: std.Target, | |
| 2 | zig_backend: std.builtin.CompilerBackend, | |
| 3 | output_mode: std.builtin.OutputMode, | |
| 4 | link_mode: std.builtin.LinkMode, | |
| 5 | is_test: bool, | |
| 6 | test_evented_io: bool, | |
| 7 | single_threaded: bool, | |
| 8 | link_libc: bool, | |
| 9 | link_libcpp: bool, | |
| 10 | optimize_mode: std.builtin.OptimizeMode, | |
| 11 | error_tracing: bool, | |
| 12 | valgrind: bool, | |
| 13 | sanitize_thread: bool, | |
| 14 | pic: bool, | |
| 15 | pie: bool, | |
| 16 | strip: bool, | |
| 17 | code_model: std.builtin.CodeModel, | |
| 18 | omit_frame_pointer: bool, | |
| 19 | wasi_exec_model: std.builtin.WasiExecModel, | |
| 20 | ||
| 21 | pub 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 | ||
| 27 | pub 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 | ||
| 239 | pub 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 | ||
| 281 | fn 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 | ||
| 305 | const builtin = @import("builtin"); | |
| 306 | const std = @import("std"); | |
| 307 | const Allocator = std.mem.Allocator; | |
| 308 | const build_options = @import("build_options"); | |
| 309 | const Module = @import("Package/Module.zig"); | |
| 310 | const assert = std.debug.assert; | |
| 311 | const AstGen = @import("AstGen.zig"); | |
| 312 | const File = @import("Module.zig").File; | |
| 313 | const Compilation = @import("Compilation.zig"); | |
| 314 | const log = std.log.scoped(.builtin); |
src/Compilation.zig+1447-1825| ... | ... | @@ -28,31 +28,79 @@ const libcxx = @import("libcxx.zig"); |
| 28 | 28 | const wasi_libc = @import("wasi_libc.zig"); |
| 29 | 29 | const fatal = @import("main.zig").fatal; |
| 30 | 30 | const clangMain = @import("main.zig").clangMain; |
| 31 | const Module = @import("Module.zig"); | |
| 31 | const Zcu = @import("Module.zig"); | |
| 32 | /// Deprecated; use `Zcu`. | |
| 33 | const Module = Zcu; | |
| 32 | 34 | const InternPool = @import("InternPool.zig"); |
| 33 | const BuildId = std.Build.CompileStep.BuildId; | |
| 34 | 35 | const Cache = std.Build.Cache; |
| 35 | 36 | const c_codegen = @import("codegen/c.zig"); |
| 36 | 37 | const libtsan = @import("libtsan.zig"); |
| 37 | 38 | const Zir = @import("Zir.zig"); |
| 38 | 39 | const Autodoc = @import("Autodoc.zig"); |
| 39 | const Color = @import("main.zig").Color; | |
| 40 | 40 | const resinator = @import("resinator.zig"); |
| 41 | const Builtin = @import("Builtin.zig"); | |
| 42 | const LlvmObject = @import("codegen/llvm.zig").Object; | |
| 43 | ||
| 44 | pub const Config = @import("Compilation/Config.zig"); | |
| 41 | 45 | |
| 42 | 46 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| 43 | 47 | gpa: 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`. | |
| 46 | arena: std.heap.ArenaAllocator, | |
| 47 | bin_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`. | |
| 50 | arena: Allocator, | |
| 51 | /// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`. | |
| 52 | /// TODO: rename to zcu: ?*Zcu | |
| 53 | module: ?*Module, | |
| 54 | /// Contains different state depending on whether the Compilation uses | |
| 55 | /// incremental or whole cache mode. | |
| 56 | cache_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. | |
| 60 | root_mod: *Package.Module, | |
| 61 | ||
| 62 | /// User-specified settings that have all the defaults resolved into concrete values. | |
| 63 | config: 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. | |
| 69 | bin_file: ?*link.File, | |
| 70 | ||
| 71 | /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) | |
| 72 | sysroot: ?[]const u8, | |
| 73 | /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used. | |
| 74 | implib_emit: ?Emit, | |
| 75 | /// This is non-null when `-femit-docs` is provided. | |
| 76 | docs_emit: ?Emit, | |
| 77 | root_name: [:0]const u8, | |
| 78 | include_compiler_rt: bool, | |
| 79 | objects: []Compilation.LinkObject, | |
| 80 | /// Needed only for passing -F args to clang. | |
| 81 | framework_dirs: []const []const u8, | |
| 82 | /// These are *always* dynamically linked. Static libraries will be | |
| 83 | /// provided as positional arguments. | |
| 84 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | |
| 85 | version: ?std.SemanticVersion, | |
| 86 | libc_installation: ?*const LibCInstallation, | |
| 87 | skip_linker_dependencies: bool, | |
| 88 | no_builtin: bool, | |
| 89 | function_sections: bool, | |
| 90 | data_sections: bool, | |
| 91 | link_eh_frame_hdr: bool, | |
| 92 | native_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. | |
| 96 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void), | |
| 97 | ||
| 48 | 98 | c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{}, |
| 49 | 99 | win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) = |
| 50 | 100 | if (build_options.only_core_functionality) {} else .{}, |
| 51 | /// This is a pointer to a local variable inside `update()`. | |
| 52 | whole_cache_manifest: ?*Cache.Manifest = null, | |
| 53 | whole_cache_manifest_mutex: std.Thread.Mutex = .{}, | |
| 54 | 101 | |
| 55 | 102 | link_error_flags: link.File.ErrorFlags = .{}, |
| 103 | link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, | |
| 56 | 104 | lld_errors: std.ArrayListUnmanaged(LldError) = .{}, |
| 57 | 105 | |
| 58 | 106 | work_queue: std.fifo.LinearFifo(Job, .Dynamic), |
| ... | ... | @@ -87,9 +135,6 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std |
| 87 | 135 | /// Miscellaneous things that can fail. |
| 88 | 136 | misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{}, |
| 89 | 137 | |
| 90 | keep_source_files_loaded: bool, | |
| 91 | c_frontend: CFrontend, | |
| 92 | sanitize_c: bool, | |
| 93 | 138 | /// When this is `true` it means invoking clang as a sub-process is expected to inherit |
| 94 | 139 | /// stdin, stdout, stderr, and if it returns non success, to forward the exit code. |
| 95 | 140 | /// Otherwise we attempt to parse the error messages and expose them via the Compilation API. |
| ... | ... | @@ -105,33 +150,25 @@ verbose_llvm_ir: ?[]const u8, |
| 105 | 150 | verbose_llvm_bc: ?[]const u8, |
| 106 | 151 | verbose_cimport: bool, |
| 107 | 152 | verbose_llvm_cpu_features: bool, |
| 153 | verbose_link: bool, | |
| 108 | 154 | disable_c_depfile: bool, |
| 109 | 155 | time_report: bool, |
| 110 | 156 | stack_report: bool, |
| 111 | unwind_tables: bool, | |
| 112 | test_evented_io: bool, | |
| 113 | 157 | debug_compiler_runtime_libs: bool, |
| 114 | 158 | debug_compile_errors: bool, |
| 115 | 159 | job_queued_compiler_rt_lib: bool = false, |
| 116 | 160 | job_queued_compiler_rt_obj: bool = false, |
| 161 | job_queued_update_builtin_zig: bool, | |
| 117 | 162 | alloc_failure_occurred: bool = false, |
| 118 | 163 | formatted_panics: bool = false, |
| 119 | 164 | last_update_was_cache_hit: bool = false, |
| 120 | 165 | |
| 121 | 166 | c_source_files: []const CSourceFile, |
| 122 | clang_argv: []const []const u8, | |
| 123 | 167 | rc_source_files: []const RcSourceFile, |
| 168 | global_cc_argv: []const []const u8, | |
| 124 | 169 | cache_parent: *Cache, |
| 125 | 170 | /// Path to own executable for invoking `zig clang`. |
| 126 | 171 | self_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. | |
| 131 | whole_bin_sub_path: ?[]u8, | |
| 132 | /// Same as `whole_bin_sub_path` but for implibs. | |
| 133 | whole_implib_sub_path: ?[]u8, | |
| 134 | whole_docs_sub_path: ?[]u8, | |
| 135 | 172 | zig_lib_directory: Directory, |
| 136 | 173 | local_cache_directory: Directory, |
| 137 | 174 | global_cache_directory: Directory, |
| ... | ... | @@ -163,19 +200,13 @@ compiler_rt_lib: ?CRTFile = null, |
| 163 | 200 | compiler_rt_obj: ?CRTFile = null, |
| 164 | 201 | |
| 165 | 202 | glibc_so_files: ?glibc.BuiltSharedObjects = null, |
| 203 | wasi_emulated_libs: []const wasi_libc.CRTFile, | |
| 166 | 204 | |
| 167 | 205 | /// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source, |
| 168 | 206 | /// The set of needed CRT (C runtime) files differs depending on the target and compilation settings. |
| 169 | 207 | /// The key is the basename, and the value is the absolute path to the completed build artifact. |
| 170 | 208 | crt_files: std.StringHashMapUnmanaged(CRTFile) = .{}, |
| 171 | 209 | |
| 172 | /// Keeping track of this possibly open resource so we can close it later. | |
| 173 | owned_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. | |
| 177 | color: Color = .auto, | |
| 178 | ||
| 179 | 210 | /// How many lines of reference trace should be included per compile error. |
| 180 | 211 | /// Null means only show snippet on first error. |
| 181 | 212 | reference_trace: ?u32 = null, |
| ... | ... | @@ -195,7 +226,31 @@ emit_llvm_bc: ?EmitLoc, |
| 195 | 226 | work_queue_wait_group: WaitGroup = .{}, |
| 196 | 227 | astgen_wait_group: WaitGroup = .{}, |
| 197 | 228 | |
| 198 | pub const default_stack_protector_buffer_size = 4; | |
| 229 | llvm_opt_bisect_limit: c_int, | |
| 230 | ||
| 231 | pub 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 | ||
| 253 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; | |
| 199 | 254 | pub const SemaError = Module.SemaError; |
| 200 | 255 | |
| 201 | 256 | pub const CRTFile = struct { |
| ... | ... | @@ -209,8 +264,8 @@ pub const CRTFile = struct { |
| 209 | 264 | } |
| 210 | 265 | }; |
| 211 | 266 | |
| 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 | |
| 214 | 269 | pub const LangToExt = std.ComptimeStringMap(FileExt, .{ |
| 215 | 270 | .{ "c", .c }, |
| 216 | 271 | .{ "c-header", .h }, |
| ... | ... | @@ -227,16 +282,20 @@ pub const LangToExt = std.ComptimeStringMap(FileExt, .{ |
| 227 | 282 | |
| 228 | 283 | /// For passing to a C compiler. |
| 229 | 284 | pub const CSourceFile = struct { |
| 285 | /// Many C compiler flags are determined by settings contained in the owning Module. | |
| 286 | owner: *Package.Module, | |
| 230 | 287 | src_path: []const u8, |
| 231 | 288 | extra_flags: []const []const u8 = &.{}, |
| 232 | 289 | /// Same as extra_flags except they are not added to the Cache hash. |
| 233 | 290 | 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". | |
| 235 | 293 | ext: ?FileExt = null, |
| 236 | 294 | }; |
| 237 | 295 | |
| 238 | 296 | /// For passing to resinator. |
| 239 | 297 | pub const RcSourceFile = struct { |
| 298 | owner: *Package.Module, | |
| 240 | 299 | src_path: []const u8, |
| 241 | 300 | extra_flags: []const []const u8 = &.{}, |
| 242 | 301 | }; |
| ... | ... | @@ -289,7 +348,7 @@ const Job = union(enum) { |
| 289 | 348 | /// one of WASI libc static objects |
| 290 | 349 | wasi_libc_crt_file: wasi_libc.CRTFile, |
| 291 | 350 | |
| 292 | /// The value is the index into `link.File.Options.system_libs`. | |
| 351 | /// The value is the index into `system_libs`. | |
| 293 | 352 | windows_import_lib: usize, |
| 294 | 353 | }; |
| 295 | 354 | |
| ... | ... | @@ -659,6 +718,8 @@ pub const Win32Resource = struct { |
| 659 | 718 | |
| 660 | 719 | pub const MiscTask = enum { |
| 661 | 720 | write_builtin_zig, |
| 721 | rename_results, | |
| 722 | check_whole_cache, | |
| 662 | 723 | glibc_crt_file, |
| 663 | 724 | glibc_shared_objects, |
| 664 | 725 | musl_crt_file, |
| ... | ... | @@ -743,6 +804,41 @@ pub const EmitLoc = struct { |
| 743 | 804 | }; |
| 744 | 805 | |
| 745 | 806 | pub 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 | ||
| 746 | 842 | pub fn addEmitLoc(hh: *Cache.HashHelper, emit_loc: EmitLoc) void { |
| 747 | 843 | hh.addBytes(emit_loc.basename); |
| 748 | 844 | } |
| ... | ... | @@ -752,7 +848,21 @@ pub const cache_helpers = struct { |
| 752 | 848 | addEmitLoc(hh, optional_emit_loc orelse return); |
| 753 | 849 | } |
| 754 | 850 | |
| 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 { | |
| 756 | 866 | _ = try self.addFile(c_source.src_path, null); |
| 757 | 867 | // Hash the extra flags, with special care to call addFile for file parameters. |
| 758 | 868 | // TODO this logic can likely be improved by utilizing clang_options_data.zig. |
| ... | ... | @@ -771,8 +881,6 @@ pub const cache_helpers = struct { |
| 771 | 881 | } |
| 772 | 882 | }; |
| 773 | 883 | |
| 774 | pub const CFrontend = enum { clang, aro }; | |
| 775 | ||
| 776 | 884 | pub const ClangPreprocessorMode = enum { |
| 777 | 885 | no, |
| 778 | 886 | /// This means we are doing `zig cc -E -o <path>`. |
| ... | ... | @@ -781,9 +889,62 @@ pub const ClangPreprocessorMode = enum { |
| 781 | 889 | stdout, |
| 782 | 890 | }; |
| 783 | 891 | |
| 784 | pub const Framework = link.Framework; | |
| 892 | pub const Framework = link.File.MachO.Framework; | |
| 785 | 893 | pub const SystemLib = link.SystemLib; |
| 786 | pub const CacheMode = link.CacheMode; | |
| 894 | ||
| 895 | pub const CacheMode = enum { incremental, whole }; | |
| 896 | ||
| 897 | const 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 | }; | |
| 787 | 948 | |
| 788 | 949 | pub const LinkObject = struct { |
| 789 | 950 | path: []const u8, |
| ... | ... | @@ -795,16 +956,27 @@ pub const LinkObject = struct { |
| 795 | 956 | loption: bool = false, |
| 796 | 957 | }; |
| 797 | 958 | |
| 798 | pub const InitOptions = struct { | |
| 959 | pub const CreateOptions = struct { | |
| 799 | 960 | zig_lib_directory: Directory, |
| 800 | 961 | local_cache_directory: Directory, |
| 801 | 962 | global_cache_directory: Directory, |
| 802 | target: Target, | |
| 803 | root_name: []const u8, | |
| 804 | main_mod: ?*Package.Module, | |
| 805 | output_mode: std.builtin.OutputMode, | |
| 806 | 963 | 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, | |
| 808 | 980 | sysroot: ?[]const u8 = null, |
| 809 | 981 | /// `null` means to not emit a binary file. |
| 810 | 982 | emit_bin: ?EmitLoc, |
| ... | ... | @@ -820,8 +992,6 @@ pub const InitOptions = struct { |
| 820 | 992 | emit_docs: ?EmitLoc = null, |
| 821 | 993 | /// `null` means to not emit an import lib. |
| 822 | 994 | emit_implib: ?EmitLoc = null, |
| 823 | link_mode: ?std.builtin.LinkMode = null, | |
| 824 | dll_export_fns: ?bool = false, | |
| 825 | 995 | /// Normally when using LLD to link, Zig uses a file named "lld.id" in the |
| 826 | 996 | /// same directory as the output binary which contains the hash of the link |
| 827 | 997 | /// operation, allowing Zig to skip linking when the hash would be unchanged. |
| ... | ... | @@ -830,14 +1000,11 @@ pub const InitOptions = struct { |
| 830 | 1000 | /// this flag would be set to disable this machinery to avoid false positives. |
| 831 | 1001 | disable_lld_caching: bool = false, |
| 832 | 1002 | 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{}, | |
| 836 | 1003 | lib_dirs: []const []const u8 = &[0][]const u8{}, |
| 837 | 1004 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 838 | 1005 | 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 = &.{}, | |
| 841 | 1008 | manifest_file: ?[]const u8 = null, |
| 842 | 1009 | rc_includes: RcIncludes = .any, |
| 843 | 1010 | link_objects: []LinkObject = &[0]LinkObject{}, |
| ... | ... | @@ -850,41 +1017,16 @@ pub const InitOptions = struct { |
| 850 | 1017 | /// * getpid |
| 851 | 1018 | /// * mman |
| 852 | 1019 | /// * 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 = &.{}, | |
| 858 | 1021 | /// This means that if the output mode is an executable it will be a |
| 859 | 1022 | /// Position Independent Executable. If the output mode is not an |
| 860 | 1023 | /// 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, | |
| 872 | 1024 | want_compiler_rt: ?bool = null, |
| 873 | 1025 | 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, | |
| 881 | 1026 | formatted_panics: ?bool = null, |
| 882 | rdynamic: bool = false, | |
| 883 | 1027 | function_sections: bool = false, |
| 884 | 1028 | data_sections: bool = false, |
| 885 | 1029 | no_builtin: bool = false, |
| 886 | is_native_os: bool, | |
| 887 | is_native_abi: bool, | |
| 888 | 1030 | time_report: bool = false, |
| 889 | 1031 | stack_report: bool = false, |
| 890 | 1032 | link_eh_frame_hdr: bool = false, |
| ... | ... | @@ -895,22 +1037,19 @@ pub const InitOptions = struct { |
| 895 | 1037 | linker_gc_sections: ?bool = null, |
| 896 | 1038 | linker_allow_shlib_undefined: ?bool = null, |
| 897 | 1039 | linker_bind_global_refs_locally: ?bool = null, |
| 898 | linker_import_memory: ?bool = null, | |
| 899 | linker_export_memory: ?bool = null, | |
| 900 | 1040 | linker_import_symbols: bool = false, |
| 901 | 1041 | linker_import_table: bool = false, |
| 902 | 1042 | linker_export_table: bool = false, |
| 903 | 1043 | linker_initial_memory: ?u64 = null, |
| 904 | 1044 | linker_max_memory: ?u64 = null, |
| 905 | linker_shared_memory: bool = false, | |
| 906 | 1045 | linker_global_base: ?u64 = null, |
| 907 | 1046 | linker_export_symbol_names: []const []const u8 = &.{}, |
| 908 | 1047 | linker_print_gc_sections: bool = false, |
| 909 | 1048 | linker_print_icf_sections: bool = false, |
| 910 | 1049 | linker_print_map: bool = false, |
| 911 | linker_opt_bisect_limit: i32 = -1, | |
| 1050 | llvm_opt_bisect_limit: i32 = -1, | |
| 912 | 1051 | each_lib_rpath: ?bool = null, |
| 913 | build_id: ?BuildId = null, | |
| 1052 | build_id: ?std.zig.BuildId = null, | |
| 914 | 1053 | disable_c_depfile: bool = false, |
| 915 | 1054 | linker_z_nodelete: bool = false, |
| 916 | 1055 | linker_z_notext: bool = false, |
| ... | ... | @@ -924,12 +1063,11 @@ pub const InitOptions = struct { |
| 924 | 1063 | linker_tsaware: bool = false, |
| 925 | 1064 | linker_nxcompat: bool = false, |
| 926 | 1065 | 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, | |
| 929 | 1067 | 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, | |
| 933 | 1071 | clang_passthrough_mode: bool = false, |
| 934 | 1072 | verbose_cc: bool = false, |
| 935 | 1073 | verbose_link: bool = false, |
| ... | ... | @@ -940,8 +1078,6 @@ pub const InitOptions = struct { |
| 940 | 1078 | verbose_llvm_bc: ?[]const u8 = null, |
| 941 | 1079 | verbose_cimport: bool = false, |
| 942 | 1080 | verbose_llvm_cpu_features: bool = false, |
| 943 | is_test: bool = false, | |
| 944 | test_evented_io: bool = false, | |
| 945 | 1081 | debug_compiler_runtime_libs: bool = false, |
| 946 | 1082 | debug_compile_errors: bool = false, |
| 947 | 1083 | /// Normally when you create a `Compilation`, Zig will automatically build |
| ... | ... | @@ -949,28 +1085,21 @@ pub const InitOptions = struct { |
| 949 | 1085 | /// building such dependencies themselves, this flag must be set to avoid |
| 950 | 1086 | /// infinite recursion. |
| 951 | 1087 | 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, | |
| 954 | 1090 | 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, | |
| 958 | 1093 | version: ?std.SemanticVersion = null, |
| 959 | 1094 | compatibility_version: ?std.SemanticVersion = null, |
| 960 | 1095 | libc_installation: ?*const LibCInstallation = null, |
| 961 | machine_code_model: std.builtin.CodeModel = .default, | |
| 1096 | native_system_include_paths: []const []const u8 = &.{}, | |
| 962 | 1097 | clang_preprocessor_mode: ClangPreprocessorMode = .no, |
| 963 | /// This is for stage1 and should be deleted upon completion of self-hosting. | |
| 964 | color: Color = .auto, | |
| 965 | 1098 | reference_trace: ?u32 = null, |
| 966 | error_tracing: ?bool = null, | |
| 967 | 1099 | test_filter: ?[]const u8 = null, |
| 968 | 1100 | test_name_prefix: ?[]const u8 = null, |
| 969 | 1101 | test_runner_path: ?[]const u8 = null, |
| 970 | 1102 | 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, | |
| 974 | 1103 | /// (Zig compiler development) Enable dumping linker's state as JSON. |
| 975 | 1104 | enable_link_snapshots: bool = false, |
| 976 | 1105 | /// (Darwin) Install name of the dylib |
| ... | ... | @@ -991,449 +1120,223 @@ pub const InitOptions = struct { |
| 991 | 1120 | pdb_source_path: ?[]const u8 = null, |
| 992 | 1121 | /// (Windows) PDB output path |
| 993 | 1122 | 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; | |
| 997 | 1127 | }; |
| 998 | 1128 | |
| 999 | 1129 | fn addModuleTableToCacheHash( |
| 1130 | gpa: Allocator, | |
| 1131 | arena: Allocator, | |
| 1000 | 1132 | 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, | |
| 1004 | 1134 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, |
| 1005 | 1135 | ) (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); | |
| 1016 | 1147 | } |
| 1017 | }.lessThan); | |
| 1148 | }; | |
| 1018 | 1149 | |
| 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); | |
| 1022 | 1160 | |
| 1023 | // Finally insert the package name and path to the cache hash. | |
| 1024 | hash.addBytes(mod_table.keys()[module_index]); | |
| 1025 | 1161 | switch (hash_type) { |
| 1026 | 1162 | .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); | |
| 1030 | 1166 | }, |
| 1031 | 1167 | .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); | |
| 1036 | 1169 | _ = try man.addFile(pkg_zig_file, null); |
| 1037 | 1170 | }, |
| 1038 | 1171 | } |
| 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, {}); | |
| 1041 | 1180 | } |
| 1042 | 1181 | } |
| 1043 | 1182 | |
| 1044 | pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | |
| 1045 | const is_dyn_lib = switch (options.output_mode) { | |
| 1183 | pub 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) { | |
| 1046 | 1186 | .Obj, .Exe => false, |
| 1047 | .Lib => (options.link_mode orelse .Static) == .Dynamic, | |
| 1187 | .Lib => options.config.link_mode == .Dynamic, | |
| 1048 | 1188 | }; |
| 1049 | const is_exe_or_dyn_lib = switch (options.output_mode) { | |
| 1189 | const is_exe_or_dyn_lib = switch (output_mode) { | |
| 1050 | 1190 | .Obj => false, |
| 1051 | 1191 | .Lib => is_dyn_lib, |
| 1052 | 1192 | .Exe => true, |
| 1053 | 1193 | }; |
| 1054 | 1194 | |
| 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 | ||
| 1058 | 1195 | if (options.linker_export_table and options.linker_import_table) { |
| 1059 | 1196 | return error.ExportTableAndImportTableConflict; |
| 1060 | 1197 | } |
| 1061 | 1198 | |
| 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; | |
| 1068 | 1200 | |
| 1201 | const comp: *Compilation = comp: { | |
| 1069 | 1202 | // We put the `Compilation` itself in the arena. Freeing the arena will free the module. |
| 1070 | 1203 | // It's initialized later after we prepare the initialization options. |
| 1071 | const comp = try arena.create(Compilation); | |
| 1072 | 1204 | const root_name = try arena.dupeZ(u8, options.root_name); |
| 1073 | 1205 | |
| 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; | |
| 1138 | 1207 | |
| 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; | |
| 1144 | 1214 | |
| 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; | |
| 1256 | 1217 | |
| 1257 | const dll_export_fns = options.dll_export_fns orelse (is_dyn_lib or options.rdynamic); | |
| 1218 | const link_libc = options.config.link_libc; | |
| 1258 | 1219 | |
| 1259 | 1220 | const libc_dirs = try detectLibCIncludeDirs( |
| 1260 | 1221 | arena, |
| 1261 | 1222 | 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, | |
| 1264 | 1225 | link_libc, |
| 1265 | 1226 | options.libc_installation, |
| 1266 | 1227 | ); |
| 1267 | 1228 | |
| 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 => {}, | |
| 1306 | 1250 | } |
| 1307 | 1251 | } |
| 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 | }; | |
| 1332 | 1289 | }; |
| 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 | } | |
| 1344 | 1290 | |
| 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; | |
| 1363 | 1292 | |
| 1364 | 1293 | const include_compiler_rt = options.want_compiler_rt orelse |
| 1365 | 1294 | (!options.skip_linker_dependencies and is_exe_or_dyn_lib); |
| 1366 | 1295 | |
| 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 | } | |
| 1404 | 1316 | |
| 1405 | 1317 | 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; | |
| 1407 | 1320 | std.debug.getStderrMutex().lock(); |
| 1408 | 1321 | defer std.debug.getStderrMutex().unlock(); |
| 1409 | 1322 | 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 | } | |
| 1414 | 1329 | } |
| 1415 | 1330 | } |
| 1416 | 1331 | |
| 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); | |
| 1434 | 1334 | |
| 1435 | 1335 | const error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1); |
| 1436 | 1336 | |
| 1337 | const each_lib_rpath = options.each_lib_rpath orelse | |
| 1338 | options.root_mod.resolved_target.is_native_os; | |
| 1339 | ||
| 1437 | 1340 | // We put everything into the cache hash that *cannot be modified |
| 1438 | 1341 | // during an incremental update*. For example, one cannot change the |
| 1439 | 1342 | // target between updates, but one can change source files, so the |
| ... | ... | @@ -1455,197 +1358,27 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1455 | 1358 | // This is shared hasher state common to zig source and all C source files. |
| 1456 | 1359 | cache.hash.addBytes(build_options.version); |
| 1457 | 1360 | 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); | |
| 1477 | 1364 | cache.hash.add(options.function_sections); |
| 1478 | 1365 | cache.hash.add(options.data_sections); |
| 1479 | 1366 | cache.hash.add(options.no_builtin); |
| 1480 | cache.hash.add(strip); | |
| 1481 | 1367 | 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); | |
| 1487 | 1372 | cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_bin); |
| 1488 | 1373 | cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_implib); |
| 1489 | 1374 | cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs); |
| 1490 | 1375 | 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); | |
| 1492 | 1377 | // TODO audit this and make sure everything is in it |
| 1493 | 1378 | |
| 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: { | |
| 1649 | 1382 | // Pre-open the directory handles for cached ZIR code so that it does not need |
| 1650 | 1383 | // to redundantly happen for each AstGen operation. |
| 1651 | 1384 | const zir_sub_dir = "z"; |
| ... | ... | @@ -1664,277 +1397,183 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1664 | 1397 | }; |
| 1665 | 1398 | |
| 1666 | 1399 | 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); | |
| 1668 | 1401 | eh.* = .{ .loc = loc }; |
| 1669 | 1402 | break :eh eh; |
| 1670 | 1403 | } else null; |
| 1671 | errdefer if (emit_h) |eh| gpa.destroy(eh); | |
| 1672 | 1404 | |
| 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 | }); | |
| 1678 | 1421 | |
| 1679 | const module = try arena.create(Module); | |
| 1680 | errdefer module.deinit(); | |
| 1681 | module.* = .{ | |
| 1422 | const zcu = try arena.create(Module); | |
| 1423 | zcu.* = .{ | |
| 1682 | 1424 | .gpa = gpa, |
| 1683 | 1425 | .comp = comp, |
| 1684 | 1426 | .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, | |
| 1687 | 1429 | .global_zir_cache = global_zir_cache, |
| 1688 | 1430 | .local_zir_cache = local_zir_cache, |
| 1689 | 1431 | .emit_h = emit_h, |
| 1690 | 1432 | .tmp_hack_arena = std.heap.ArenaAllocator.init(gpa), |
| 1691 | 1433 | .error_limit = error_limit, |
| 1434 | .llvm_object = null, | |
| 1692 | 1435 | }; |
| 1693 | try module.init(); | |
| 1694 | ||
| 1695 | break :blk module; | |
| 1436 | try zcu.init(); | |
| 1437 | break :blk zcu; | |
| 1696 | 1438 | } else blk: { |
| 1697 | 1439 | if (options.emit_h != null) return error.NoZigModuleForCHeader; |
| 1698 | 1440 | break :blk null; |
| 1699 | 1441 | }; |
| 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(); | |
| 1814 | 1443 | |
| 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 | ); | |
| 1827 | 1449 | 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 | } | |
| 1832 | 1450 | |
| 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, | |
| 1837 | 1502 | .root_name = root_name, |
| 1838 | .module = module, | |
| 1839 | .target = options.target, | |
| 1840 | .dynamic_linker = options.dynamic_linker, | |
| 1841 | 1503 | .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, | |
| 1852 | 1508 | .objects = options.link_objects, |
| 1853 | .frameworks = options.frameworks, | |
| 1854 | 1509 | .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, | |
| 1856 | 1517 | .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, | |
| 1857 | 1542 | .lib_dirs = options.lib_dirs, |
| 1858 | 1543 | .rpath_list = options.rpath_list, |
| 1859 | 1544 | .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, | |
| 1866 | 1545 | .allow_shlib_undefined = options.linker_allow_shlib_undefined, |
| 1867 | 1546 | .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, |
| 1868 | 1547 | .compress_debug_sections = options.linker_compress_debug_sections orelse .none, |
| 1869 | 1548 | .module_definition_file = options.linker_module_definition_file, |
| 1870 | 1549 | .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), | |
| 1873 | 1550 | .import_symbols = options.linker_import_symbols, |
| 1874 | 1551 | .import_table = options.linker_import_table, |
| 1875 | 1552 | .export_table = options.linker_export_table, |
| 1876 | 1553 | .initial_memory = options.linker_initial_memory, |
| 1877 | 1554 | .max_memory = options.linker_max_memory, |
| 1878 | .shared_memory = options.linker_shared_memory, | |
| 1879 | 1555 | .global_base = options.linker_global_base, |
| 1880 | 1556 | .export_symbol_names = options.linker_export_symbol_names, |
| 1881 | 1557 | .print_gc_sections = options.linker_print_gc_sections, |
| 1882 | 1558 | .print_icf_sections = options.linker_print_icf_sections, |
| 1883 | 1559 | .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, | |
| 1894 | 1560 | .tsaware = options.linker_tsaware, |
| 1895 | 1561 | .nxcompat = options.linker_nxcompat, |
| 1896 | 1562 | .dynamicbase = options.linker_dynamicbase, |
| 1897 | .linker_optimization = linker_optimization, | |
| 1898 | 1563 | .major_subsystem_version = options.major_subsystem_version, |
| 1899 | 1564 | .minor_subsystem_version = options.minor_subsystem_version, |
| 1900 | 1565 | .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, | |
| 1905 | 1568 | .version_script = options.version_script, |
| 1906 | 1569 | .gc_sections = options.linker_gc_sections, |
| 1907 | .eh_frame_hdr = link_eh_frame_hdr, | |
| 1908 | 1570 | .emit_relocs = options.link_emit_relocs, |
| 1909 | .rdynamic = options.rdynamic, | |
| 1910 | 1571 | .soname = options.soname, |
| 1911 | .version = options.version, | |
| 1912 | 1572 | .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, | |
| 1931 | 1574 | .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, | |
| 1934 | 1576 | .subsystem = options.subsystem, |
| 1935 | .is_test = options.is_test, | |
| 1936 | .dwarf_format = options.dwarf_format, | |
| 1937 | .wasi_exec_model = wasi_exec_model, | |
| 1938 | 1577 | .hash_style = options.hash_style, |
| 1939 | 1578 | .enable_link_snapshots = options.enable_link_snapshots, |
| 1940 | 1579 | .install_name = options.install_name, |
| ... | ... | @@ -1943,76 +1582,125 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1943 | 1582 | .headerpad_size = options.headerpad_size, |
| 1944 | 1583 | .headerpad_max_install_names = options.headerpad_max_install_names, |
| 1945 | 1584 | .dead_strip_dylibs = options.dead_strip_dylibs, |
| 1946 | .force_undefined_symbols = options.force_undefined_symbols, | |
| 1947 | 1585 | .pdb_source_path = options.pdb_source_path, |
| 1948 | 1586 | .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?) | |
| 2007 | 1588 | }; |
| 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 | ||
| 2008 | 1696 | break :comp comp; |
| 2009 | 1697 | }; |
| 2010 | 1698 | errdefer comp.destroy(); |
| 2011 | 1699 | |
| 2012 | const target = comp.getTarget(); | |
| 1700 | const target = comp.root_mod.resolved_target.result; | |
| 2013 | 1701 | |
| 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); | |
| 2016 | 1704 | |
| 2017 | 1705 | // Add a `CObject` for each `c_source_files`. |
| 2018 | 1706 | try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len); |
| ... | ... | @@ -2052,9 +1740,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2052 | 1740 | } |
| 2053 | 1741 | } |
| 2054 | 1742 | |
| 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 | }; | |
| 2056 | 1747 | |
| 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) { | |
| 2058 | 1749 | if (target.isDarwin()) { |
| 2059 | 1750 | switch (target.abi) { |
| 2060 | 1751 | .none, |
| ... | ... | @@ -2095,27 +1786,30 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2095 | 1786 | .{ .musl_crt_file = .crt1_o }, |
| 2096 | 1787 | .{ .musl_crt_file = .scrt1_o }, |
| 2097 | 1788 | .{ .musl_crt_file = .rcrt1_o }, |
| 2098 | switch (comp.bin_file.options.link_mode) { | |
| 1789 | switch (comp.config.link_mode) { | |
| 2099 | 1790 | .Static => .{ .musl_crt_file = .libc_a }, |
| 2100 | 1791 | .Dynamic => .{ .musl_crt_file = .libc_so }, |
| 2101 | 1792 | }, |
| 2102 | 1793 | }); |
| 2103 | 1794 | } |
| 1795 | ||
| 2104 | 1796 | if (comp.wantBuildWasiLibcFromSource()) { |
| 2105 | 1797 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 2106 | 1798 | |
| 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| { | |
| 2110 | 1803 | comp.work_queue.writeItemAssumeCapacity(.{ |
| 2111 | 1804 | .wasi_libc_crt_file = crt_file, |
| 2112 | 1805 | }); |
| 2113 | 1806 | } |
| 2114 | 1807 | 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) }, | |
| 2116 | 1809 | .{ .wasi_libc_crt_file = .libc_a }, |
| 2117 | 1810 | }); |
| 2118 | 1811 | } |
| 1812 | ||
| 2119 | 1813 | if (comp.wantBuildMinGWFromSource()) { |
| 2120 | 1814 | if (!target_util.canBuildLibC(target)) return error.LibCUnavailable; |
| 2121 | 1815 | |
| ... | ... | @@ -2132,7 +1826,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2132 | 1826 | |
| 2133 | 1827 | // When linking mingw-w64 there are some import libs we always need. |
| 2134 | 1828 | 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, .{ | |
| 2136 | 1830 | .needed = false, |
| 2137 | 1831 | .weak = false, |
| 2138 | 1832 | .path = null, |
| ... | ... | @@ -2141,7 +1835,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2141 | 1835 | } |
| 2142 | 1836 | // Generate Windows import libs. |
| 2143 | 1837 | if (target.os.tag == .windows) { |
| 2144 | const count = comp.bin_file.options.system_libs.count(); | |
| 1838 | const count = comp.system_libs.count(); | |
| 2145 | 1839 | try comp.work_queue.ensureUnusedCapacity(count); |
| 2146 | 1840 | for (0..count) |i| { |
| 2147 | 1841 | comp.work_queue.writeItemAssumeCapacity(.{ .windows_import_lib = i }); |
| ... | ... | @@ -2150,31 +1844,31 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2150 | 1844 | if (comp.wantBuildLibUnwindFromSource()) { |
| 2151 | 1845 | try comp.work_queue.writeItem(.{ .libunwind = {} }); |
| 2152 | 1846 | } |
| 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) { | |
| 2154 | 1848 | try comp.work_queue.writeItem(.libcxx); |
| 2155 | 1849 | try comp.work_queue.writeItem(.libcxxabi); |
| 2156 | 1850 | } |
| 2157 | if (build_options.have_llvm and comp.bin_file.options.tsan) { | |
| 1851 | if (build_options.have_llvm and comp.config.any_sanitize_thread) { | |
| 2158 | 1852 | try comp.work_queue.writeItem(.libtsan); |
| 2159 | 1853 | } |
| 2160 | 1854 | |
| 2161 | if (comp.getTarget().isMinGW() and !comp.bin_file.options.single_threaded) { | |
| 1855 | if (target.isMinGW() and comp.config.any_non_single_threaded) { | |
| 2162 | 1856 | // LLD might drop some symbols as unused during LTO and GCing, therefore, |
| 2163 | 1857 | // we force mark them for resolution here. |
| 2164 | 1858 | |
| 2165 | const tls_index_sym = switch (comp.getTarget().cpu.arch) { | |
| 1859 | const tls_index_sym = switch (target.cpu.arch) { | |
| 2166 | 1860 | .x86 => "__tls_index", |
| 2167 | 1861 | else => "_tls_index", |
| 2168 | 1862 | }; |
| 2169 | 1863 | |
| 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, {}); | |
| 2171 | 1865 | } |
| 2172 | 1866 | |
| 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) { | |
| 2174 | 1868 | if (is_exe_or_dyn_lib) { |
| 2175 | 1869 | log.debug("queuing a job to build compiler_rt_lib", .{}); |
| 2176 | 1870 | comp.job_queued_compiler_rt_lib = true; |
| 2177 | } else if (options.output_mode != .Obj) { | |
| 1871 | } else if (output_mode != .Obj) { | |
| 2178 | 1872 | log.debug("queuing a job to build compiler_rt_obj", .{}); |
| 2179 | 1873 | // In this case we are making a static library, so we ask |
| 2180 | 1874 | // for a compiler-rt object to put in it. |
| ... | ... | @@ -2182,8 +1876,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2182 | 1876 | } |
| 2183 | 1877 | } |
| 2184 | 1878 | |
| 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) | |
| 2187 | 1881 | { |
| 2188 | 1882 | try comp.work_queue.writeItem(.{ .zig_libc = {} }); |
| 2189 | 1883 | } |
| ... | ... | @@ -2192,88 +1886,87 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 2192 | 1886 | return comp; |
| 2193 | 1887 | } |
| 2194 | 1888 | |
| 2195 | pub 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(); | |
| 1889 | pub 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(); | |
| 2204 | 1896 | if (!build_options.only_core_functionality) { |
| 2205 | self.win32_resource_work_queue.deinit(); | |
| 1897 | comp.win32_resource_work_queue.deinit(); | |
| 2206 | 1898 | } |
| 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); | |
| 2209 | 1904 | |
| 2210 | 1905 | { |
| 2211 | var it = self.crt_files.iterator(); | |
| 1906 | var it = comp.crt_files.iterator(); | |
| 2212 | 1907 | while (it.next()) |entry| { |
| 2213 | 1908 | gpa.free(entry.key_ptr.*); |
| 2214 | 1909 | entry.value_ptr.deinit(gpa); |
| 2215 | 1910 | } |
| 2216 | self.crt_files.deinit(gpa); | |
| 1911 | comp.crt_files.deinit(gpa); | |
| 2217 | 1912 | } |
| 2218 | 1913 | |
| 2219 | if (self.libunwind_static_lib) |*crt_file| { | |
| 1914 | if (comp.libunwind_static_lib) |*crt_file| { | |
| 2220 | 1915 | crt_file.deinit(gpa); |
| 2221 | 1916 | } |
| 2222 | if (self.libcxx_static_lib) |*crt_file| { | |
| 1917 | if (comp.libcxx_static_lib) |*crt_file| { | |
| 2223 | 1918 | crt_file.deinit(gpa); |
| 2224 | 1919 | } |
| 2225 | if (self.libcxxabi_static_lib) |*crt_file| { | |
| 1920 | if (comp.libcxxabi_static_lib) |*crt_file| { | |
| 2226 | 1921 | crt_file.deinit(gpa); |
| 2227 | 1922 | } |
| 2228 | if (self.compiler_rt_lib) |*crt_file| { | |
| 1923 | if (comp.compiler_rt_lib) |*crt_file| { | |
| 2229 | 1924 | crt_file.deinit(gpa); |
| 2230 | 1925 | } |
| 2231 | if (self.compiler_rt_obj) |*crt_file| { | |
| 1926 | if (comp.compiler_rt_obj) |*crt_file| { | |
| 2232 | 1927 | crt_file.deinit(gpa); |
| 2233 | 1928 | } |
| 2234 | if (self.libc_static_lib) |*crt_file| { | |
| 1929 | if (comp.libc_static_lib) |*crt_file| { | |
| 2235 | 1930 | crt_file.deinit(gpa); |
| 2236 | 1931 | } |
| 2237 | 1932 | |
| 2238 | if (self.glibc_so_files) |*glibc_file| { | |
| 1933 | if (comp.glibc_so_files) |*glibc_file| { | |
| 2239 | 1934 | glibc_file.deinit(gpa); |
| 2240 | 1935 | } |
| 2241 | 1936 | |
| 2242 | for (self.c_object_table.keys()) |key| { | |
| 1937 | for (comp.c_object_table.keys()) |key| { | |
| 2243 | 1938 | key.destroy(gpa); |
| 2244 | 1939 | } |
| 2245 | self.c_object_table.deinit(gpa); | |
| 1940 | comp.c_object_table.deinit(gpa); | |
| 2246 | 1941 | |
| 2247 | for (self.failed_c_objects.values()) |bundle| { | |
| 1942 | for (comp.failed_c_objects.values()) |bundle| { | |
| 2248 | 1943 | bundle.destroy(gpa); |
| 2249 | 1944 | } |
| 2250 | self.failed_c_objects.deinit(gpa); | |
| 1945 | comp.failed_c_objects.deinit(gpa); | |
| 2251 | 1946 | |
| 2252 | 1947 | if (!build_options.only_core_functionality) { |
| 2253 | for (self.win32_resource_table.keys()) |key| { | |
| 1948 | for (comp.win32_resource_table.keys()) |key| { | |
| 2254 | 1949 | key.destroy(gpa); |
| 2255 | 1950 | } |
| 2256 | self.win32_resource_table.deinit(gpa); | |
| 1951 | comp.win32_resource_table.deinit(gpa); | |
| 2257 | 1952 | |
| 2258 | for (self.failed_win32_resources.values()) |*value| { | |
| 1953 | for (comp.failed_win32_resources.values()) |*value| { | |
| 2259 | 1954 | value.deinit(gpa); |
| 2260 | 1955 | } |
| 2261 | self.failed_win32_resources.deinit(gpa); | |
| 1956 | comp.failed_win32_resources.deinit(gpa); | |
| 2262 | 1957 | } |
| 2263 | 1958 | |
| 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| { | |
| 2265 | 1963 | lld_error.deinit(gpa); |
| 2266 | 1964 | } |
| 2267 | self.lld_errors.deinit(gpa); | |
| 2268 | ||
| 2269 | self.clearMiscFailures(); | |
| 1965 | comp.lld_errors.deinit(gpa); | |
| 2270 | 1966 | |
| 2271 | self.cache_parent.manifest_dir.close(); | |
| 2272 | if (self.owned_link_dir) |*dir| dir.close(); | |
| 1967 | comp.clearMiscFailures(); | |
| 2273 | 1968 | |
| 2274 | // This destroys `self`. | |
| 2275 | var arena_instance = self.arena; | |
| 2276 | arena_instance.deinit(); | |
| 1969 | comp.cache_parent.manifest_dir.close(); | |
| 2277 | 1970 | } |
| 2278 | 1971 | |
| 2279 | 1972 | pub fn clearMiscFailures(comp: *Compilation) void { |
| ... | ... | @@ -2286,135 +1979,142 @@ pub fn clearMiscFailures(comp: *Compilation) void { |
| 2286 | 1979 | } |
| 2287 | 1980 | |
| 2288 | 1981 | pub fn getTarget(self: Compilation) Target { |
| 2289 | return self.bin_file.options.target; | |
| 1982 | return self.root_mod.resolved_target.result; | |
| 2290 | 1983 | } |
| 2291 | 1984 | |
| 2292 | fn 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. | |
| 1986 | pub 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(); | |
| 2302 | 1996 | } |
| 2303 | 1997 | |
| 2304 | fn 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); | |
| 1998 | fn 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 | }, | |
| 2313 | 2016 | } |
| 2314 | 2017 | } |
| 2315 | 2018 | |
| 2316 | pub 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 | ||
| 2323 | 2019 | /// Detect changes to source files, perform semantic analysis, and update the output files. |
| 2324 | 2020 | pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void { |
| 2325 | 2021 | const tracy_trace = trace(@src()); |
| 2326 | 2022 | defer tracy_trace.end(); |
| 2327 | 2023 | |
| 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 | ||
| 2328 | 2030 | comp.clearMiscFailures(); |
| 2329 | 2031 | comp.last_update_was_cache_hit = false; |
| 2330 | 2032 | |
| 2331 | 2033 | var man: Cache.Manifest = undefined; |
| 2332 | defer if (comp.whole_cache_manifest != null) man.deinit(); | |
| 2034 | defer cleanupAfterUpdate(comp); | |
| 2333 | 2035 | |
| 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; | |
| 2337 | 2037 | |
| 2338 | 2038 | // If using the whole caching strategy, we check for *everything* up front, including |
| 2339 | 2039 | // 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(); | |
| 2362 | 2064 | |
| 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); | |
| 2368 | 2066 | |
| 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}); | |
| 2374 | 2072 | |
| 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); | |
| 2376 | 2078 | |
| 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); | |
| 2379 | 2081 | |
| 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(); | |
| 2382 | 2084 | |
| 2383 | break :d .{ | |
| 2384 | .path = path, | |
| 2385 | .handle = handle, | |
| 2085 | break :d .{ | |
| 2086 | .path = path, | |
| 2087 | .handle = handle, | |
| 2088 | }; | |
| 2386 | 2089 | }; |
| 2387 | }; | |
| 2090 | whole.tmp_artifact_directory = tmp_artifact_directory; | |
| 2388 | 2091 | |
| 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. | |
| 2393 | 2094 | |
| 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 => {}, | |
| 2418 | 2118 | } |
| 2419 | 2119 | |
| 2420 | 2120 | // 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 |
| 2433 | 2133 | } |
| 2434 | 2134 | } |
| 2435 | 2135 | |
| 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); | |
| 2438 | 2138 | module.generation += 1; |
| 2439 | 2139 | |
| 2440 | 2140 | // Make sure std.zig is inside the import_table. We unconditionally need |
| 2441 | 2141 | // it for start.zig. |
| 2442 | const std_mod = module.main_mod.deps.get("std").?; | |
| 2142 | const std_mod = module.std_mod; | |
| 2443 | 2143 | _ = try module.importPkg(std_mod); |
| 2444 | 2144 | |
| 2445 | 2145 | // 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 |
| 2448 | 2148 | // import_table here. |
| 2449 | 2149 | // Likewise, in the case of `zig test`, the test runner is the root source file, |
| 2450 | 2150 | // and so there is nothing to import the main file. |
| 2451 | if (comp.bin_file.options.is_test) { | |
| 2151 | if (comp.config.is_test) { | |
| 2452 | 2152 | _ = try module.importPkg(module.main_mod); |
| 2453 | 2153 | } |
| 2454 | 2154 | |
| 2455 | if (module.main_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | |
| 2155 | if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | |
| 2456 | 2156 | _ = try module.importPkg(compiler_rt_mod); |
| 2457 | 2157 | } |
| 2458 | 2158 | |
| 2459 | 2159 | // Put a work item in for every known source file to detect if |
| 2460 | 2160 | // it changed, and, if so, re-compute ZIR and then queue the job |
| 2461 | 2161 | // 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. | |
| 2464 | 2162 | 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); | |
| 2467 | 2166 | } |
| 2468 | 2167 | |
| 2469 | 2168 | // 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 |
| 2473 | 2172 | } |
| 2474 | 2173 | |
| 2475 | 2174 | try comp.work_queue.writeItem(.{ .analyze_mod = std_mod }); |
| 2476 | if (comp.bin_file.options.is_test) { | |
| 2175 | if (comp.config.is_test) { | |
| 2477 | 2176 | try comp.work_queue.writeItem(.{ .analyze_mod = module.main_mod }); |
| 2478 | 2177 | } |
| 2479 | 2178 | |
| 2480 | if (module.main_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | |
| 2179 | if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | |
| 2481 | 2180 | try comp.work_queue.writeItem(.{ .analyze_mod = compiler_rt_mod }); |
| 2482 | 2181 | } |
| 2483 | 2182 | } |
| 2484 | 2183 | |
| 2485 | 2184 | try comp.performAllTheWork(main_progress_node); |
| 2486 | 2185 | |
| 2487 | if (comp.bin_file.options.module) |module| { | |
| 2186 | if (comp.module) |module| { | |
| 2488 | 2187 | if (builtin.mode == .Debug and comp.verbose_intern_pool) { |
| 2489 | 2188 | std.debug.print("intern pool stats for '{s}':\n", .{ |
| 2490 | comp.bin_file.options.root_name, | |
| 2189 | comp.root_name, | |
| 2491 | 2190 | }); |
| 2492 | 2191 | module.intern_pool.dump(); |
| 2493 | 2192 | } |
| 2494 | 2193 | |
| 2495 | 2194 | if (builtin.mode == .Debug and comp.verbose_generic_instances) { |
| 2496 | 2195 | std.debug.print("generic instances for '{s}:0x{x}':\n", .{ |
| 2497 | comp.bin_file.options.root_name, | |
| 2196 | comp.root_name, | |
| 2498 | 2197 | @as(usize, @intFromPtr(module)), |
| 2499 | 2198 | }); |
| 2500 | module.intern_pool.dumpGenericInstances(comp.gpa); | |
| 2199 | module.intern_pool.dumpGenericInstances(gpa); | |
| 2501 | 2200 | } |
| 2502 | 2201 | |
| 2503 | if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) { | |
| 2202 | if (comp.config.is_test and comp.totalErrorCount() == 0) { | |
| 2504 | 2203 | // The `test_functions` decl has been intentionally postponed until now, |
| 2505 | 2204 | // at which point we must populate it with the list of test functions that |
| 2506 | 2205 | // have been discovered and not filtered out. |
| ... | ... | @@ -2516,106 +2215,188 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void |
| 2516 | 2215 | return; |
| 2517 | 2216 | } |
| 2518 | 2217 | |
| 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. | |
| 2521 | 2220 | comp.emitOthers(); |
| 2522 | 2221 | |
| 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(); | |
| 2525 | 2225 | |
| 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; | |
| 2548 | 2233 | |
| 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 | }; | |
| 2551 | 2259 | |
| 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 | }; | |
| 2556 | 2281 | |
| 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 | } | |
| 2563 | 2287 | |
| 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; | |
| 2566 | 2290 | |
| 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)}); | |
| 2570 | 2294 | }; |
| 2571 | 2295 | |
| 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 | } | |
| 2574 | 2300 | |
| 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); | |
| 2580 | 2306 | if (comp.totalErrorCount() != 0) return; |
| 2581 | } | |
| 2307 | }, | |
| 2308 | } | |
| 2309 | } | |
| 2582 | 2310 | |
| 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)}); | |
| 2311 | fn 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, | |
| 2586 | 2318 | }; |
| 2319 | } | |
| 2587 | 2320 | |
| 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); | |
| 2592 | 2323 | |
| 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); | |
| 2595 | 2337 | } |
| 2596 | 2338 | } |
| 2597 | 2339 | |
| 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`. | |
| 2355 | fn 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; | |
| 2609 | 2390 | } |
| 2610 | 2391 | } |
| 2611 | 2392 | |
| 2612 | 2393 | fn 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; | |
| 2614 | 2395 | // TODO: do this in a separate job during performAllTheWork(). The |
| 2615 | 2396 | // file copies at the end of generate() can also be extracted to |
| 2616 | 2397 | // separate jobs |
| 2617 | 2398 | 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| { | |
| 2619 | 2400 | var dir = try emit.directory.handle.makeOpenPath(emit.sub_path, .{}); |
| 2620 | 2401 | defer dir.close(); |
| 2621 | 2402 | |
| ... | ... | @@ -2629,46 +2410,31 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi |
| 2629 | 2410 | } |
| 2630 | 2411 | } |
| 2631 | 2412 | |
| 2632 | fn 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 | ||
| 2646 | 2413 | /// Communicate the output binary location to parent Compilations. |
| 2647 | fn wholeCacheModeSetBinFilePath(comp: *Compilation, digest: *const [Cache.hex_digest_len]u8) void { | |
| 2414 | fn wholeCacheModeSetBinFilePath( | |
| 2415 | comp: *Compilation, | |
| 2416 | whole: *CacheUse.Whole, | |
| 2417 | digest: *const [Cache.hex_digest_len]u8, | |
| 2418 | ) void { | |
| 2648 | 2419 | const digest_start = 2; // "o/[digest]/[basename]" |
| 2649 | 2420 | |
| 2650 | if (comp.whole_bin_sub_path) |sub_path| { | |
| 2421 | if (whole.bin_sub_path) |sub_path| { | |
| 2651 | 2422 | @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 | }; | |
| 2657 | 2423 | } |
| 2658 | 2424 | |
| 2659 | if (comp.whole_implib_sub_path) |sub_path| { | |
| 2425 | if (whole.implib_sub_path) |sub_path| { | |
| 2660 | 2426 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2661 | 2427 | |
| 2662 | comp.bin_file.options.implib_emit = .{ | |
| 2428 | comp.implib_emit = .{ | |
| 2663 | 2429 | .directory = comp.local_cache_directory, |
| 2664 | 2430 | .sub_path = sub_path, |
| 2665 | 2431 | }; |
| 2666 | 2432 | } |
| 2667 | 2433 | |
| 2668 | if (comp.whole_docs_sub_path) |sub_path| { | |
| 2434 | if (whole.docs_sub_path) |sub_path| { | |
| 2669 | 2435 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2670 | 2436 | |
| 2671 | comp.bin_file.options.docs_emit = .{ | |
| 2437 | comp.docs_emit = .{ | |
| 2672 | 2438 | .directory = comp.local_cache_directory, |
| 2673 | 2439 | .sub_path = sub_path, |
| 2674 | 2440 | }; |
| ... | ... | @@ -2689,51 +2455,33 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2689 | 2455 | /// anything from the link cache manifest. |
| 2690 | 2456 | pub const link_hash_implementation_version = 10; |
| 2691 | 2457 | |
| 2692 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { | |
| 2458 | fn addNonIncrementalStuffToCacheManifest( | |
| 2459 | comp: *Compilation, | |
| 2460 | arena: Allocator, | |
| 2461 | man: *Cache.Manifest, | |
| 2462 | ) !void { | |
| 2693 | 2463 | 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(); | |
| 2699 | 2464 | |
| 2700 | 2465 | comptime assert(link_hash_implementation_version == 10); |
| 2701 | 2466 | |
| 2702 | if (comp.bin_file.options.module) |mod| { | |
| 2467 | if (comp.module) |mod| { | |
| 2703 | 2468 | const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path); |
| 2704 | 2469 | _ = 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 }); | |
| 2715 | 2471 | |
| 2716 | 2472 | // 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); | |
| 2724 | 2474 | man.hash.addOptionalBytes(comp.test_filter); |
| 2725 | 2475 | 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); | |
| 2727 | 2477 | man.hash.add(comp.formatted_panics); |
| 2728 | 2478 | man.hash.add(mod.emit_h != null); |
| 2729 | 2479 | 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); | |
| 2731 | 2482 | } |
| 2732 | 2483 | |
| 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| { | |
| 2737 | 2485 | _ = try man.addFile(obj.path, null); |
| 2738 | 2486 | man.hash.add(obj.must_link); |
| 2739 | 2487 | man.hash.add(obj.loption); |
| ... | ... | @@ -2759,88 +2507,99 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2759 | 2507 | } |
| 2760 | 2508 | } |
| 2761 | 2509 | |
| 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); | |
| 2762 | 2524 | 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); | |
| 2763 | 2528 | |
| 2764 | 2529 | cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm); |
| 2765 | 2530 | cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir); |
| 2766 | 2531 | cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc); |
| 2767 | 2532 | |
| 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| { | |
| 2798 | 2552 | man.hash.addOptionalBytes(libc_installation.crt_dir); |
| 2799 | 2553 | if (target.abi == .msvc) { |
| 2800 | 2554 | man.hash.addOptionalBytes(libc_installation.msvc_lib_dir); |
| 2801 | 2555 | man.hash.addOptionalBytes(libc_installation.kernel32_lib_dir); |
| 2802 | 2556 | } |
| 2803 | 2557 | } |
| 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); | |
| 2815 | 2578 | |
| 2816 | 2579 | // 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); | |
| 2823 | 2583 | |
| 2824 | 2584 | // 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); | |
| 2832 | 2591 | |
| 2833 | 2592 | // 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); | |
| 2840 | 2599 | } |
| 2841 | 2600 | |
| 2842 | 2601 | fn 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 | |
| 2844 | 2603 | comp.c_object_table.count() == 0) |
| 2845 | 2604 | { |
| 2846 | 2605 | return; |
| ... | ... | @@ -2877,6 +2636,50 @@ fn emitOthers(comp: *Compilation) void { |
| 2877 | 2636 | } |
| 2878 | 2637 | } |
| 2879 | 2638 | |
| 2639 | pub 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 | ||
| 2670 | fn 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 | ||
| 2880 | 2683 | fn reportMultiModuleErrors(mod: *Module) !void { |
| 2881 | 2684 | // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to |
| 2882 | 2685 | // print all of, so we'll cap the number of these to emit. |
| ... | ... | @@ -2982,12 +2785,14 @@ fn reportMultiModuleErrors(mod: *Module) !void { |
| 2982 | 2785 | /// binary is concerned. This will remove the write flag, or close the file, |
| 2983 | 2786 | /// or whatever is needed so that it can be executed. |
| 2984 | 2787 | /// After this, one must call` makeFileWritable` before calling `update`. |
| 2985 | pub fn makeBinFileExecutable(self: *Compilation) !void { | |
| 2986 | return self.bin_file.makeExecutable(); | |
| 2788 | pub fn makeBinFileExecutable(comp: *Compilation) !void { | |
| 2789 | const lf = comp.bin_file orelse return; | |
| 2790 | return lf.makeExecutable(); | |
| 2987 | 2791 | } |
| 2988 | 2792 | |
| 2989 | pub fn makeBinFileWritable(self: *Compilation) !void { | |
| 2990 | return self.bin_file.makeWritable(); | |
| 2793 | pub fn makeBinFileWritable(comp: *Compilation) !void { | |
| 2794 | const lf = comp.bin_file orelse return; | |
| 2795 | return lf.makeWritable(); | |
| 2991 | 2796 | } |
| 2992 | 2797 | |
| 2993 | 2798 | const Header = extern struct { |
| ... | ... | @@ -3006,10 +2811,10 @@ pub fn saveState(comp: *Compilation) !void { |
| 3006 | 2811 | var bufs_list: [6]std.os.iovec_const = undefined; |
| 3007 | 2812 | var bufs_len: usize = 0; |
| 3008 | 2813 | |
| 3009 | const emit = comp.bin_file.options.emit orelse return; | |
| 2814 | const lf = comp.bin_file orelse return; | |
| 3010 | 2815 | |
| 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; | |
| 3013 | 2818 | const header: Header = .{ |
| 3014 | 2819 | .intern_pool = .{ |
| 3015 | 2820 | .items_len = @intCast(ip.items.len), |
| ... | ... | @@ -3033,7 +2838,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 3033 | 2838 | } |
| 3034 | 2839 | var basename_buf: [255]u8 = undefined; |
| 3035 | 2840 | const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{ |
| 3036 | comp.bin_file.options.root_name, | |
| 2841 | comp.root_name, | |
| 3037 | 2842 | }) catch o: { |
| 3038 | 2843 | basename_buf[basename_buf.len - 4 ..].* = ".zcs".*; |
| 3039 | 2844 | break :o &basename_buf; |
| ... | ... | @@ -3041,7 +2846,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 3041 | 2846 | |
| 3042 | 2847 | // Using an atomic file prevents a crash or power failure from corrupting |
| 3043 | 2848 | // the previous incremental compilation state. |
| 3044 | var af = try emit.directory.handle.atomicFile(basename, .{}); | |
| 2849 | var af = try lf.emit.directory.handle.atomicFile(basename, .{}); | |
| 3045 | 2850 | defer af.deinit(); |
| 3046 | 2851 | try af.file.pwritevAll(bufs_list[0..bufs_len], 0); |
| 3047 | 2852 | try af.finish(); |
| ... | ... | @@ -3057,23 +2862,23 @@ fn addBuf(bufs_list: []std.os.iovec_const, bufs_len: *usize, buf: []const u8) vo |
| 3057 | 2862 | } |
| 3058 | 2863 | |
| 3059 | 2864 | /// This function is temporally single-threaded. |
| 3060 | pub fn totalErrorCount(self: *Compilation) u32 { | |
| 2865 | pub fn totalErrorCount(comp: *Compilation) u32 { | |
| 3061 | 2866 | 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; | |
| 3065 | 2870 | |
| 3066 | for (self.failed_c_objects.values()) |bundle| { | |
| 2871 | for (comp.failed_c_objects.values()) |bundle| { | |
| 3067 | 2872 | total += bundle.diags.len; |
| 3068 | 2873 | } |
| 3069 | 2874 | |
| 3070 | 2875 | if (!build_options.only_core_functionality) { |
| 3071 | for (self.failed_win32_resources.values()) |errs| { | |
| 2876 | for (comp.failed_win32_resources.values()) |errs| { | |
| 3072 | 2877 | total += errs.errorMessageCount(); |
| 3073 | 2878 | } |
| 3074 | 2879 | } |
| 3075 | 2880 | |
| 3076 | if (self.bin_file.options.module) |module| { | |
| 2881 | if (comp.module) |module| { | |
| 3077 | 2882 | total += module.failed_exports.count(); |
| 3078 | 2883 | total += module.failed_embed_files.count(); |
| 3079 | 2884 | |
| ... | ... | @@ -3116,16 +2921,15 @@ pub fn totalErrorCount(self: *Compilation) u32 { |
| 3116 | 2921 | |
| 3117 | 2922 | // The "no entry point found" error only counts if there are no semantic analysis errors. |
| 3118 | 2923 | 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); | |
| 3120 | 2925 | } |
| 3121 | total += @intFromBool(self.link_error_flags.missing_libc); | |
| 2926 | total += @intFromBool(comp.link_error_flags.missing_libc); | |
| 3122 | 2927 | |
| 3123 | // Misc linker errors | |
| 3124 | total += self.bin_file.miscErrors().len; | |
| 2928 | total += comp.link_errors.items.len; | |
| 3125 | 2929 | |
| 3126 | 2930 | // Compile log errors only count if there are no other errors. |
| 3127 | 2931 | if (total == 0) { |
| 3128 | if (self.bin_file.options.module) |module| { | |
| 2932 | if (comp.module) |module| { | |
| 3129 | 2933 | total += @intFromBool(module.compile_log_decls.count() != 0); |
| 3130 | 2934 | } |
| 3131 | 2935 | } |
| ... | ... | @@ -3134,24 +2938,24 @@ pub fn totalErrorCount(self: *Compilation) u32 { |
| 3134 | 2938 | } |
| 3135 | 2939 | |
| 3136 | 2940 | /// This function is temporally single-threaded. |
| 3137 | pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | |
| 3138 | const gpa = self.gpa; | |
| 2941 | pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { | |
| 2942 | const gpa = comp.gpa; | |
| 3139 | 2943 | |
| 3140 | 2944 | var bundle: ErrorBundle.Wip = undefined; |
| 3141 | 2945 | try bundle.init(gpa); |
| 3142 | 2946 | defer bundle.deinit(); |
| 3143 | 2947 | |
| 3144 | for (self.failed_c_objects.values()) |diag_bundle| { | |
| 2948 | for (comp.failed_c_objects.values()) |diag_bundle| { | |
| 3145 | 2949 | try diag_bundle.addToErrorBundle(&bundle); |
| 3146 | 2950 | } |
| 3147 | 2951 | |
| 3148 | 2952 | if (!build_options.only_core_functionality) { |
| 3149 | for (self.failed_win32_resources.values()) |error_bundle| { | |
| 2953 | for (comp.failed_win32_resources.values()) |error_bundle| { | |
| 3150 | 2954 | try bundle.addBundleAsRoots(error_bundle); |
| 3151 | 2955 | } |
| 3152 | 2956 | } |
| 3153 | 2957 | |
| 3154 | for (self.lld_errors.items) |lld_error| { | |
| 2958 | for (comp.lld_errors.items) |lld_error| { | |
| 3155 | 2959 | const notes_len = @as(u32, @intCast(lld_error.context_lines.len)); |
| 3156 | 2960 | |
| 3157 | 2961 | try bundle.addRootErrorMessage(.{ |
| ... | ... | @@ -3165,19 +2969,19 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 3165 | 2969 | })); |
| 3166 | 2970 | } |
| 3167 | 2971 | } |
| 3168 | for (self.misc_failures.values()) |*value| { | |
| 2972 | for (comp.misc_failures.values()) |*value| { | |
| 3169 | 2973 | try bundle.addRootErrorMessage(.{ |
| 3170 | 2974 | .msg = try bundle.addString(value.msg), |
| 3171 | 2975 | .notes_len = if (value.children) |b| b.errorMessageCount() else 0, |
| 3172 | 2976 | }); |
| 3173 | 2977 | if (value.children) |b| try bundle.addBundleAsNotes(b); |
| 3174 | 2978 | } |
| 3175 | if (self.alloc_failure_occurred) { | |
| 2979 | if (comp.alloc_failure_occurred) { | |
| 3176 | 2980 | try bundle.addRootErrorMessage(.{ |
| 3177 | 2981 | .msg = try bundle.addString("memory allocation failure"), |
| 3178 | 2982 | }); |
| 3179 | 2983 | } |
| 3180 | if (self.bin_file.options.module) |module| { | |
| 2984 | if (comp.module) |module| { | |
| 3181 | 2985 | for (module.failed_files.keys(), module.failed_files.values()) |file, error_msg| { |
| 3182 | 2986 | if (error_msg) |msg| { |
| 3183 | 2987 | try addModuleErrorMsg(module, &bundle, msg.*); |
| ... | ... | @@ -3249,14 +3053,14 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 3249 | 3053 | } |
| 3250 | 3054 | |
| 3251 | 3055 | 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) { | |
| 3253 | 3057 | try bundle.addRootErrorMessage(.{ |
| 3254 | 3058 | .msg = try bundle.addString("no entry point found"), |
| 3255 | 3059 | }); |
| 3256 | 3060 | } |
| 3257 | 3061 | } |
| 3258 | 3062 | |
| 3259 | if (self.link_error_flags.missing_libc) { | |
| 3063 | if (comp.link_error_flags.missing_libc) { | |
| 3260 | 3064 | try bundle.addRootErrorMessage(.{ |
| 3261 | 3065 | .msg = try bundle.addString("libc not available"), |
| 3262 | 3066 | .notes_len = 2, |
| ... | ... | @@ -3270,7 +3074,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 3270 | 3074 | })); |
| 3271 | 3075 | } |
| 3272 | 3076 | |
| 3273 | for (self.bin_file.miscErrors()) |link_err| { | |
| 3077 | for (comp.link_errors.items) |link_err| { | |
| 3274 | 3078 | try bundle.addRootErrorMessage(.{ |
| 3275 | 3079 | .msg = try bundle.addString(link_err.msg), |
| 3276 | 3080 | .notes_len = @intCast(link_err.notes.len), |
| ... | ... | @@ -3283,7 +3087,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 3283 | 3087 | } |
| 3284 | 3088 | } |
| 3285 | 3089 | |
| 3286 | if (self.bin_file.options.module) |module| { | |
| 3090 | if (comp.module) |module| { | |
| 3287 | 3091 | if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) { |
| 3288 | 3092 | const keys = module.compile_log_decls.keys(); |
| 3289 | 3093 | const values = module.compile_log_decls.values(); |
| ... | ... | @@ -3309,9 +3113,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 3309 | 3113 | } |
| 3310 | 3114 | } |
| 3311 | 3115 | |
| 3312 | assert(self.totalErrorCount() == bundle.root_list.items.len); | |
| 3116 | assert(comp.totalErrorCount() == bundle.root_list.items.len); | |
| 3313 | 3117 | |
| 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 ""; | |
| 3315 | 3119 | return bundle.toOwnedBundle(compile_log_text); |
| 3316 | 3120 | } |
| 3317 | 3121 | |
| ... | ... | @@ -3344,7 +3148,7 @@ pub const ErrorNoteHashContext = struct { |
| 3344 | 3148 | const eb = ctx.eb.tmpBundle(); |
| 3345 | 3149 | const msg_a = eb.nullTerminatedString(a.msg); |
| 3346 | 3150 | 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; | |
| 3348 | 3152 | |
| 3349 | 3153 | if (a.src_loc == .none and b.src_loc == .none) return true; |
| 3350 | 3154 | if (a.src_loc == .none or b.src_loc == .none) return false; |
| ... | ... | @@ -3354,7 +3158,7 @@ pub const ErrorNoteHashContext = struct { |
| 3354 | 3158 | const src_path_a = eb.nullTerminatedString(src_a.src_path); |
| 3355 | 3159 | const src_path_b = eb.nullTerminatedString(src_b.src_path); |
| 3356 | 3160 | |
| 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 | |
| 3358 | 3162 | src_a.line == src_b.line and |
| 3359 | 3163 | src_a.column == src_b.column and |
| 3360 | 3164 | src_a.span_main == src_b.span_main; |
| ... | ... | @@ -3595,13 +3399,25 @@ pub fn performAllTheWork( |
| 3595 | 3399 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files |
| 3596 | 3400 | // 2. optimization; in the hot path it only incurs a stat() syscall, which happens |
| 3597 | 3401 | // 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; | |
| 3601 | 3417 | |
| 3602 | 3418 | comp.astgen_wait_group.start(); |
| 3603 | 3419 | try comp.thread_pool.spawn(workerUpdateBuiltinZigFile, .{ |
| 3604 | comp, mod, &comp.astgen_wait_group, | |
| 3420 | comp, mod, file, &comp.astgen_wait_group, | |
| 3605 | 3421 | }); |
| 3606 | 3422 | } |
| 3607 | 3423 | } |
| ... | ... | @@ -3637,15 +3453,15 @@ pub fn performAllTheWork( |
| 3637 | 3453 | } |
| 3638 | 3454 | } |
| 3639 | 3455 | |
| 3640 | if (comp.bin_file.options.module) |mod| { | |
| 3456 | if (comp.module) |mod| { | |
| 3641 | 3457 | try reportMultiModuleErrors(mod); |
| 3642 | 3458 | } |
| 3643 | 3459 | |
| 3644 | if (comp.bin_file.options.module) |mod| { | |
| 3460 | if (comp.module) |mod| { | |
| 3645 | 3461 | mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); |
| 3646 | 3462 | mod.sema_prog_node.activate(); |
| 3647 | 3463 | } |
| 3648 | defer if (comp.bin_file.options.module) |mod| { | |
| 3464 | defer if (comp.module) |mod| { | |
| 3649 | 3465 | mod.sema_prog_node.end(); |
| 3650 | 3466 | mod.sema_prog_node = undefined; |
| 3651 | 3467 | }; |
| ... | ... | @@ -3679,7 +3495,7 @@ pub fn performAllTheWork( |
| 3679 | 3495 | fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !void { |
| 3680 | 3496 | switch (job) { |
| 3681 | 3497 | .codegen_decl => |decl_index| { |
| 3682 | const module = comp.bin_file.options.module.?; | |
| 3498 | const module = comp.module.?; | |
| 3683 | 3499 | const decl = module.declPtr(decl_index); |
| 3684 | 3500 | |
| 3685 | 3501 | switch (decl.analysis) { |
| ... | ... | @@ -3717,14 +3533,14 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3717 | 3533 | const named_frame = tracy.namedFrame("codegen_func"); |
| 3718 | 3534 | defer named_frame.end(); |
| 3719 | 3535 | |
| 3720 | const module = comp.bin_file.options.module.?; | |
| 3536 | const module = comp.module.?; | |
| 3721 | 3537 | module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { |
| 3722 | 3538 | error.OutOfMemory => return error.OutOfMemory, |
| 3723 | 3539 | error.AnalysisFail => return, |
| 3724 | 3540 | }; |
| 3725 | 3541 | }, |
| 3726 | 3542 | .emit_h_decl => |decl_index| { |
| 3727 | const module = comp.bin_file.options.module.?; | |
| 3543 | const module = comp.module.?; | |
| 3728 | 3544 | const decl = module.declPtr(decl_index); |
| 3729 | 3545 | |
| 3730 | 3546 | switch (decl.analysis) { |
| ... | ... | @@ -3783,13 +3599,13 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3783 | 3599 | } |
| 3784 | 3600 | }, |
| 3785 | 3601 | .analyze_decl => |decl_index| { |
| 3786 | const module = comp.bin_file.options.module.?; | |
| 3602 | const module = comp.module.?; | |
| 3787 | 3603 | module.ensureDeclAnalyzed(decl_index) catch |err| switch (err) { |
| 3788 | 3604 | error.OutOfMemory => return error.OutOfMemory, |
| 3789 | 3605 | error.AnalysisFail => return, |
| 3790 | 3606 | }; |
| 3791 | 3607 | 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) { | |
| 3793 | 3609 | // Tests are always emitted in test binaries. The decl_refs are created by |
| 3794 | 3610 | // Module.populateTestFunctions, but this will not queue body analysis, so do |
| 3795 | 3611 | // that now. |
| ... | ... | @@ -3801,9 +3617,10 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3801 | 3617 | defer named_frame.end(); |
| 3802 | 3618 | |
| 3803 | 3619 | const gpa = comp.gpa; |
| 3804 | const module = comp.bin_file.options.module.?; | |
| 3620 | const module = comp.module.?; | |
| 3805 | 3621 | 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| { | |
| 3807 | 3624 | try module.failed_decls.ensureUnusedCapacity(gpa, 1); |
| 3808 | 3625 | module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create( |
| 3809 | 3626 | gpa, |
| ... | ... | @@ -3818,7 +3635,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3818 | 3635 | const named_frame = tracy.namedFrame("analyze_mod"); |
| 3819 | 3636 | defer named_frame.end(); |
| 3820 | 3637 | |
| 3821 | const module = comp.bin_file.options.module.?; | |
| 3638 | const module = comp.module.?; | |
| 3822 | 3639 | module.semaPkg(pkg) catch |err| switch (err) { |
| 3823 | 3640 | error.OutOfMemory => return error.OutOfMemory, |
| 3824 | 3641 | error.AnalysisFail => return, |
| ... | ... | @@ -3875,10 +3692,13 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v |
| 3875 | 3692 | }; |
| 3876 | 3693 | }, |
| 3877 | 3694 | .windows_import_lib => |index| { |
| 3695 | if (build_options.only_c) | |
| 3696 | @panic("building import libs not included in core functionality"); | |
| 3697 | ||
| 3878 | 3698 | const named_frame = tracy.namedFrame("windows_import_lib"); |
| 3879 | 3699 | defer named_frame.end(); |
| 3880 | 3700 | |
| 3881 | const link_lib = comp.bin_file.options.system_libs.keys()[index]; | |
| 3701 | const link_lib = comp.system_libs.keys()[index]; | |
| 3882 | 3702 | mingw.buildImportLib(comp, link_lib) catch |err| { |
| 3883 | 3703 | // TODO Surface more error details. |
| 3884 | 3704 | comp.lockAndSetMiscFailure( |
| ... | ... | @@ -3997,7 +3817,7 @@ fn workerAstGenFile( |
| 3997 | 3817 | child_prog_node.activate(); |
| 3998 | 3818 | defer child_prog_node.end(); |
| 3999 | 3819 | |
| 4000 | const mod = comp.bin_file.options.module.?; | |
| 3820 | const mod = comp.module.?; | |
| 4001 | 3821 | mod.astGenFile(file) catch |err| switch (err) { |
| 4002 | 3822 | error.AnalysisFail => return, |
| 4003 | 3823 | else => { |
| ... | ... | @@ -4065,19 +3885,17 @@ fn workerAstGenFile( |
| 4065 | 3885 | |
| 4066 | 3886 | fn workerUpdateBuiltinZigFile( |
| 4067 | 3887 | comp: *Compilation, |
| 4068 | mod: *Module, | |
| 3888 | mod: *Package.Module, | |
| 3889 | file: *Module.File, | |
| 4069 | 3890 | wg: *WaitGroup, |
| 4070 | 3891 | ) void { |
| 4071 | 3892 | 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| { | |
| 4076 | 3894 | comp.mutex.lock(); |
| 4077 | 3895 | defer comp.mutex.unlock(); |
| 4078 | 3896 | |
| 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), | |
| 4081 | 3899 | }); |
| 4082 | 3900 | }; |
| 4083 | 3901 | } |
| ... | ... | @@ -4100,7 +3918,7 @@ fn workerCheckEmbedFile( |
| 4100 | 3918 | } |
| 4101 | 3919 | |
| 4102 | 3920 | fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !void { |
| 4103 | const mod = comp.bin_file.options.module.?; | |
| 3921 | const mod = comp.module.?; | |
| 4104 | 3922 | const ip = &mod.intern_pool; |
| 4105 | 3923 | const sub_file_path = ip.stringToSlice(embed_file.sub_file_path); |
| 4106 | 3924 | var file = try embed_file.owner.root.openFile(sub_file_path, .{}); |
| ... | ... | @@ -4118,21 +3936,24 @@ fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !voi |
| 4118 | 3936 | @panic("TODO: handle embed file incremental update"); |
| 4119 | 3937 | } |
| 4120 | 3938 | |
| 4121 | pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest { | |
| 3939 | pub fn obtainCObjectCacheManifest( | |
| 3940 | comp: *const Compilation, | |
| 3941 | owner_mod: *Package.Module, | |
| 3942 | ) Cache.Manifest { | |
| 4122 | 3943 | var man = comp.cache_parent.obtain(); |
| 4123 | 3944 | |
| 4124 | 3945 | // Only things that need to be added on top of the base hash, and only things |
| 4125 | 3946 | // that apply both to @cImport and compiling C objects. No linking stuff here! |
| 4126 | 3947 | // 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); | |
| 4130 | 3951 | |
| 4131 | 3952 | // When libc_installation is null it means that Zig generated this dir list |
| 4132 | 3953 | // based on the zig library directory alone. The zig lib directory file |
| 4133 | 3954 | // path is purposefully either in the cache or not in the cache. The |
| 4134 | 3955 | // decision should not be overridden here. |
| 4135 | if (comp.bin_file.options.libc_installation != null) { | |
| 3956 | if (comp.libc_installation != null) { | |
| 4136 | 3957 | man.hash.addListOfBytes(comp.libc_include_dir_list); |
| 4137 | 3958 | } |
| 4138 | 3959 | |
| ... | ... | @@ -4152,7 +3973,7 @@ pub const CImportResult = struct { |
| 4152 | 3973 | cache_hit: bool, |
| 4153 | 3974 | errors: std.zig.ErrorBundle, |
| 4154 | 3975 | |
| 4155 | pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void { | |
| 3976 | pub fn deinit(result: *CImportResult, gpa: mem.Allocator) void { | |
| 4156 | 3977 | result.errors.deinit(gpa); |
| 4157 | 3978 | } |
| 4158 | 3979 | }; |
| ... | ... | @@ -4160,19 +3981,19 @@ pub const CImportResult = struct { |
| 4160 | 3981 | /// Caller owns returned memory. |
| 4161 | 3982 | /// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked |
| 4162 | 3983 | /// a bit when we want to start using it from self-hosted. |
| 4163 | pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { | |
| 3984 | pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module) !CImportResult { | |
| 4164 | 3985 | if (build_options.only_core_functionality) @panic("@cImport is not available in a zig2.c build"); |
| 4165 | 3986 | const tracy_trace = trace(@src()); |
| 4166 | 3987 | defer tracy_trace.end(); |
| 4167 | 3988 | |
| 4168 | 3989 | const cimport_zig_basename = "cimport.zig"; |
| 4169 | 3990 | |
| 4170 | var man = comp.obtainCObjectCacheManifest(); | |
| 3991 | var man = comp.obtainCObjectCacheManifest(owner_mod); | |
| 4171 | 3992 | defer man.deinit(); |
| 4172 | 3993 | |
| 4173 | 3994 | man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects |
| 4174 | 3995 | man.hash.addBytes(c_src); |
| 4175 | man.hash.add(comp.c_frontend); | |
| 3996 | man.hash.add(comp.config.c_frontend); | |
| 4176 | 3997 | |
| 4177 | 3998 | // If the previous invocation resulted in clang errors, we will see a hit |
| 4178 | 3999 | // 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 { |
| 4209 | 4030 | var argv = std.ArrayList([]const u8).init(comp.gpa); |
| 4210 | 4031 | defer argv.deinit(); |
| 4211 | 4032 | |
| 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); | |
| 4214 | 4035 | |
| 4215 | 4036 | try argv.append(out_h_path); |
| 4216 | 4037 | |
| 4217 | 4038 | if (comp.verbose_cc) { |
| 4218 | 4039 | dump_argv(argv.items); |
| 4219 | 4040 | } |
| 4220 | var tree = switch (comp.c_frontend) { | |
| 4041 | var tree = switch (comp.config.c_frontend) { | |
| 4221 | 4042 | .aro => tree: { |
| 4222 | 4043 | const translate_c = @import("aro_translate_c.zig"); |
| 4223 | 4044 | _ = translate_c; |
| ... | ... | @@ -4265,10 +4086,13 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { |
| 4265 | 4086 | |
| 4266 | 4087 | const dep_basename = std.fs.path.basename(out_dep_path); |
| 4267 | 4088 | 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 => {}, | |
| 4272 | 4096 | } |
| 4273 | 4097 | |
| 4274 | 4098 | const digest = man.final(); |
| ... | ... | @@ -4297,7 +4121,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { |
| 4297 | 4121 | }; |
| 4298 | 4122 | } |
| 4299 | 4123 | |
| 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, &.{ | |
| 4301 | 4125 | "o", &digest, cimport_zig_basename, |
| 4302 | 4126 | }); |
| 4303 | 4127 | if (comp.verbose_cimport) { |
| ... | ... | @@ -4423,7 +4247,7 @@ fn reportRetryableAstGenError( |
| 4423 | 4247 | file: *Module.File, |
| 4424 | 4248 | err: anyerror, |
| 4425 | 4249 | ) error{OutOfMemory}!void { |
| 4426 | const mod = comp.bin_file.options.module.?; | |
| 4250 | const mod = comp.module.?; | |
| 4427 | 4251 | const gpa = mod.gpa; |
| 4428 | 4252 | |
| 4429 | 4253 | file.status = .retryable_failure; |
| ... | ... | @@ -4462,7 +4286,7 @@ fn reportRetryableEmbedFileError( |
| 4462 | 4286 | embed_file: *Module.EmbedFile, |
| 4463 | 4287 | err: anyerror, |
| 4464 | 4288 | ) error{OutOfMemory}!void { |
| 4465 | const mod = comp.bin_file.options.module.?; | |
| 4289 | const mod = comp.module.?; | |
| 4466 | 4290 | const gpa = mod.gpa; |
| 4467 | 4291 | const src_loc = embed_file.src_loc; |
| 4468 | 4292 | const ip = &mod.intern_pool; |
| ... | ... | @@ -4482,7 +4306,7 @@ fn reportRetryableEmbedFileError( |
| 4482 | 4306 | } |
| 4483 | 4307 | |
| 4484 | 4308 | fn 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) { | |
| 4486 | 4310 | return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{}); |
| 4487 | 4311 | } |
| 4488 | 4312 | if (!build_options.have_llvm) { |
| ... | ... | @@ -4505,7 +4329,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4505 | 4329 | _ = comp.failed_c_objects.swapRemove(c_object); |
| 4506 | 4330 | } |
| 4507 | 4331 | |
| 4508 | var man = comp.obtainCObjectCacheManifest(); | |
| 4332 | var man = comp.obtainCObjectCacheManifest(c_object.src.owner); | |
| 4509 | 4333 | defer man.deinit(); |
| 4510 | 4334 | |
| 4511 | 4335 | man.hash.add(comp.clang_preprocessor_mode); |
| ... | ... | @@ -4529,10 +4353,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4529 | 4353 | // Special case when doing build-obj for just one C file. When there are more than one object |
| 4530 | 4354 | // file and building an object we need to link them together, but with just one it should go |
| 4531 | 4355 | // 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; | |
| 4534 | 4358 | const o_basename_noext = if (direct_o) |
| 4535 | comp.bin_file.options.root_name | |
| 4359 | comp.root_name | |
| 4536 | 4360 | else |
| 4537 | 4361 | c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len]; |
| 4538 | 4362 | |
| ... | ... | @@ -4582,12 +4406,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4582 | 4406 | if (std.process.can_execv and direct_o and |
| 4583 | 4407 | comp.disable_c_depfile and comp.clang_passthrough_mode) |
| 4584 | 4408 | { |
| 4585 | try comp.addCCArgs(arena, &argv, ext, null); | |
| 4409 | try comp.addCCArgs(arena, &argv, ext, null, c_object.src.owner); | |
| 4586 | 4410 | try argv.appendSlice(c_object.src.extra_flags); |
| 4587 | 4411 | try argv.appendSlice(c_object.src.cache_exempt_flags); |
| 4588 | 4412 | |
| 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}) | |
| 4591 | 4415 | else |
| 4592 | 4416 | "/dev/null"; |
| 4593 | 4417 | |
| ... | ... | @@ -4625,7 +4449,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4625 | 4449 | null |
| 4626 | 4450 | else |
| 4627 | 4451 | 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); | |
| 4629 | 4453 | try argv.appendSlice(c_object.src.extra_flags); |
| 4630 | 4454 | try argv.appendSlice(c_object.src.cache_exempt_flags); |
| 4631 | 4455 | |
| ... | ... | @@ -4720,10 +4544,15 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4720 | 4544 | const dep_basename = std.fs.path.basename(dep_file_path); |
| 4721 | 4545 | // Add the files depended on to the cache system. |
| 4722 | 4546 | 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 => {}, | |
| 4727 | 4556 | } |
| 4728 | 4557 | // Just to save disk space, we delete the file because it is never needed again. |
| 4729 | 4558 | zig_cache_tmp_dir.deleteFile(dep_basename) catch |err| { |
| ... | ... | @@ -4973,7 +4802,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 4973 | 4802 | // mode. While these defines are not normally present when calling rc.exe directly, |
| 4974 | 4803 | // them being defined matches the behavior of how MSVC calls rc.exe which is the more |
| 4975 | 4804 | // 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); | |
| 4977 | 4806 | |
| 4978 | 4807 | if (comp.verbose_cc) { |
| 4979 | 4808 | dump_argv(argv.items); |
| ... | ... | @@ -5019,10 +4848,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5019 | 4848 | const dep_basename = std.fs.path.basename(out_dep_path); |
| 5020 | 4849 | // Add the files depended on to the cache system. |
| 5021 | 4850 | 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 => {}, | |
| 5026 | 4858 | } |
| 5027 | 4859 | // Just to save disk space, we delete the file because it is never needed again. |
| 5028 | 4860 | zig_cache_tmp_dir.deleteFile(dep_basename) catch |err| { |
| ... | ... | @@ -5094,10 +4926,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5094 | 4926 | |
| 5095 | 4927 | for (dependencies_list.items) |dep_file_path| { |
| 5096 | 4928 | 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 => {}, | |
| 5101 | 4936 | } |
| 5102 | 4937 | } |
| 5103 | 4938 | |
| ... | ... | @@ -5151,11 +4986,12 @@ pub fn addTranslateCCArgs( |
| 5151 | 4986 | argv: *std.ArrayList([]const u8), |
| 5152 | 4987 | ext: FileExt, |
| 5153 | 4988 | out_dep_path: ?[]const u8, |
| 4989 | owner_mod: *Package.Module, | |
| 5154 | 4990 | ) !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); | |
| 5157 | 4993 | // 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" }); | |
| 5159 | 4995 | } |
| 5160 | 4996 | |
| 5161 | 4997 | /// Add common C compiler args between translate-c and C object compilation. |
| ... | ... | @@ -5165,8 +5001,9 @@ pub fn addCCArgs( |
| 5165 | 5001 | argv: *std.ArrayList([]const u8), |
| 5166 | 5002 | ext: FileExt, |
| 5167 | 5003 | out_dep_path: ?[]const u8, |
| 5004 | mod: *Package.Module, | |
| 5168 | 5005 | ) !void { |
| 5169 | const target = comp.getTarget(); | |
| 5006 | const target = mod.resolved_target.result; | |
| 5170 | 5007 | |
| 5171 | 5008 | // As of Clang 16.x, it will by default read extra flags from /etc/clang. |
| 5172 | 5009 | // I'm sure the person who implemented this means well, but they have a lot |
| ... | ... | @@ -5187,19 +5024,19 @@ pub fn addCCArgs( |
| 5187 | 5024 | try argv.append("-fno-caret-diagnostics"); |
| 5188 | 5025 | } |
| 5189 | 5026 | |
| 5190 | if (comp.bin_file.options.function_sections) { | |
| 5027 | if (comp.function_sections) { | |
| 5191 | 5028 | try argv.append("-ffunction-sections"); |
| 5192 | 5029 | } |
| 5193 | 5030 | |
| 5194 | if (comp.bin_file.options.data_sections) { | |
| 5031 | if (comp.data_sections) { | |
| 5195 | 5032 | try argv.append("-fdata-sections"); |
| 5196 | 5033 | } |
| 5197 | 5034 | |
| 5198 | if (comp.bin_file.options.no_builtin) { | |
| 5035 | if (comp.no_builtin) { | |
| 5199 | 5036 | try argv.append("-fno-builtin"); |
| 5200 | 5037 | } |
| 5201 | 5038 | |
| 5202 | if (comp.bin_file.options.link_libcpp) { | |
| 5039 | if (comp.config.link_libcpp) { | |
| 5203 | 5040 | const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 5204 | 5041 | comp.zig_lib_directory.path.?, "libcxx", "include", |
| 5205 | 5042 | }); |
| ... | ... | @@ -5220,7 +5057,7 @@ pub fn addCCArgs( |
| 5220 | 5057 | try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 5221 | 5058 | try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); |
| 5222 | 5059 | |
| 5223 | if (comp.bin_file.options.single_threaded) { | |
| 5060 | if (!comp.config.any_non_single_threaded) { | |
| 5224 | 5061 | try argv.append("-D_LIBCPP_HAS_NO_THREADS"); |
| 5225 | 5062 | } |
| 5226 | 5063 | |
| ... | ... | @@ -5235,7 +5072,7 @@ pub fn addCCArgs( |
| 5235 | 5072 | })); |
| 5236 | 5073 | } |
| 5237 | 5074 | |
| 5238 | if (comp.bin_file.options.link_libunwind) { | |
| 5075 | if (comp.config.link_libunwind) { | |
| 5239 | 5076 | const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{ |
| 5240 | 5077 | comp.zig_lib_directory.path.?, "libunwind", "include", |
| 5241 | 5078 | }); |
| ... | ... | @@ -5244,7 +5081,7 @@ pub fn addCCArgs( |
| 5244 | 5081 | try argv.append(libunwind_include_path); |
| 5245 | 5082 | } |
| 5246 | 5083 | |
| 5247 | if (comp.bin_file.options.link_libc and target.isGnuLibC()) { | |
| 5084 | if (comp.config.link_libc and target.isGnuLibC()) { | |
| 5248 | 5085 | const target_version = target.os.version_range.linux.glibc; |
| 5249 | 5086 | const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ |
| 5250 | 5087 | target_version.minor, |
| ... | ... | @@ -5269,7 +5106,7 @@ pub fn addCCArgs( |
| 5269 | 5106 | "-nostdinc", |
| 5270 | 5107 | "-fno-spell-checking", |
| 5271 | 5108 | }); |
| 5272 | if (comp.bin_file.options.lto) { | |
| 5109 | if (comp.config.lto) { | |
| 5273 | 5110 | try argv.append("-flto"); |
| 5274 | 5111 | } |
| 5275 | 5112 | |
| ... | ... | @@ -5281,7 +5118,7 @@ pub fn addCCArgs( |
| 5281 | 5118 | try argv.appendSlice(&.{ "-iframework", framework_dir }); |
| 5282 | 5119 | } |
| 5283 | 5120 | |
| 5284 | for (comp.bin_file.options.framework_dirs) |framework_dir| { | |
| 5121 | for (comp.framework_dirs) |framework_dir| { | |
| 5285 | 5122 | try argv.appendSlice(&.{ "-F", framework_dir }); |
| 5286 | 5123 | } |
| 5287 | 5124 | |
| ... | ... | @@ -5324,9 +5161,8 @@ pub fn addCCArgs( |
| 5324 | 5161 | argv.appendAssumeCapacity(arg); |
| 5325 | 5162 | } |
| 5326 | 5163 | } |
| 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)})); | |
| 5330 | 5166 | } |
| 5331 | 5167 | |
| 5332 | 5168 | switch (target.os.tag) { |
| ... | ... | @@ -5375,7 +5211,7 @@ pub fn addCCArgs( |
| 5375 | 5211 | try argv.append("-mthumb"); |
| 5376 | 5212 | } |
| 5377 | 5213 | |
| 5378 | if (comp.sanitize_c and !comp.bin_file.options.tsan) { | |
| 5214 | if (mod.sanitize_c and !mod.sanitize_thread) { | |
| 5379 | 5215 | try argv.append("-fsanitize=undefined"); |
| 5380 | 5216 | try argv.append("-fsanitize-trap=undefined"); |
| 5381 | 5217 | // It is very common, and well-defined, for a pointer on one side of a C ABI |
| ... | ... | @@ -5386,27 +5222,27 @@ pub fn addCCArgs( |
| 5386 | 5222 | // Without this flag, Clang would invoke UBSAN when such an extern |
| 5387 | 5223 | // function was called. |
| 5388 | 5224 | 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) { | |
| 5390 | 5226 | try argv.append("-fsanitize=undefined,thread"); |
| 5391 | 5227 | try argv.append("-fsanitize-trap=undefined"); |
| 5392 | 5228 | 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) { | |
| 5394 | 5230 | try argv.append("-fsanitize=thread"); |
| 5395 | 5231 | } |
| 5396 | 5232 | |
| 5397 | if (comp.bin_file.options.red_zone) { | |
| 5233 | if (mod.red_zone) { | |
| 5398 | 5234 | try argv.append("-mred-zone"); |
| 5399 | 5235 | } else if (target_util.hasRedZone(target)) { |
| 5400 | 5236 | try argv.append("-mno-red-zone"); |
| 5401 | 5237 | } |
| 5402 | 5238 | |
| 5403 | if (comp.bin_file.options.omit_frame_pointer) { | |
| 5239 | if (mod.omit_frame_pointer) { | |
| 5404 | 5240 | try argv.append("-fomit-frame-pointer"); |
| 5405 | 5241 | } else { |
| 5406 | 5242 | try argv.append("-fno-omit-frame-pointer"); |
| 5407 | 5243 | } |
| 5408 | 5244 | |
| 5409 | const ssp_buf_size = comp.bin_file.options.stack_protector; | |
| 5245 | const ssp_buf_size = mod.stack_protector; | |
| 5410 | 5246 | if (ssp_buf_size != 0) { |
| 5411 | 5247 | try argv.appendSlice(&[_][]const u8{ |
| 5412 | 5248 | "-fstack-protector-strong", |
| ... | ... | @@ -5417,7 +5253,7 @@ pub fn addCCArgs( |
| 5417 | 5253 | try argv.append("-fno-stack-protector"); |
| 5418 | 5254 | } |
| 5419 | 5255 | |
| 5420 | switch (comp.bin_file.options.optimize_mode) { | |
| 5256 | switch (mod.optimize_mode) { | |
| 5421 | 5257 | .Debug => { |
| 5422 | 5258 | // windows c runtime requires -D_DEBUG if using debug libraries |
| 5423 | 5259 | try argv.append("-D_DEBUG"); |
| ... | ... | @@ -5447,11 +5283,11 @@ pub fn addCCArgs( |
| 5447 | 5283 | }, |
| 5448 | 5284 | } |
| 5449 | 5285 | |
| 5450 | if (target_util.supports_fpic(target) and comp.bin_file.options.pic) { | |
| 5286 | if (target_util.supports_fpic(target) and mod.pic) { | |
| 5451 | 5287 | try argv.append("-fPIC"); |
| 5452 | 5288 | } |
| 5453 | 5289 | |
| 5454 | if (comp.unwind_tables) { | |
| 5290 | if (mod.unwind_tables) { | |
| 5455 | 5291 | try argv.append("-funwind-tables"); |
| 5456 | 5292 | } else { |
| 5457 | 5293 | try argv.append("-fno-unwind-tables"); |
| ... | ... | @@ -5536,22 +5372,21 @@ pub fn addCCArgs( |
| 5536 | 5372 | }, |
| 5537 | 5373 | } |
| 5538 | 5374 | |
| 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 | }, | |
| 5555 | 5390 | } |
| 5556 | 5391 | |
| 5557 | 5392 | if (target_util.llvmMachineAbi(target)) |mabi| { |
| ... | ... | @@ -5574,7 +5409,16 @@ pub fn addCCArgs( |
| 5574 | 5409 | try argv.append("-ffreestanding"); |
| 5575 | 5410 | } |
| 5576 | 5411 | |
| 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); | |
| 5578 | 5422 | } |
| 5579 | 5423 | |
| 5580 | 5424 | fn failCObj( |
| ... | ... | @@ -5621,68 +5465,6 @@ fn failCObjWithOwnedDiagBundle( |
| 5621 | 5465 | return error.AnalysisFail; |
| 5622 | 5466 | } |
| 5623 | 5467 | |
| 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. | |
| 5633 | fn 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 | ||
| 5686 | 5468 | fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) SemaError { |
| 5687 | 5469 | @setCold(true); |
| 5688 | 5470 | var bundle: ErrorBundle.Wip = undefined; |
| ... | ... | @@ -6064,7 +5846,7 @@ const LibCDirs = struct { |
| 6064 | 5846 | libc_installation: ?*const LibCInstallation, |
| 6065 | 5847 | libc_framework_dir_list: []const []const u8, |
| 6066 | 5848 | sysroot: ?[]const u8, |
| 6067 | darwin_sdk_layout: ?link.DarwinSdkLayout, | |
| 5849 | darwin_sdk_layout: ?link.File.MachO.SdkLayout, | |
| 6068 | 5850 | }; |
| 6069 | 5851 | |
| 6070 | 5852 | fn 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 |
| 6285 | 6067 | { |
| 6286 | 6068 | return comp.crt_files.get(basename).?.full_object_path; |
| 6287 | 6069 | } |
| 6288 | const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable; | |
| 6070 | const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable; | |
| 6289 | 6071 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir; |
| 6290 | 6072 | const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename }); |
| 6291 | 6073 | return full_path; |
| 6292 | 6074 | } |
| 6293 | 6075 | |
| 6294 | 6076 | fn 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) { | |
| 6296 | 6078 | .Obj => false, |
| 6297 | .Lib => comp.bin_file.options.link_mode == .Dynamic, | |
| 6079 | .Lib => comp.config.link_mode == .Dynamic, | |
| 6298 | 6080 | .Exe => true, |
| 6299 | 6081 | }; |
| 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; | |
| 6303 | 6085 | } |
| 6304 | 6086 | |
| 6305 | 6087 | fn wantBuildGLibCFromSource(comp: Compilation) bool { |
| ... | ... | @@ -6321,13 +6103,13 @@ fn wantBuildMinGWFromSource(comp: Compilation) bool { |
| 6321 | 6103 | } |
| 6322 | 6104 | |
| 6323 | 6105 | fn 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) { | |
| 6325 | 6107 | .Obj => false, |
| 6326 | .Lib => comp.bin_file.options.link_mode == .Dynamic, | |
| 6108 | .Lib => comp.config.link_mode == .Dynamic, | |
| 6327 | 6109 | .Exe => true, |
| 6328 | 6110 | }; |
| 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; | |
| 6331 | 6113 | } |
| 6332 | 6114 | |
| 6333 | 6115 | fn setAllocFailure(comp: *Compilation) void { |
| ... | ... | @@ -6377,7 +6159,7 @@ fn parseLldStderr(comp: *Compilation, comptime prefix: []const u8, stderr: []con |
| 6377 | 6159 | err.context_lines = try context_lines.toOwnedSlice(); |
| 6378 | 6160 | } |
| 6379 | 6161 | |
| 6380 | var split = std.mem.splitSequence(u8, line, "error: "); | |
| 6162 | var split = mem.splitSequence(u8, line, "error: "); | |
| 6381 | 6163 | _ = split.first(); |
| 6382 | 6164 | |
| 6383 | 6165 | 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 { |
| 6430 | 6212 | .spirv32, .spirv64 => return false, |
| 6431 | 6213 | else => {}, |
| 6432 | 6214 | } |
| 6433 | return switch (zigBackend(target, use_llvm)) { | |
| 6215 | return switch (target_util.zigBackend(target, use_llvm)) { | |
| 6434 | 6216 | .stage2_llvm => true, |
| 6435 | 6217 | .stage2_x86_64 => if (target.ofmt == .elf) true else build_options.have_llvm, |
| 6436 | 6218 | else => build_options.have_llvm, |
| ... | ... | @@ -6448,7 +6230,7 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool { |
| 6448 | 6230 | .spirv32, .spirv64 => return false, |
| 6449 | 6231 | else => {}, |
| 6450 | 6232 | } |
| 6451 | return switch (zigBackend(target, use_llvm)) { | |
| 6233 | return switch (target_util.zigBackend(target, use_llvm)) { | |
| 6452 | 6234 | .stage2_llvm => true, |
| 6453 | 6235 | .stage2_x86_64 => if (target.ofmt == .elf) true else build_options.have_llvm, |
| 6454 | 6236 | else => build_options.have_llvm, |
| ... | ... | @@ -6456,222 +6238,8 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool { |
| 6456 | 6238 | } |
| 6457 | 6239 | |
| 6458 | 6240 | pub 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 | ||
| 6463 | fn 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 | ||
| 6479 | pub 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); | |
| 6675 | 6243 | } |
| 6676 | 6244 | |
| 6677 | 6245 | pub fn updateSubCompilation( |
| ... | ... | @@ -6718,60 +6286,83 @@ fn buildOutputFromZig( |
| 6718 | 6286 | const tracy_trace = trace(@src()); |
| 6719 | 6287 | defer tracy_trace.end(); |
| 6720 | 6288 | |
| 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 | ||
| 6721 | 6294 | assert(output_mode != .Exe); |
| 6722 | 6295 | |
| 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 | }, | |
| 6726 | 6319 | .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 | }); | |
| 6728 | 6337 | const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; |
| 6729 | 6338 | const target = comp.getTarget(); |
| 6730 | const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{ | |
| 6339 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | |
| 6731 | 6340 | .root_name = root_name, |
| 6732 | 6341 | .target = target, |
| 6733 | 6342 | .output_mode = output_mode, |
| 6734 | 6343 | }); |
| 6735 | defer comp.gpa.free(bin_basename); | |
| 6736 | 6344 | |
| 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, .{ | |
| 6742 | 6346 | .global_cache_directory = comp.global_cache_directory, |
| 6743 | 6347 | .local_cache_directory = comp.global_cache_directory, |
| 6744 | 6348 | .zig_lib_directory = comp.zig_lib_directory, |
| 6349 | .self_exe_path = comp.self_exe_path, | |
| 6350 | .config = config, | |
| 6351 | .root_mod = root_mod, | |
| 6745 | 6352 | .cache_mode = .whole, |
| 6746 | .target = target, | |
| 6747 | 6353 | .root_name = root_name, |
| 6748 | .main_mod = &main_mod, | |
| 6749 | .output_mode = output_mode, | |
| 6750 | 6354 | .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 | }, | |
| 6755 | 6360 | .function_sections = true, |
| 6756 | 6361 | .data_sections = true, |
| 6757 | 6362 | .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, | |
| 6768 | 6363 | .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, | |
| 6773 | 6364 | .verbose_cc = comp.verbose_cc, |
| 6774 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 6365 | .verbose_link = comp.verbose_link, | |
| 6775 | 6366 | .verbose_air = comp.verbose_air, |
| 6776 | 6367 | .verbose_intern_pool = comp.verbose_intern_pool, |
| 6777 | 6368 | .verbose_generic_instances = comp.verbose_intern_pool, |
| ... | ... | @@ -6781,20 +6372,13 @@ fn buildOutputFromZig( |
| 6781 | 6372 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 6782 | 6373 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 6783 | 6374 | .skip_linker_dependencies = true, |
| 6784 | .link_libc = comp.bin_file.options.link_libc, | |
| 6785 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, | |
| 6786 | 6375 | }); |
| 6787 | 6376 | defer sub_compilation.destroy(); |
| 6788 | 6377 | |
| 6789 | 6378 | try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node); |
| 6790 | 6379 | |
| 6791 | 6380 | 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(); | |
| 6798 | 6382 | } |
| 6799 | 6383 | |
| 6800 | 6384 | pub fn build_crt_file( |
| ... | ... | @@ -6803,56 +6387,89 @@ pub fn build_crt_file( |
| 6803 | 6387 | output_mode: std.builtin.OutputMode, |
| 6804 | 6388 | misc_task_tag: MiscTask, |
| 6805 | 6389 | 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, | |
| 6807 | 6393 | ) !void { |
| 6808 | 6394 | const tracy_trace = trace(@src()); |
| 6809 | 6395 | defer tracy_trace.end(); |
| 6810 | 6396 | |
| 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, .{ | |
| 6813 | 6403 | .root_name = root_name, |
| 6814 | .target = target, | |
| 6404 | .target = comp.root_mod.resolved_target.result, | |
| 6815 | 6405 | .output_mode = output_mode, |
| 6816 | 6406 | }); |
| 6817 | errdefer comp.gpa.free(basename); | |
| 6818 | 6407 | |
| 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, .{ | |
| 6820 | 6455 | .local_cache_directory = comp.global_cache_directory, |
| 6821 | 6456 | .global_cache_directory = comp.global_cache_directory, |
| 6822 | 6457 | .zig_lib_directory = comp.zig_lib_directory, |
| 6458 | .self_exe_path = comp.self_exe_path, | |
| 6823 | 6459 | .cache_mode = .whole, |
| 6824 | .target = target, | |
| 6460 | .config = config, | |
| 6461 | .root_mod = root_mod, | |
| 6825 | 6462 | .root_name = root_name, |
| 6826 | .main_mod = null, | |
| 6827 | .output_mode = output_mode, | |
| 6828 | 6463 | .thread_pool = comp.thread_pool, |
| 6829 | .libc_installation = comp.bin_file.options.libc_installation, | |
| 6464 | .libc_installation = comp.libc_installation, | |
| 6830 | 6465 | .emit_bin = .{ |
| 6831 | 6466 | .directory = null, // Put it in the cache directory. |
| 6832 | 6467 | .basename = basename, |
| 6833 | 6468 | }, |
| 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 | }, | |
| 6848 | 6469 | .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, | |
| 6853 | 6470 | .c_source_files = c_source_files, |
| 6854 | 6471 | .verbose_cc = comp.verbose_cc, |
| 6855 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 6472 | .verbose_link = comp.verbose_link, | |
| 6856 | 6473 | .verbose_air = comp.verbose_air, |
| 6857 | 6474 | .verbose_intern_pool = comp.verbose_intern_pool, |
| 6858 | 6475 | .verbose_generic_instances = comp.verbose_generic_instances, |
| ... | ... | @@ -6862,21 +6479,22 @@ pub fn build_crt_file( |
| 6862 | 6479 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 6863 | 6480 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 6864 | 6481 | .skip_linker_dependencies = true, |
| 6865 | .link_libc = comp.bin_file.options.link_libc, | |
| 6866 | .want_structured_cfg = comp.bin_file.options.want_structured_cfg, | |
| 6867 | 6482 | }); |
| 6868 | 6483 | defer sub_compilation.destroy(); |
| 6869 | 6484 | |
| 6870 | 6485 | try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node); |
| 6871 | 6486 | |
| 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 | } | |
| 6873 | 6490 | |
| 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, | |
| 6491 | pub 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.?, | |
| 6877 | 6495 | }), |
| 6878 | .lock = sub_compilation.bin_file.toOwnedLock(), | |
| 6879 | }); | |
| 6496 | .lock = comp.cache_use.whole.moveLock(), | |
| 6497 | }; | |
| 6880 | 6498 | } |
| 6881 | 6499 | |
| 6882 | 6500 | pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| ... | ... | @@ -6884,21 +6502,24 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| 6884 | 6502 | // This can happen when the user uses `build-exe foo.obj -lkernel32` and |
| 6885 | 6503 | // then when we create a sub-Compilation for zig libc, it also tries to |
| 6886 | 6504 | // build kernel32.lib. |
| 6887 | if (comp.bin_file.options.skip_linker_dependencies) return; | |
| 6505 | if (comp.skip_linker_dependencies) return; | |
| 6888 | 6506 | |
| 6889 | 6507 | // This happens when an `extern "foo"` function is referenced. |
| 6890 | 6508 | // If we haven't seen this library yet and we're targeting Windows, we need |
| 6891 | 6509 | // 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) { | |
| 6894 | 6512 | gop.value_ptr.* = .{ |
| 6895 | 6513 | .needed = true, |
| 6896 | 6514 | .weak = false, |
| 6897 | 6515 | .path = null, |
| 6898 | 6516 | }; |
| 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 | } | |
| 6902 | 6523 | } |
| 6903 | 6524 | } |
| 6904 | 6525 | |
| ... | ... | @@ -6906,10 +6527,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void { |
| 6906 | 6527 | /// compiler-rt, libcxx, libc, libunwind, etc. |
| 6907 | 6528 | pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode { |
| 6908 | 6529 | if (comp.debug_compiler_runtime_libs) { |
| 6909 | return comp.bin_file.options.optimize_mode; | |
| 6530 | return comp.root_mod.optimize_mode; | |
| 6910 | 6531 | } |
| 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), | |
| 6913 | 6535 | .ReleaseFast => return .ReleaseFast, |
| 6914 | 6536 | .ReleaseSmall => return .ReleaseSmall, |
| 6915 | 6537 | } |
| ... | ... | @@ -6918,5 +6540,5 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode { |
| 6918 | 6540 | /// This decides whether to strip debug info for all zig-provided libraries, including |
| 6919 | 6541 | /// compiler-rt, libcxx, libc, libunwind, etc. |
| 6920 | 6542 | pub fn compilerRtStrip(comp: Compilation) bool { |
| 6921 | return comp.bin_file.options.strip; | |
| 6543 | return comp.root_mod.strip; | |
| 6922 | 6544 | } |
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 | ||
| 6 | have_zcu: bool, | |
| 7 | output_mode: std.builtin.OutputMode, | |
| 8 | link_mode: std.builtin.LinkMode, | |
| 9 | link_libc: bool, | |
| 10 | link_libcpp: bool, | |
| 11 | link_libunwind: bool, | |
| 12 | /// True if and only if the c_source_files field will have nonzero length when | |
| 13 | /// calling Compilation.create. | |
| 14 | any_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. | |
| 21 | any_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. | |
| 28 | any_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. | |
| 33 | any_error_tracing: bool, | |
| 34 | any_sanitize_thread: bool, | |
| 35 | pie: 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. | |
| 40 | use_llvm: bool, | |
| 41 | /// Whether or not the LLVM library API will be used by the LLVM backend. | |
| 42 | use_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. | |
| 47 | use_lld: bool, | |
| 48 | c_frontend: CFrontend, | |
| 49 | lto: bool, | |
| 50 | /// WASI-only. Type of WASI execution model ("command" or "reactor"). | |
| 51 | /// Always set to `command` for non-WASI targets. | |
| 52 | wasi_exec_model: std.builtin.WasiExecModel, | |
| 53 | import_memory: bool, | |
| 54 | export_memory: bool, | |
| 55 | shared_memory: bool, | |
| 56 | is_test: bool, | |
| 57 | test_evented_io: bool, | |
| 58 | debug_format: DebugFormat, | |
| 59 | root_strip: bool, | |
| 60 | root_error_tracing: bool, | |
| 61 | dll_export_fns: bool, | |
| 62 | rdynamic: bool, | |
| 63 | ||
| 64 | pub const CFrontend = enum { clang, aro }; | |
| 65 | ||
| 66 | pub const DebugFormat = union(enum) { | |
| 67 | strip, | |
| 68 | dwarf: std.dwarf.Format, | |
| 69 | code_view, | |
| 70 | }; | |
| 71 | ||
| 72 | pub 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 | ||
| 113 | pub 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 | ||
| 144 | pub 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 | ||
| 508 | const std = @import("std"); | |
| 509 | const Module = @import("../Package.zig").Module; | |
| 510 | const Config = @This(); | |
| 511 | const target_util = @import("../target.zig"); | |
| 512 | const build_options = @import("build_options"); |
src/Module.zig+258-300| ... | ... | @@ -14,7 +14,9 @@ const BigIntMutable = std.math.big.int.Mutable; |
| 14 | 14 | const Target = std.Target; |
| 15 | 15 | const Ast = std.zig.Ast; |
| 16 | 16 | |
| 17 | const Module = @This(); | |
| 17 | /// Deprecated, use `Zcu`. | |
| 18 | const Module = Zcu; | |
| 19 | const Zcu = @This(); | |
| 18 | 20 | const Compilation = @import("Compilation.zig"); |
| 19 | 21 | const Cache = std.Build.Cache; |
| 20 | 22 | const Value = @import("value.zig").Value; |
| ... | ... | @@ -35,6 +37,7 @@ const clang = @import("clang.zig"); |
| 35 | 37 | const InternPool = @import("InternPool.zig"); |
| 36 | 38 | const Alignment = InternPool.Alignment; |
| 37 | 39 | const BuiltinFn = std.zig.BuiltinFn; |
| 40 | const LlvmObject = @import("codegen/llvm.zig").Object; | |
| 38 | 41 | |
| 39 | 42 | comptime { |
| 40 | 43 | @setEvalBranchQuota(4000); |
| ... | ... | @@ -51,14 +54,17 @@ comptime { |
| 51 | 54 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| 52 | 55 | gpa: Allocator, |
| 53 | 56 | comp: *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. | |
| 60 | llvm_object: ?*LlvmObject, | |
| 54 | 61 | |
| 55 | /// Where build artifacts and incremental compilation metadata serialization go. | |
| 56 | zig_cache_artifact_directory: Compilation.Directory, | |
| 57 | 62 | /// Pointer to externally managed resource. |
| 58 | 63 | root_mod: *Package.Module, |
| 59 | 64 | /// Normally, `main_mod` and `root_mod` are the same. The exception is `zig test`, in which |
| 60 | 65 | /// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests. |
| 61 | 66 | main_mod: *Package.Module, |
| 67 | std_mod: *Package.Module, | |
| 62 | 68 | sema_prog_node: std.Progress.Node = undefined, |
| 63 | 69 | |
| 64 | 70 | /// Used by AstGen worker to load and store ZIR cache. |
| ... | ... | @@ -153,8 +159,6 @@ stage1_flags: packed struct { |
| 153 | 159 | reserved: u2 = 0, |
| 154 | 160 | } = .{}, |
| 155 | 161 | |
| 156 | job_queued_update_builtin_zig: bool = true, | |
| 157 | ||
| 158 | 162 | compile_log_text: ArrayListUnmanaged(u8) = .{}, |
| 159 | 163 | |
| 160 | 164 | emit_h: ?*GlobalEmitH, |
| ... | ... | @@ -622,7 +626,8 @@ pub const Decl = struct { |
| 622 | 626 | // Sanitize the name for nvptx which is more restrictive. |
| 623 | 627 | // TODO This should be handled by the backend, not the frontend. Have a |
| 624 | 628 | // 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()) { | |
| 626 | 631 | for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) { |
| 627 | 632 | '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_', |
| 628 | 633 | else => {}, |
| ... | ... | @@ -949,15 +954,21 @@ pub const File = struct { |
| 949 | 954 | |
| 950 | 955 | pub fn deinit(file: *File, mod: *Module) void { |
| 951 | 956 | const gpa = mod.gpa; |
| 957 | const is_builtin = file.mod.isBuiltin(); | |
| 952 | 958 | 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 | } | |
| 953 | 966 | file.deleted_decls.deinit(gpa); |
| 954 | 967 | file.outdated_decls.deinit(gpa); |
| 955 | 968 | file.references.deinit(gpa); |
| 956 | 969 | if (file.root_decl.unwrap()) |root_decl| { |
| 957 | 970 | mod.destroyDecl(root_decl); |
| 958 | 971 | } |
| 959 | gpa.free(file.sub_file_path); | |
| 960 | file.unload(gpa); | |
| 961 | 972 | if (file.prev_zir) |prev_zir| { |
| 962 | 973 | prev_zir.deinit(gpa); |
| 963 | 974 | gpa.destroy(prev_zir); |
| ... | ... | @@ -1019,8 +1030,9 @@ pub const File = struct { |
| 1019 | 1030 | |
| 1020 | 1031 | pub fn destroy(file: *File, mod: *Module) void { |
| 1021 | 1032 | const gpa = mod.gpa; |
| 1033 | const is_builtin = file.mod.isBuiltin(); | |
| 1022 | 1034 | file.deinit(mod); |
| 1023 | gpa.destroy(file); | |
| 1035 | if (!is_builtin) gpa.destroy(file); | |
| 1024 | 1036 | } |
| 1025 | 1037 | |
| 1026 | 1038 | pub fn renderFullyQualifiedName(file: File, writer: anytype) !void { |
| ... | ... | @@ -2469,108 +2481,111 @@ pub fn init(mod: *Module) !void { |
| 2469 | 2481 | try mod.global_error_set.put(gpa, .empty, {}); |
| 2470 | 2482 | } |
| 2471 | 2483 | |
| 2472 | pub fn deinit(mod: *Module) void { | |
| 2473 | const gpa = mod.gpa; | |
| 2484 | pub fn deinit(zcu: *Zcu) void { | |
| 2485 | const gpa = zcu.gpa; | |
| 2474 | 2486 | |
| 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| { | |
| 2476 | 2493 | gpa.free(key); |
| 2477 | 2494 | } |
| 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); | |
| 2482 | 2499 | } |
| 2483 | mod.import_table.deinit(gpa); | |
| 2500 | zcu.import_table.deinit(gpa); | |
| 2484 | 2501 | |
| 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| { | |
| 2486 | 2503 | gpa.free(path); |
| 2487 | 2504 | gpa.destroy(embed_file); |
| 2488 | 2505 | } |
| 2489 | mod.embed_table.deinit(gpa); | |
| 2506 | zcu.embed_table.deinit(gpa); | |
| 2490 | 2507 | |
| 2491 | mod.compile_log_text.deinit(gpa); | |
| 2508 | zcu.compile_log_text.deinit(gpa); | |
| 2492 | 2509 | |
| 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(); | |
| 2496 | 2512 | |
| 2497 | 2513 | for (failed_decls.values()) |value| { |
| 2498 | 2514 | value.destroy(gpa); |
| 2499 | 2515 | } |
| 2500 | 2516 | failed_decls.deinit(gpa); |
| 2501 | 2517 | |
| 2502 | if (mod.emit_h) |emit_h| { | |
| 2518 | if (zcu.emit_h) |emit_h| { | |
| 2503 | 2519 | for (emit_h.failed_decls.values()) |value| { |
| 2504 | 2520 | value.destroy(gpa); |
| 2505 | 2521 | } |
| 2506 | 2522 | emit_h.failed_decls.deinit(gpa); |
| 2507 | 2523 | emit_h.decl_table.deinit(gpa); |
| 2508 | 2524 | emit_h.allocated_emit_h.deinit(gpa); |
| 2509 | gpa.destroy(emit_h); | |
| 2510 | 2525 | } |
| 2511 | 2526 | |
| 2512 | for (mod.failed_files.values()) |value| { | |
| 2527 | for (zcu.failed_files.values()) |value| { | |
| 2513 | 2528 | if (value) |msg| msg.destroy(gpa); |
| 2514 | 2529 | } |
| 2515 | mod.failed_files.deinit(gpa); | |
| 2530 | zcu.failed_files.deinit(gpa); | |
| 2516 | 2531 | |
| 2517 | for (mod.failed_embed_files.values()) |msg| { | |
| 2532 | for (zcu.failed_embed_files.values()) |msg| { | |
| 2518 | 2533 | msg.destroy(gpa); |
| 2519 | 2534 | } |
| 2520 | mod.failed_embed_files.deinit(gpa); | |
| 2535 | zcu.failed_embed_files.deinit(gpa); | |
| 2521 | 2536 | |
| 2522 | for (mod.failed_exports.values()) |value| { | |
| 2537 | for (zcu.failed_exports.values()) |value| { | |
| 2523 | 2538 | value.destroy(gpa); |
| 2524 | 2539 | } |
| 2525 | mod.failed_exports.deinit(gpa); | |
| 2540 | zcu.failed_exports.deinit(gpa); | |
| 2526 | 2541 | |
| 2527 | for (mod.cimport_errors.values()) |*errs| { | |
| 2542 | for (zcu.cimport_errors.values()) |*errs| { | |
| 2528 | 2543 | errs.deinit(gpa); |
| 2529 | 2544 | } |
| 2530 | mod.cimport_errors.deinit(gpa); | |
| 2545 | zcu.cimport_errors.deinit(gpa); | |
| 2531 | 2546 | |
| 2532 | mod.compile_log_decls.deinit(gpa); | |
| 2547 | zcu.compile_log_decls.deinit(gpa); | |
| 2533 | 2548 | |
| 2534 | for (mod.decl_exports.values()) |*export_list| { | |
| 2549 | for (zcu.decl_exports.values()) |*export_list| { | |
| 2535 | 2550 | export_list.deinit(gpa); |
| 2536 | 2551 | } |
| 2537 | mod.decl_exports.deinit(gpa); | |
| 2552 | zcu.decl_exports.deinit(gpa); | |
| 2538 | 2553 | |
| 2539 | for (mod.value_exports.values()) |*export_list| { | |
| 2554 | for (zcu.value_exports.values()) |*export_list| { | |
| 2540 | 2555 | export_list.deinit(gpa); |
| 2541 | 2556 | } |
| 2542 | mod.value_exports.deinit(gpa); | |
| 2557 | zcu.value_exports.deinit(gpa); | |
| 2543 | 2558 | |
| 2544 | for (mod.export_owners.values()) |*value| { | |
| 2559 | for (zcu.export_owners.values()) |*value| { | |
| 2545 | 2560 | freeExportList(gpa, value); |
| 2546 | 2561 | } |
| 2547 | mod.export_owners.deinit(gpa); | |
| 2562 | zcu.export_owners.deinit(gpa); | |
| 2548 | 2563 | |
| 2549 | mod.global_error_set.deinit(gpa); | |
| 2564 | zcu.global_error_set.deinit(gpa); | |
| 2550 | 2565 | |
| 2551 | mod.test_functions.deinit(gpa); | |
| 2566 | zcu.test_functions.deinit(gpa); | |
| 2552 | 2567 | |
| 2553 | for (mod.global_assembly.values()) |s| { | |
| 2568 | for (zcu.global_assembly.values()) |s| { | |
| 2554 | 2569 | gpa.free(s); |
| 2555 | 2570 | } |
| 2556 | mod.global_assembly.deinit(gpa); | |
| 2571 | zcu.global_assembly.deinit(gpa); | |
| 2557 | 2572 | |
| 2558 | mod.reference_table.deinit(gpa); | |
| 2573 | zcu.reference_table.deinit(gpa); | |
| 2559 | 2574 | |
| 2560 | 2575 | { |
| 2561 | var it = mod.intern_pool.allocated_namespaces.iterator(0); | |
| 2576 | var it = zcu.intern_pool.allocated_namespaces.iterator(0); | |
| 2562 | 2577 | while (it.next()) |namespace| { |
| 2563 | 2578 | namespace.decls.deinit(gpa); |
| 2564 | 2579 | namespace.usingnamespace_set.deinit(gpa); |
| 2565 | 2580 | } |
| 2566 | 2581 | } |
| 2567 | 2582 | |
| 2568 | mod.intern_pool.deinit(gpa); | |
| 2569 | mod.tmp_hack_arena.deinit(); | |
| 2583 | zcu.intern_pool.deinit(gpa); | |
| 2584 | zcu.tmp_hack_arena.deinit(); | |
| 2570 | 2585 | |
| 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); | |
| 2574 | 2589 | } |
| 2575 | 2590 | |
| 2576 | 2591 | pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void { |
| ... | ... | @@ -2632,6 +2647,8 @@ comptime { |
| 2632 | 2647 | } |
| 2633 | 2648 | |
| 2634 | 2649 | pub fn astGenFile(mod: *Module, file: *File) !void { |
| 2650 | assert(!file.mod.isBuiltin()); | |
| 2651 | ||
| 2635 | 2652 | const tracy = trace(@src()); |
| 2636 | 2653 | defer tracy.end(); |
| 2637 | 2654 | |
| ... | ... | @@ -3076,72 +3093,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void { |
| 3076 | 3093 | } |
| 3077 | 3094 | } |
| 3078 | 3095 | |
| 3079 | pub 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 | ||
| 3132 | fn 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 | ||
| 3145 | 3096 | pub fn mapOldZirToNew( |
| 3146 | 3097 | gpa: Allocator, |
| 3147 | 3098 | old_zir: Zir, |
| ... | ... | @@ -3228,6 +3179,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { |
| 3228 | 3179 | .complete => return, |
| 3229 | 3180 | |
| 3230 | 3181 | .outdated => blk: { |
| 3182 | if (build_options.only_c) unreachable; | |
| 3231 | 3183 | // The exports this Decl performs will be re-discovered, so we remove them here |
| 3232 | 3184 | // prior to re-analysis. |
| 3233 | 3185 | try mod.deleteDeclExports(decl_index); |
| ... | ... | @@ -3280,14 +3232,14 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { |
| 3280 | 3232 | } |
| 3281 | 3233 | } |
| 3282 | 3234 | |
| 3283 | pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaError!void { | |
| 3235 | pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError!void { | |
| 3284 | 3236 | const tracy = trace(@src()); |
| 3285 | 3237 | defer tracy.end(); |
| 3286 | 3238 | |
| 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); | |
| 3289 | 3241 | const decl_index = func.owner_decl; |
| 3290 | const decl = mod.declPtr(decl_index); | |
| 3242 | const decl = zcu.declPtr(decl_index); | |
| 3291 | 3243 | |
| 3292 | 3244 | switch (decl.analysis) { |
| 3293 | 3245 | .unreferenced => unreachable, |
| ... | ... | @@ -3311,13 +3263,13 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr |
| 3311 | 3263 | .success => return, |
| 3312 | 3264 | } |
| 3313 | 3265 | |
| 3314 | const gpa = mod.gpa; | |
| 3266 | const gpa = zcu.gpa; | |
| 3315 | 3267 | |
| 3316 | 3268 | var tmp_arena = std.heap.ArenaAllocator.init(gpa); |
| 3317 | 3269 | defer tmp_arena.deinit(); |
| 3318 | 3270 | const sema_arena = tmp_arena.allocator(); |
| 3319 | 3271 | |
| 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) { | |
| 3321 | 3273 | error.AnalysisFail => { |
| 3322 | 3274 | if (func.analysis(ip).state == .in_progress) { |
| 3323 | 3275 | // 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 |
| 3331 | 3283 | }; |
| 3332 | 3284 | defer air.deinit(gpa); |
| 3333 | 3285 | |
| 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; | |
| 3340 | 3287 | |
| 3341 | 3288 | const dump_air = builtin.mode == .Debug and comp.verbose_air; |
| 3342 | 3289 | const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null); |
| 3343 | 3290 | |
| 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 | } | |
| 3345 | 3294 | |
| 3346 | 3295 | var liveness = try Liveness.analyze(gpa, air, ip); |
| 3347 | 3296 | defer liveness.deinit(gpa); |
| 3348 | 3297 | |
| 3349 | 3298 | if (dump_air) { |
| 3350 | const fqn = try decl.getFullyQualifiedName(mod); | |
| 3299 | const fqn = try decl.getFullyQualifiedName(zcu); | |
| 3351 | 3300 | 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); | |
| 3353 | 3302 | std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)}); |
| 3354 | 3303 | } |
| 3355 | 3304 | |
| ... | ... | @@ -3365,12 +3314,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr |
| 3365 | 3314 | verify.verify() catch |err| switch (err) { |
| 3366 | 3315 | error.OutOfMemory => return error.OutOfMemory, |
| 3367 | 3316 | 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( | |
| 3370 | 3319 | decl_index, |
| 3371 | 3320 | try Module.ErrorMsg.create( |
| 3372 | 3321 | gpa, |
| 3373 | decl.srcLoc(mod), | |
| 3322 | decl.srcLoc(zcu), | |
| 3374 | 3323 | "invalid liveness: {s}", |
| 3375 | 3324 | .{@errorName(err)}, |
| 3376 | 3325 | ), |
| ... | ... | @@ -3381,27 +3330,32 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr |
| 3381 | 3330 | }; |
| 3382 | 3331 | } |
| 3383 | 3332 | |
| 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 | } | |
| 3405 | 3359 | }, |
| 3406 | 3360 | } |
| 3407 | 3361 | } |
| ... | ... | @@ -3477,6 +3431,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 3477 | 3431 | if (file.root_decl != .none) return; |
| 3478 | 3432 | |
| 3479 | 3433 | 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 | }); | |
| 3480 | 3437 | |
| 3481 | 3438 | // Because these three things each reference each other, `undefined` |
| 3482 | 3439 | // 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 { |
| 3558 | 3515 | new_decl.owns_tv = true; |
| 3559 | 3516 | new_decl.analysis = .complete; |
| 3560 | 3517 | |
| 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 | }; | |
| 3566 | 3525 | |
| 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); | |
| 3576 | 3535 | |
| 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 => {}, | |
| 3580 | 3541 | } |
| 3581 | 3542 | } |
| 3582 | 3543 | |
| ... | ... | @@ -3588,6 +3549,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 3588 | 3549 | defer tracy.end(); |
| 3589 | 3550 | |
| 3590 | 3551 | const decl = mod.declPtr(decl_index); |
| 3552 | const ip = &mod.intern_pool; | |
| 3591 | 3553 | |
| 3592 | 3554 | if (decl.getFileScope(mod).status != .success_zir) { |
| 3593 | 3555 | return error.AnalysisFail; |
| ... | ... | @@ -3597,20 +3559,18 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 3597 | 3559 | const zir = decl.getFileScope(mod).zir; |
| 3598 | 3560 | const zir_datas = zir.instructions.items(.data); |
| 3599 | 3561 | |
| 3600 | // TODO: figure out how this works under incremental changes to builtin.zig! | |
| 3601 | 3562 | 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; | |
| 3603 | 3564 | if (decl.getFileScope(mod).mod != std_mod) break :blk .none; |
| 3604 | 3565 | // We're in the std module. |
| 3605 | 3566 | const std_file = (try mod.importPkg(std_mod)).file; |
| 3606 | 3567 | const std_decl = mod.declPtr(std_file.root_decl.unwrap().?); |
| 3607 | 3568 | 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"); | |
| 3609 | 3570 | const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none); |
| 3610 | 3571 | const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none; |
| 3611 | 3572 | if (decl.src_namespace != builtin_namespace) break :blk .none; |
| 3612 | 3573 | // 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); | |
| 3614 | 3574 | for ([_]struct { []const u8, InternPool.Index }{ |
| 3615 | 3575 | .{ "AtomicOrder", .atomic_order_type }, |
| 3616 | 3576 | .{ "AtomicRmwOp", .atomic_rmw_op_type }, |
| ... | ... | @@ -3624,6 +3584,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 3624 | 3584 | .{ "ExternOptions", .extern_options_type }, |
| 3625 | 3585 | .{ "Type", .type_info_type }, |
| 3626 | 3586 | }) |pair| { |
| 3587 | const decl_name = ip.stringToSlice(decl.name); | |
| 3627 | 3588 | if (std.mem.eql(u8, decl_name, pair[0])) { |
| 3628 | 3589 | break :blk pair[1]; |
| 3629 | 3590 | } |
| ... | ... | @@ -3719,7 +3680,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 3719 | 3680 | return true; |
| 3720 | 3681 | } |
| 3721 | 3682 | |
| 3722 | const ip = &mod.intern_pool; | |
| 3723 | 3683 | switch (ip.indexToKey(decl_tv.val.toIntern())) { |
| 3724 | 3684 | .func => |func| { |
| 3725 | 3685 | const owns_tv = func.owner_decl == decl_index; |
| ... | ... | @@ -3863,25 +3823,24 @@ pub const ImportFileResult = struct { |
| 3863 | 3823 | is_pkg: bool, |
| 3864 | 3824 | }; |
| 3865 | 3825 | |
| 3866 | /// https://github.com/ziglang/zig/issues/14307 | |
| 3867 | pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult { | |
| 3868 | const gpa = mod.gpa; | |
| 3826 | pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { | |
| 3827 | const gpa = zcu.gpa; | |
| 3869 | 3828 | |
| 3870 | 3829 | // The resolved path is used as the key in the import table, to detect if |
| 3871 | 3830 | // an import refers to the same as another, despite different relative paths |
| 3872 | 3831 | // or differently mapped package names. |
| 3873 | 3832 | 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, | |
| 3877 | 3836 | }); |
| 3878 | 3837 | var keep_resolved_path = false; |
| 3879 | 3838 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| 3880 | 3839 | |
| 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(); | |
| 3883 | 3842 | if (gop.found_existing) { |
| 3884 | try gop.value_ptr.*.addReference(mod.*, .{ .root = pkg }); | |
| 3843 | try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod }); | |
| 3885 | 3844 | return ImportFileResult{ |
| 3886 | 3845 | .file = gop.value_ptr.*, |
| 3887 | 3846 | .is_new = false, |
| ... | ... | @@ -3889,7 +3848,18 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult { |
| 3889 | 3848 | }; |
| 3890 | 3849 | } |
| 3891 | 3850 | |
| 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); | |
| 3893 | 3863 | errdefer gpa.free(sub_file_path); |
| 3894 | 3864 | |
| 3895 | 3865 | const new_file = try gpa.create(File); |
| ... | ... | @@ -3907,10 +3877,10 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult { |
| 3907 | 3877 | .tree = undefined, |
| 3908 | 3878 | .zir = undefined, |
| 3909 | 3879 | .status = .never_loaded, |
| 3910 | .mod = pkg, | |
| 3880 | .mod = mod, | |
| 3911 | 3881 | .root_decl = .none, |
| 3912 | 3882 | }; |
| 3913 | try new_file.addReference(mod.*, .{ .root = pkg }); | |
| 3883 | try new_file.addReference(zcu.*, .{ .root = mod }); | |
| 3914 | 3884 | return ImportFileResult{ |
| 3915 | 3885 | .file = new_file, |
| 3916 | 3886 | .is_new = true, |
| ... | ... | @@ -3924,10 +3894,7 @@ pub fn importFile( |
| 3924 | 3894 | import_string: []const u8, |
| 3925 | 3895 | ) !ImportFileResult { |
| 3926 | 3896 | 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); | |
| 3931 | 3898 | } |
| 3932 | 3899 | if (std.mem.eql(u8, import_string, "root")) { |
| 3933 | 3900 | return mod.importPkg(mod.root_mod); |
| ... | ... | @@ -4118,12 +4085,16 @@ fn newEmbedFile( |
| 4118 | 4085 | const actual_read = try file.readAll(ptr); |
| 4119 | 4086 | if (actual_read != size) return error.UnexpectedEndOfFile; |
| 4120 | 4087 | |
| 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 => {}, | |
| 4127 | 4098 | } |
| 4128 | 4099 | |
| 4129 | 4100 | 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 |
| 4312 | 4283 | 1 => blk: { |
| 4313 | 4284 | // test decl with no name. Skip the part where we check against |
| 4314 | 4285 | // the test name filter. |
| 4315 | if (!comp.bin_file.options.is_test) break :blk false; | |
| 4286 | if (!comp.config.is_test) break :blk false; | |
| 4316 | 4287 | if (decl_mod != mod.main_mod) break :blk false; |
| 4317 | 4288 | try mod.test_functions.put(gpa, new_decl_index, {}); |
| 4318 | 4289 | break :blk true; |
| 4319 | 4290 | }, |
| 4320 | 4291 | else => blk: { |
| 4321 | 4292 | 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; | |
| 4323 | 4294 | if (decl_mod != mod.main_mod) break :blk false; |
| 4324 | 4295 | if (comp.test_filter) |test_filter| { |
| 4325 | 4296 | 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 |
| 4331 | 4302 | }, |
| 4332 | 4303 | }; |
| 4333 | 4304 | 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 | }); | |
| 4334 | 4308 | comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index }); |
| 4335 | 4309 | } |
| 4336 | 4310 | new_decl.is_pub = is_pub; |
| ... | ... | @@ -4373,14 +4347,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err |
| 4373 | 4347 | decl.has_linksection_or_addrspace = has_linksection_or_addrspace; |
| 4374 | 4348 | decl.zir_decl_index = @enumFromInt(decl_sub_index); |
| 4375 | 4349 | 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 }); | |
| 4384 | 4353 | } |
| 4385 | 4354 | } |
| 4386 | 4355 | |
| ... | ... | @@ -4466,7 +4435,9 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void |
| 4466 | 4435 | } |
| 4467 | 4436 | }, |
| 4468 | 4437 | } |
| 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 | } | |
| 4470 | 4441 | if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| { |
| 4471 | 4442 | failed_kv.value.destroy(mod.gpa); |
| 4472 | 4443 | } |
| ... | ... | @@ -4628,7 +4599,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato |
| 4628 | 4599 | |
| 4629 | 4600 | // If we don't get an error return trace from a caller, create our own. |
| 4630 | 4601 | 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 | |
| 4632 | 4603 | !sema.fn_ret_ty.isError(mod)) |
| 4633 | 4604 | { |
| 4634 | 4605 | 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 |
| 4721 | 4692 | }; |
| 4722 | 4693 | } |
| 4723 | 4694 | |
| 4724 | fn 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 | ||
| 4743 | 4695 | pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index { |
| 4744 | 4696 | return mod.intern_pool.createNamespace(mod.gpa, initialization); |
| 4745 | 4697 | } |
| ... | ... | @@ -4875,12 +4827,18 @@ pub fn errNoteNonLazy( |
| 4875 | 4827 | }; |
| 4876 | 4828 | } |
| 4877 | 4829 | |
| 4878 | pub 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. | |
| 4833 | pub fn getTarget(zcu: Module) Target { | |
| 4834 | return zcu.root_mod.resolved_target.result; | |
| 4880 | 4835 | } |
| 4881 | 4836 | |
| 4882 | pub 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. | |
| 4840 | pub fn optimizeMode(zcu: Module) std.builtin.OptimizeMode { | |
| 4841 | return zcu.root_mod.optimize_mode; | |
| 4884 | 4842 | } |
| 4885 | 4843 | |
| 4886 | 4844 | fn lockAndClearFileCompileError(mod: *Module, file: *File) void { |
| ... | ... | @@ -5288,43 +5246,57 @@ pub fn processExports(mod: *Module) !void { |
| 5288 | 5246 | const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, *Export); |
| 5289 | 5247 | |
| 5290 | 5248 | fn processExportsInner( |
| 5291 | mod: *Module, | |
| 5249 | zcu: *Zcu, | |
| 5292 | 5250 | symbol_exports: *SymbolExports, |
| 5293 | 5251 | exported: Exported, |
| 5294 | 5252 | exports: []const *Export, |
| 5295 | 5253 | ) error{OutOfMemory}!void { |
| 5296 | const gpa = mod.gpa; | |
| 5254 | const gpa = zcu.gpa; | |
| 5297 | 5255 | |
| 5298 | 5256 | for (exports) |new_export| { |
| 5299 | 5257 | const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name); |
| 5300 | 5258 | if (gop.found_existing) { |
| 5301 | 5259 | 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); | |
| 5304 | 5262 | 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), | |
| 5306 | 5264 | }); |
| 5307 | 5265 | errdefer msg.destroy(gpa); |
| 5308 | 5266 | 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); | |
| 5312 | 5270 | new_export.status = .failed; |
| 5313 | 5271 | } else { |
| 5314 | 5272 | gop.value_ptr.* = new_export; |
| 5315 | 5273 | } |
| 5316 | 5274 | } |
| 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 | ||
| 5283 | fn 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) { | |
| 5318 | 5290 | error.OutOfMemory => return error.OutOfMemory, |
| 5319 | else => { | |
| 5291 | error.AnalysisFail => { | |
| 5320 | 5292 | const new_export = exports[0]; |
| 5321 | 5293 | 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); | |
| 5324 | 5296 | const msg = try ErrorMsg.create(gpa, src_loc, "unable to export: {s}", .{ |
| 5325 | 5297 | @errorName(err), |
| 5326 | 5298 | }); |
| 5327 | mod.failed_exports.putAssumeCapacityNoClobber(new_export, msg); | |
| 5299 | zcu.failed_exports.putAssumeCapacityNoClobber(new_export, msg); | |
| 5328 | 5300 | }, |
| 5329 | 5301 | }; |
| 5330 | 5302 | } |
| ... | ... | @@ -5335,7 +5307,7 @@ pub fn populateTestFunctions( |
| 5335 | 5307 | ) !void { |
| 5336 | 5308 | const gpa = mod.gpa; |
| 5337 | 5309 | const ip = &mod.intern_pool; |
| 5338 | const builtin_mod = mod.main_mod.deps.get("builtin").?; | |
| 5310 | const builtin_mod = mod.root_mod.getBuiltinDependency(); | |
| 5339 | 5311 | const builtin_file = (mod.importPkg(builtin_mod) catch unreachable).file; |
| 5340 | 5312 | const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?); |
| 5341 | 5313 | const builtin_namespace = mod.namespacePtr(root_decl.src_namespace); |
| ... | ... | @@ -5467,39 +5439,39 @@ pub fn populateTestFunctions( |
| 5467 | 5439 | try mod.linkerUpdateDecl(decl_index); |
| 5468 | 5440 | } |
| 5469 | 5441 | |
| 5470 | pub 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); | |
| 5442 | pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void { | |
| 5443 | const comp = zcu.comp; | |
| 5477 | 5444 | |
| 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 | } | |
| 5503 | 5475 | } |
| 5504 | 5476 | |
| 5505 | 5477 | fn reportRetryableFileError( |
| ... | ... | @@ -5592,10 +5564,6 @@ pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u |
| 5592 | 5564 | } |
| 5593 | 5565 | } |
| 5594 | 5566 | |
| 5595 | pub fn wantDllExports(mod: Module) bool { | |
| 5596 | return mod.comp.bin_file.options.dll_export_fns and mod.getTarget().os.tag == .windows; | |
| 5597 | } | |
| 5598 | ||
| 5599 | 5567 | pub fn getDeclExports(mod: Module, decl_index: Decl.Index) []const *Export { |
| 5600 | 5568 | if (mod.decl_exports.get(decl_index)) |l| { |
| 5601 | 5569 | return l.items; |
| ... | ... | @@ -5622,21 +5590,11 @@ pub const Feature = enum { |
| 5622 | 5590 | safety_checked_instructions, |
| 5623 | 5591 | }; |
| 5624 | 5592 | |
| 5625 | pub 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 | }; | |
| 5593 | pub 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); | |
| 5640 | 5598 | } |
| 5641 | 5599 | |
| 5642 | 5600 | /// Shortcut for calling `intern_pool.get`. |
src/Package.zig+12-2| ... | ... | @@ -88,10 +88,10 @@ pub const Path = struct { |
| 88 | 88 | p: Path, |
| 89 | 89 | sub_path: []const u8, |
| 90 | 90 | options: fs.Dir.AtomicFileOptions, |
| 91 | buf: *[fs.MAX_PATH_BYTES]u8, | |
| 91 | 92 | ) !fs.AtomicFile { |
| 92 | var buf: [fs.MAX_PATH_BYTES]u8 = undefined; | |
| 93 | 93 | 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}", .{ | |
| 95 | 95 | p.sub_path, sub_path, |
| 96 | 96 | }) catch return error.NameTooLong; |
| 97 | 97 | }; |
| ... | ... | @@ -108,6 +108,16 @@ pub const Path = struct { |
| 108 | 108 | return p.root_dir.handle.access(joined_path, flags); |
| 109 | 109 | } |
| 110 | 110 | |
| 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 | ||
| 111 | 121 | pub fn format( |
| 112 | 122 | self: Path, |
| 113 | 123 | comptime fmt_string: []const u8, |
src/Package/Module.zig+460-6| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //! 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 | |
| 4 | 4 | |
| 5 | 5 | /// Only files inside this directory can be imported. |
| 6 | 6 | root: Package.Path, |
| ... | ... | @@ -14,17 +14,465 @@ fully_qualified_name: []const u8, |
| 14 | 14 | /// responsible for detecting these names and using the correct package. |
| 15 | 15 | deps: Deps = .{}, |
| 16 | 16 | |
| 17 | resolved_target: ResolvedTarget, | |
| 18 | optimize_mode: std.builtin.OptimizeMode, | |
| 19 | code_model: std.builtin.CodeModel, | |
| 20 | single_threaded: bool, | |
| 21 | error_tracing: bool, | |
| 22 | valgrind: bool, | |
| 23 | pic: bool, | |
| 24 | strip: bool, | |
| 25 | omit_frame_pointer: bool, | |
| 26 | stack_check: bool, | |
| 27 | stack_protector: u32, | |
| 28 | red_zone: bool, | |
| 29 | sanitize_c: bool, | |
| 30 | sanitize_thread: bool, | |
| 31 | unwind_tables: bool, | |
| 32 | cc_argv: []const []const u8, | |
| 33 | /// (SPIR-V) whether to generate a structured control flow graph or not | |
| 34 | structured_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. | |
| 38 | builtin_file: ?*File, | |
| 39 | ||
| 17 | 40 | pub const Deps = std.StringArrayHashMapUnmanaged(*Module); |
| 18 | 41 | |
| 42 | pub fn isBuiltin(m: Module) bool { | |
| 43 | return m.builtin_file != null; | |
| 44 | } | |
| 45 | ||
| 19 | 46 | pub const Tree = struct { |
| 20 | 47 | /// Each `Package` exposes a `Module` with build.zig as its root source file. |
| 21 | 48 | build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module), |
| 22 | 49 | }; |
| 23 | 50 | |
| 24 | pub fn create(allocator: Allocator, m: Module) Allocator.Error!*Module { | |
| 25 | const new = try allocator.create(Module); | |
| 26 | new.* = m; | |
| 27 | return new; | |
| 51 | pub 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 | ||
| 96 | pub 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. | |
| 104 | pub 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`. | |
| 432 | pub 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. | |
| 440 | pub 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. | |
| 472 | pub fn getBuiltinDependency(m: Module) *Module { | |
| 473 | const result = m.deps.values()[0]; | |
| 474 | assert(result.isBuiltin()); | |
| 475 | return result; | |
| 28 | 476 | } |
| 29 | 477 | |
| 30 | 478 | const Module = @This(); |
| ... | ... | @@ -32,3 +480,9 @@ const Package = @import("../Package.zig"); |
| 32 | 480 | const std = @import("std"); |
| 33 | 481 | const Allocator = std.mem.Allocator; |
| 34 | 482 | const MultiHashHexDigest = Package.Manifest.MultiHashHexDigest; |
| 483 | const target_util = @import("../target.zig"); | |
| 484 | const Cache = std.Build.Cache; | |
| 485 | const Builtin = @import("../Builtin.zig"); | |
| 486 | const assert = std.debug.assert; | |
| 487 | const Compilation = @import("../Compilation.zig"); | |
| 488 | const File = @import("../Module.zig").File; |
src/Sema.zig+88-61| ... | ... | @@ -784,6 +784,11 @@ pub const Block = struct { |
| 784 | 784 | } |
| 785 | 785 | } |
| 786 | 786 | |
| 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 | ||
| 787 | 792 | pub fn startAnonDecl(block: *Block) !WipAnonDecl { |
| 788 | 793 | return WipAnonDecl{ |
| 789 | 794 | .block = block, |
| ... | ... | @@ -1324,13 +1329,13 @@ fn analyzeBodyInner( |
| 1324 | 1329 | }, |
| 1325 | 1330 | .dbg_block_begin => { |
| 1326 | 1331 | dbg_block_begins += 1; |
| 1327 | try sema.zirDbgBlockBegin(block); | |
| 1332 | try zirDbgBlockBegin(block); | |
| 1328 | 1333 | i += 1; |
| 1329 | 1334 | continue; |
| 1330 | 1335 | }, |
| 1331 | 1336 | .dbg_block_end => { |
| 1332 | 1337 | dbg_block_begins -= 1; |
| 1333 | try sema.zirDbgBlockEnd(block); | |
| 1338 | try zirDbgBlockEnd(block); | |
| 1334 | 1339 | i += 1; |
| 1335 | 1340 | continue; |
| 1336 | 1341 | }, |
| ... | ... | @@ -1825,17 +1830,17 @@ fn analyzeBodyInner( |
| 1825 | 1830 | }; |
| 1826 | 1831 | |
| 1827 | 1832 | // 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); | |
| 1837 | 1843 | } |
| 1838 | if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some); | |
| 1839 | 1844 | |
| 1840 | 1845 | // We may have overwritten the capture scope due to a `repeat` instruction where |
| 1841 | 1846 | // the body had a capture; restore it now. |
| ... | ... | @@ -2040,9 +2045,10 @@ fn analyzeAsType( |
| 2040 | 2045 | |
| 2041 | 2046 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { |
| 2042 | 2047 | const mod = sema.mod; |
| 2048 | const comp = mod.comp; | |
| 2043 | 2049 | const gpa = sema.gpa; |
| 2044 | 2050 | const ip = &mod.intern_pool; |
| 2045 | if (!mod.backendSupportsFeature(.error_return_trace)) return; | |
| 2051 | if (!comp.config.any_error_tracing) return; | |
| 2046 | 2052 | |
| 2047 | 2053 | assert(!block.is_comptime); |
| 2048 | 2054 | var err_trace_block = block.makeSubBlock(); |
| ... | ... | @@ -5733,7 +5739,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5733 | 5739 | // Ignore the result, all the relevant operations have written to c_import_buf already. |
| 5734 | 5740 | _ = try sema.analyzeBodyBreak(&child_block, body); |
| 5735 | 5741 | |
| 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| | |
| 5737 | 5743 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 5738 | 5744 | defer c_import_res.deinit(gpa); |
| 5739 | 5745 | |
| ... | ... | @@ -5742,7 +5748,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5742 | 5748 | const msg = try sema.errMsg(&child_block, src, "C import failed", .{}); |
| 5743 | 5749 | errdefer msg.destroy(gpa); |
| 5744 | 5750 | |
| 5745 | if (!comp.bin_file.options.link_libc) | |
| 5751 | if (!comp.config.link_libc) | |
| 5746 | 5752 | try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{}); |
| 5747 | 5753 | |
| 5748 | 5754 | 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 |
| 5754 | 5760 | }; |
| 5755 | 5761 | return sema.failWithOwnedErrorMsg(&child_block, msg); |
| 5756 | 5762 | } |
| 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), | |
| 5761 | 5772 | }, |
| 5762 | .root_src_path = std.fs.path.basename(c_import_res.out_zig_path), | |
| 5763 | 5773 | .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 | }; | |
| 5765 | 5796 | |
| 5766 | 5797 | const result = mod.importPkg(c_import_mod) catch |err| |
| 5767 | 5798 | 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 |
| 6267 | 6298 | // ZIR code that possibly will need to generate runtime code. So error messages |
| 6268 | 6299 | // and other source locations must not rely on sema.src being set from dbg_stmt |
| 6269 | 6300 | // 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; | |
| 6271 | 6302 | |
| 6272 | 6303 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; |
| 6273 | 6304 | |
| ... | ... | @@ -6292,8 +6323,8 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi |
| 6292 | 6323 | }); |
| 6293 | 6324 | } |
| 6294 | 6325 | |
| 6295 | fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void { | |
| 6296 | if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return; | |
| 6326 | fn zirDbgBlockBegin(block: *Block) CompileError!void { | |
| 6327 | if (block.is_comptime or block.ownerModule().strip) return; | |
| 6297 | 6328 | |
| 6298 | 6329 | _ = try block.addInst(.{ |
| 6299 | 6330 | .tag = .dbg_block_begin, |
| ... | ... | @@ -6301,8 +6332,8 @@ fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void { |
| 6301 | 6332 | }); |
| 6302 | 6333 | } |
| 6303 | 6334 | |
| 6304 | fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void { | |
| 6305 | if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return; | |
| 6335 | fn zirDbgBlockEnd(block: *Block) CompileError!void { | |
| 6336 | if (block.is_comptime or block.ownerModule().strip) return; | |
| 6306 | 6337 | |
| 6307 | 6338 | _ = try block.addInst(.{ |
| 6308 | 6339 | .tag = .dbg_block_end, |
| ... | ... | @@ -6316,7 +6347,7 @@ fn zirDbgVar( |
| 6316 | 6347 | inst: Zir.Inst.Index, |
| 6317 | 6348 | air_tag: Air.Inst.Tag, |
| 6318 | 6349 | ) 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; | |
| 6320 | 6351 | |
| 6321 | 6352 | const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op; |
| 6322 | 6353 | const operand = try sema.resolveInst(str_op.operand); |
| ... | ... | @@ -6513,8 +6544,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 6513 | 6544 | const gpa = sema.gpa; |
| 6514 | 6545 | const src = sema.src; |
| 6515 | 6546 | |
| 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; | |
| 6518 | 6548 | |
| 6519 | 6549 | if (block.is_comptime) |
| 6520 | 6550 | return .none; |
| ... | ... | @@ -6698,7 +6728,7 @@ fn zirCall( |
| 6698 | 6728 | input_is_error = false; |
| 6699 | 6729 | } |
| 6700 | 6730 | |
| 6701 | if (mod.backendSupportsFeature(.error_return_trace) and mod.comp.bin_file.options.error_return_tracing and | |
| 6731 | if (block.ownerModule().error_tracing and | |
| 6702 | 6732 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) |
| 6703 | 6733 | { |
| 6704 | 6734 | const return_ty = sema.typeOf(call_inst); |
| ... | ... | @@ -7451,7 +7481,7 @@ fn analyzeCall( |
| 7451 | 7481 | new_fn_info.return_type = sema.fn_ret_ty.toIntern(); |
| 7452 | 7482 | const new_func_resolved_ty = try mod.funcType(new_fn_info); |
| 7453 | 7483 | 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); | |
| 7455 | 7485 | |
| 7456 | 7486 | const zir_tags = sema.code.instructions.items(.tag); |
| 7457 | 7487 | for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) { |
| ... | ... | @@ -7489,7 +7519,7 @@ fn analyzeCall( |
| 7489 | 7519 | if (!is_comptime_call and !block.is_typeof and |
| 7490 | 7520 | sema.typeOf(result).zigTypeTag(mod) != .NoReturn) |
| 7491 | 7521 | { |
| 7492 | try sema.emitDbgInline( | |
| 7522 | try emitDbgInline( | |
| 7493 | 7523 | block, |
| 7494 | 7524 | module_fn_index, |
| 7495 | 7525 | prev_fn_index, |
| ... | ... | @@ -8062,15 +8092,13 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) |
| 8062 | 8092 | } |
| 8063 | 8093 | |
| 8064 | 8094 | fn emitDbgInline( |
| 8065 | sema: *Sema, | |
| 8066 | 8095 | block: *Block, |
| 8067 | 8096 | old_func: InternPool.Index, |
| 8068 | 8097 | new_func: InternPool.Index, |
| 8069 | 8098 | new_func_ty: Type, |
| 8070 | 8099 | tag: Air.Inst.Tag, |
| 8071 | 8100 | ) CompileError!void { |
| 8072 | const mod = sema.mod; | |
| 8073 | if (mod.comp.bin_file.options.strip) return; | |
| 8101 | if (block.ownerModule().strip) return; | |
| 8074 | 8102 | |
| 8075 | 8103 | // Recursive inline call; no dbg_inline needed. |
| 8076 | 8104 | if (old_func == new_func) return; |
| ... | ... | @@ -9058,7 +9086,7 @@ fn resolveGenericBody( |
| 9058 | 9086 | |
| 9059 | 9087 | /// Given a library name, examines if the library name should end up in |
| 9060 | 9088 | /// `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), | |
| 9062 | 9090 | /// and puts it there if it doesn't exist. |
| 9063 | 9091 | /// It also dupes the library name which can then be saved as part of the |
| 9064 | 9092 | /// respective `Decl` (either `ExternFn` or `Var`). |
| ... | ... | @@ -9075,8 +9103,8 @@ fn handleExternLibName( |
| 9075 | 9103 | const comp = mod.comp; |
| 9076 | 9104 | const target = mod.getTarget(); |
| 9077 | 9105 | 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) { | |
| 9080 | 9108 | return sema.fail( |
| 9081 | 9109 | block, |
| 9082 | 9110 | src_loc, |
| ... | ... | @@ -9086,22 +9114,25 @@ fn handleExternLibName( |
| 9086 | 9114 | } |
| 9087 | 9115 | break :blk; |
| 9088 | 9116 | } |
| 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 | ); | |
| 9098 | 9124 | break :blk; |
| 9099 | 9125 | } |
| 9100 | 9126 | 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 | ); | |
| 9102 | 9133 | break :blk; |
| 9103 | 9134 | } |
| 9104 | if (!target.isWasm() and !comp.bin_file.options.pic) { | |
| 9135 | if (!target.isWasm() and !block.ownerModule().pic) { | |
| 9105 | 9136 | return sema.fail( |
| 9106 | 9137 | block, |
| 9107 | 9138 | src_loc, |
| ... | ... | @@ -18728,18 +18759,14 @@ fn retWithErrTracing( |
| 18728 | 18759 | |
| 18729 | 18760 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 18730 | 18761 | 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; | |
| 18735 | 18763 | } |
| 18736 | 18764 | |
| 18737 | 18765 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 18738 | 18766 | const mod = sema.mod; |
| 18739 | 18767 | const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index; |
| 18740 | 18768 | |
| 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; | |
| 18743 | 18770 | |
| 18744 | 18771 | // This is only relevant at runtime. |
| 18745 | 18772 | if (block.is_comptime or block.is_typeof) return; |
| ... | ... | @@ -18764,9 +18791,8 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) |
| 18764 | 18791 | const mod = sema.mod; |
| 18765 | 18792 | const ip = &mod.intern_pool; |
| 18766 | 18793 | |
| 18767 | if (!mod.backendSupportsFeature(.error_return_trace)) return; | |
| 18768 | 18794 | 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; | |
| 18770 | 18796 | |
| 18771 | 18797 | const tracy = trace(@src()); |
| 18772 | 18798 | defer tracy.end(); |
| ... | ... | @@ -20037,8 +20063,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 20037 | 20063 | |
| 20038 | 20064 | if (sema.owner_func_index != .none and |
| 20039 | 20065 | 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) | |
| 20042 | 20067 | { |
| 20043 | 20068 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 20044 | 20069 | } |
| ... | ... | @@ -34520,7 +34545,9 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void { |
| 34520 | 34545 | |
| 34521 | 34546 | try sema.resolveTypeFully(Type.fromInterned(fn_ty_info.return_type)); |
| 34522 | 34547 | |
| 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 | { | |
| 34524 | 34551 | // Ensure the type exists so that backends can assume that. |
| 34525 | 34552 | _ = try sema.getBuiltinType("StackTrace"); |
| 34526 | 34553 | } |
| ... | ... | @@ -36692,7 +36719,7 @@ fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!Int |
| 36692 | 36719 | |
| 36693 | 36720 | const mod = sema.mod; |
| 36694 | 36721 | const ip = &mod.intern_pool; |
| 36695 | const std_mod = mod.main_mod.deps.get("std").?; | |
| 36722 | const std_mod = mod.std_mod; | |
| 36696 | 36723 | const std_file = (mod.importPkg(std_mod) catch unreachable).file; |
| 36697 | 36724 | const opt_builtin_inst = (try sema.namespaceLookupRef( |
| 36698 | 36725 | block, |
src/arch/aarch64/CodeGen.zig+92-93| ... | ... | @@ -329,7 +329,7 @@ const BigTomb = struct { |
| 329 | 329 | const Self = @This(); |
| 330 | 330 | |
| 331 | 331 | pub fn generate( |
| 332 | bin_file: *link.File, | |
| 332 | lf: *link.File, | |
| 333 | 333 | src_loc: Module.SrcLoc, |
| 334 | 334 | func_index: InternPool.Index, |
| 335 | 335 | air: Air, |
| ... | ... | @@ -337,31 +337,30 @@ pub fn generate( |
| 337 | 337 | code: *std.ArrayList(u8), |
| 338 | 338 | debug_output: DebugInfoOutput, |
| 339 | 339 | ) 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); | |
| 347 | 344 | assert(fn_owner_decl.has_tv); |
| 348 | 345 | 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; | |
| 349 | 348 | |
| 350 | var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); | |
| 349 | var branch_stack = std.ArrayList(Branch).init(gpa); | |
| 351 | 350 | defer { |
| 352 | 351 | assert(branch_stack.items.len == 1); |
| 353 | branch_stack.items[0].deinit(bin_file.allocator); | |
| 352 | branch_stack.items[0].deinit(gpa); | |
| 354 | 353 | branch_stack.deinit(); |
| 355 | 354 | } |
| 356 | 355 | try branch_stack.append(.{}); |
| 357 | 356 | |
| 358 | 357 | var function = Self{ |
| 359 | .gpa = bin_file.allocator, | |
| 358 | .gpa = gpa, | |
| 360 | 359 | .air = air, |
| 361 | 360 | .liveness = liveness, |
| 362 | 361 | .debug_output = debug_output, |
| 363 | .target = &bin_file.options.target, | |
| 364 | .bin_file = bin_file, | |
| 362 | .target = target, | |
| 363 | .bin_file = lf, | |
| 365 | 364 | .func_index = func_index, |
| 366 | 365 | .owner_decl = func.owner_decl, |
| 367 | 366 | .err_msg = null, |
| ... | ... | @@ -375,15 +374,15 @@ pub fn generate( |
| 375 | 374 | .end_di_line = func.rbrace_line, |
| 376 | 375 | .end_di_column = func.rbrace_column, |
| 377 | 376 | }; |
| 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); | |
| 382 | 381 | |
| 383 | 382 | var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) { |
| 384 | 383 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 385 | 384 | 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.", .{}), | |
| 387 | 386 | }, |
| 388 | 387 | else => |e| return e, |
| 389 | 388 | }; |
| ... | ... | @@ -397,7 +396,7 @@ pub fn generate( |
| 397 | 396 | function.gen() catch |err| switch (err) { |
| 398 | 397 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 399 | 398 | 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.", .{}), | |
| 401 | 400 | }, |
| 402 | 401 | else => |e| return e, |
| 403 | 402 | }; |
| ... | ... | @@ -408,15 +407,15 @@ pub fn generate( |
| 408 | 407 | |
| 409 | 408 | var mir = Mir{ |
| 410 | 409 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 411 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 410 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 412 | 411 | }; |
| 413 | defer mir.deinit(bin_file.allocator); | |
| 412 | defer mir.deinit(gpa); | |
| 414 | 413 | |
| 415 | 414 | var emit = Emit{ |
| 416 | 415 | .mir = mir, |
| 417 | .bin_file = bin_file, | |
| 416 | .bin_file = lf, | |
| 418 | 417 | .debug_output = debug_output, |
| 419 | .target = &bin_file.options.target, | |
| 418 | .target = target, | |
| 420 | 419 | .src_loc = src_loc, |
| 421 | 420 | .code = code, |
| 422 | 421 | .prev_di_pc = 0, |
| ... | ... | @@ -476,7 +475,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 476 | 475 | } |
| 477 | 476 | |
| 478 | 477 | fn gen(self: *Self) !void { |
| 479 | const mod = self.bin_file.options.module.?; | |
| 478 | const mod = self.bin_file.comp.module.?; | |
| 480 | 479 | const cc = self.fn_type.fnCallingConvention(mod); |
| 481 | 480 | if (cc != .Naked) { |
| 482 | 481 | // stp fp, lr, [sp, #-16]! |
| ... | ... | @@ -656,7 +655,7 @@ fn gen(self: *Self) !void { |
| 656 | 655 | } |
| 657 | 656 | |
| 658 | 657 | fn 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.?; | |
| 660 | 659 | const ip = &mod.intern_pool; |
| 661 | 660 | const air_tags = self.air.instructions.items(.tag); |
| 662 | 661 | |
| ... | ... | @@ -1028,7 +1027,7 @@ fn allocMem( |
| 1028 | 1027 | |
| 1029 | 1028 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1030 | 1029 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1031 | const mod = self.bin_file.options.module.?; | |
| 1030 | const mod = self.bin_file.comp.module.?; | |
| 1032 | 1031 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 1033 | 1032 | |
| 1034 | 1033 | if (!elem_ty.hasRuntimeBits(mod)) { |
| ... | ... | @@ -1048,7 +1047,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1048 | 1047 | } |
| 1049 | 1048 | |
| 1050 | 1049 | fn 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.?; | |
| 1052 | 1051 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { |
| 1053 | 1052 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); |
| 1054 | 1053 | }; |
| ... | ... | @@ -1139,7 +1138,7 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1139 | 1138 | } |
| 1140 | 1139 | |
| 1141 | 1140 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1142 | const mod = self.bin_file.options.module.?; | |
| 1141 | const mod = self.bin_file.comp.module.?; | |
| 1143 | 1142 | const result: MCValue = switch (self.ret_mcv) { |
| 1144 | 1143 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1145 | 1144 | .stack_offset => blk: { |
| ... | ... | @@ -1176,7 +1175,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1176 | 1175 | if (self.liveness.isUnused(inst)) |
| 1177 | 1176 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 1178 | 1177 | |
| 1179 | const mod = self.bin_file.options.module.?; | |
| 1178 | const mod = self.bin_file.comp.module.?; | |
| 1180 | 1179 | const operand = ty_op.operand; |
| 1181 | 1180 | const operand_mcv = try self.resolveInst(operand); |
| 1182 | 1181 | const operand_ty = self.typeOf(operand); |
| ... | ... | @@ -1257,7 +1256,7 @@ fn trunc( |
| 1257 | 1256 | operand_ty: Type, |
| 1258 | 1257 | dest_ty: Type, |
| 1259 | 1258 | ) !MCValue { |
| 1260 | const mod = self.bin_file.options.module.?; | |
| 1259 | const mod = self.bin_file.comp.module.?; | |
| 1261 | 1260 | const info_a = operand_ty.intInfo(mod); |
| 1262 | 1261 | const info_b = dest_ty.intInfo(mod); |
| 1263 | 1262 | |
| ... | ... | @@ -1320,7 +1319,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1320 | 1319 | |
| 1321 | 1320 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1322 | 1321 | 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.?; | |
| 1324 | 1323 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1325 | 1324 | const operand = try self.resolveInst(ty_op.operand); |
| 1326 | 1325 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -1415,7 +1414,7 @@ fn minMax( |
| 1415 | 1414 | rhs_ty: Type, |
| 1416 | 1415 | maybe_inst: ?Air.Inst.Index, |
| 1417 | 1416 | ) !MCValue { |
| 1418 | const mod = self.bin_file.options.module.?; | |
| 1417 | const mod = self.bin_file.comp.module.?; | |
| 1419 | 1418 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1420 | 1419 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1421 | 1420 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| ... | ... | @@ -1905,7 +1904,7 @@ fn addSub( |
| 1905 | 1904 | rhs_ty: Type, |
| 1906 | 1905 | maybe_inst: ?Air.Inst.Index, |
| 1907 | 1906 | ) InnerError!MCValue { |
| 1908 | const mod = self.bin_file.options.module.?; | |
| 1907 | const mod = self.bin_file.comp.module.?; | |
| 1909 | 1908 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1910 | 1909 | .Float => return self.fail("TODO binary operations on floats", .{}), |
| 1911 | 1910 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| ... | ... | @@ -1966,7 +1965,7 @@ fn mul( |
| 1966 | 1965 | rhs_ty: Type, |
| 1967 | 1966 | maybe_inst: ?Air.Inst.Index, |
| 1968 | 1967 | ) InnerError!MCValue { |
| 1969 | const mod = self.bin_file.options.module.?; | |
| 1968 | const mod = self.bin_file.comp.module.?; | |
| 1970 | 1969 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1971 | 1970 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 1972 | 1971 | .Int => { |
| ... | ... | @@ -1998,7 +1997,7 @@ fn divFloat( |
| 1998 | 1997 | _ = rhs_ty; |
| 1999 | 1998 | _ = maybe_inst; |
| 2000 | 1999 | |
| 2001 | const mod = self.bin_file.options.module.?; | |
| 2000 | const mod = self.bin_file.comp.module.?; | |
| 2002 | 2001 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2003 | 2002 | .Float => return self.fail("TODO div_float", .{}), |
| 2004 | 2003 | .Vector => return self.fail("TODO div_float on vectors", .{}), |
| ... | ... | @@ -2014,7 +2013,7 @@ fn divTrunc( |
| 2014 | 2013 | rhs_ty: Type, |
| 2015 | 2014 | maybe_inst: ?Air.Inst.Index, |
| 2016 | 2015 | ) InnerError!MCValue { |
| 2017 | const mod = self.bin_file.options.module.?; | |
| 2016 | const mod = self.bin_file.comp.module.?; | |
| 2018 | 2017 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2019 | 2018 | .Float => return self.fail("TODO div on floats", .{}), |
| 2020 | 2019 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | ... | @@ -2048,7 +2047,7 @@ fn divFloor( |
| 2048 | 2047 | rhs_ty: Type, |
| 2049 | 2048 | maybe_inst: ?Air.Inst.Index, |
| 2050 | 2049 | ) InnerError!MCValue { |
| 2051 | const mod = self.bin_file.options.module.?; | |
| 2050 | const mod = self.bin_file.comp.module.?; | |
| 2052 | 2051 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2053 | 2052 | .Float => return self.fail("TODO div on floats", .{}), |
| 2054 | 2053 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | ... | @@ -2081,7 +2080,7 @@ fn divExact( |
| 2081 | 2080 | rhs_ty: Type, |
| 2082 | 2081 | maybe_inst: ?Air.Inst.Index, |
| 2083 | 2082 | ) InnerError!MCValue { |
| 2084 | const mod = self.bin_file.options.module.?; | |
| 2083 | const mod = self.bin_file.comp.module.?; | |
| 2085 | 2084 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2086 | 2085 | .Float => return self.fail("TODO div on floats", .{}), |
| 2087 | 2086 | .Vector => return self.fail("TODO div on vectors", .{}), |
| ... | ... | @@ -2117,7 +2116,7 @@ fn rem( |
| 2117 | 2116 | ) InnerError!MCValue { |
| 2118 | 2117 | _ = maybe_inst; |
| 2119 | 2118 | |
| 2120 | const mod = self.bin_file.options.module.?; | |
| 2119 | const mod = self.bin_file.comp.module.?; | |
| 2121 | 2120 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2122 | 2121 | .Float => return self.fail("TODO rem/mod on floats", .{}), |
| 2123 | 2122 | .Vector => return self.fail("TODO rem/mod on vectors", .{}), |
| ... | ... | @@ -2188,7 +2187,7 @@ fn modulo( |
| 2188 | 2187 | _ = rhs_ty; |
| 2189 | 2188 | _ = maybe_inst; |
| 2190 | 2189 | |
| 2191 | const mod = self.bin_file.options.module.?; | |
| 2190 | const mod = self.bin_file.comp.module.?; | |
| 2192 | 2191 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2193 | 2192 | .Float => return self.fail("TODO mod on floats", .{}), |
| 2194 | 2193 | .Vector => return self.fail("TODO mod on vectors", .{}), |
| ... | ... | @@ -2206,7 +2205,7 @@ fn wrappingArithmetic( |
| 2206 | 2205 | rhs_ty: Type, |
| 2207 | 2206 | maybe_inst: ?Air.Inst.Index, |
| 2208 | 2207 | ) InnerError!MCValue { |
| 2209 | const mod = self.bin_file.options.module.?; | |
| 2208 | const mod = self.bin_file.comp.module.?; | |
| 2210 | 2209 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2211 | 2210 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2212 | 2211 | .Int => { |
| ... | ... | @@ -2241,7 +2240,7 @@ fn bitwise( |
| 2241 | 2240 | rhs_ty: Type, |
| 2242 | 2241 | maybe_inst: ?Air.Inst.Index, |
| 2243 | 2242 | ) InnerError!MCValue { |
| 2244 | const mod = self.bin_file.options.module.?; | |
| 2243 | const mod = self.bin_file.comp.module.?; | |
| 2245 | 2244 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2246 | 2245 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2247 | 2246 | .Int => { |
| ... | ... | @@ -2276,7 +2275,7 @@ fn shiftExact( |
| 2276 | 2275 | ) InnerError!MCValue { |
| 2277 | 2276 | _ = rhs_ty; |
| 2278 | 2277 | |
| 2279 | const mod = self.bin_file.options.module.?; | |
| 2278 | const mod = self.bin_file.comp.module.?; | |
| 2280 | 2279 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2281 | 2280 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2282 | 2281 | .Int => { |
| ... | ... | @@ -2326,7 +2325,7 @@ fn shiftNormal( |
| 2326 | 2325 | rhs_ty: Type, |
| 2327 | 2326 | maybe_inst: ?Air.Inst.Index, |
| 2328 | 2327 | ) InnerError!MCValue { |
| 2329 | const mod = self.bin_file.options.module.?; | |
| 2328 | const mod = self.bin_file.comp.module.?; | |
| 2330 | 2329 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2331 | 2330 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 2332 | 2331 | .Int => { |
| ... | ... | @@ -2366,7 +2365,7 @@ fn booleanOp( |
| 2366 | 2365 | rhs_ty: Type, |
| 2367 | 2366 | maybe_inst: ?Air.Inst.Index, |
| 2368 | 2367 | ) InnerError!MCValue { |
| 2369 | const mod = self.bin_file.options.module.?; | |
| 2368 | const mod = self.bin_file.comp.module.?; | |
| 2370 | 2369 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2371 | 2370 | .Bool => { |
| 2372 | 2371 | assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema |
| ... | ... | @@ -2393,7 +2392,7 @@ fn ptrArithmetic( |
| 2393 | 2392 | rhs_ty: Type, |
| 2394 | 2393 | maybe_inst: ?Air.Inst.Index, |
| 2395 | 2394 | ) InnerError!MCValue { |
| 2396 | const mod = self.bin_file.options.module.?; | |
| 2395 | const mod = self.bin_file.comp.module.?; | |
| 2397 | 2396 | switch (lhs_ty.zigTypeTag(mod)) { |
| 2398 | 2397 | .Pointer => { |
| 2399 | 2398 | assert(rhs_ty.eql(Type.usize, mod)); |
| ... | ... | @@ -2516,7 +2515,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2516 | 2515 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 2517 | 2516 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2518 | 2517 | 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.?; | |
| 2520 | 2519 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2521 | 2520 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2522 | 2521 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -2644,7 +2643,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2644 | 2643 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2645 | 2644 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2646 | 2645 | 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.?; | |
| 2648 | 2647 | const result: MCValue = result: { |
| 2649 | 2648 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2650 | 2649 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -2868,7 +2867,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2868 | 2867 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2869 | 2868 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 2870 | 2869 | 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.?; | |
| 2872 | 2871 | const result: MCValue = result: { |
| 2873 | 2872 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 2874 | 2873 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -3016,7 +3015,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3016 | 3015 | } |
| 3017 | 3016 | |
| 3018 | 3017 | fn 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.?; | |
| 3020 | 3019 | const payload_ty = optional_ty.optionalChild(mod); |
| 3021 | 3020 | if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none; |
| 3022 | 3021 | if (optional_ty.isPtrLikeOptional(mod)) { |
| ... | ... | @@ -3060,7 +3059,7 @@ fn errUnionErr( |
| 3060 | 3059 | error_union_ty: Type, |
| 3061 | 3060 | maybe_inst: ?Air.Inst.Index, |
| 3062 | 3061 | ) !MCValue { |
| 3063 | const mod = self.bin_file.options.module.?; | |
| 3062 | const mod = self.bin_file.comp.module.?; | |
| 3064 | 3063 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3065 | 3064 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3066 | 3065 | if (err_ty.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -3140,7 +3139,7 @@ fn errUnionPayload( |
| 3140 | 3139 | error_union_ty: Type, |
| 3141 | 3140 | maybe_inst: ?Air.Inst.Index, |
| 3142 | 3141 | ) !MCValue { |
| 3143 | const mod = self.bin_file.options.module.?; | |
| 3142 | const mod = self.bin_file.comp.module.?; | |
| 3144 | 3143 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3145 | 3144 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3146 | 3145 | if (err_ty.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -3252,7 +3251,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 3252 | 3251 | } |
| 3253 | 3252 | |
| 3254 | 3253 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3255 | const mod = self.bin_file.options.module.?; | |
| 3254 | const mod = self.bin_file.comp.module.?; | |
| 3256 | 3255 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3257 | 3256 | |
| 3258 | 3257 | if (self.liveness.isUnused(inst)) { |
| ... | ... | @@ -3297,7 +3296,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3297 | 3296 | |
| 3298 | 3297 | /// T to E!T |
| 3299 | 3298 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3300 | const mod = self.bin_file.options.module.?; | |
| 3299 | const mod = self.bin_file.comp.module.?; | |
| 3301 | 3300 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3302 | 3301 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3303 | 3302 | const error_union_ty = ty_op.ty.toType(); |
| ... | ... | @@ -3323,7 +3322,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3323 | 3322 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3324 | 3323 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3325 | 3324 | 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.?; | |
| 3327 | 3326 | const error_union_ty = ty_op.ty.toType(); |
| 3328 | 3327 | const error_ty = error_union_ty.errorUnionSet(mod); |
| 3329 | 3328 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| ... | ... | @@ -3426,7 +3425,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3426 | 3425 | } |
| 3427 | 3426 | |
| 3428 | 3427 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3429 | const mod = self.bin_file.options.module.?; | |
| 3428 | const mod = self.bin_file.comp.module.?; | |
| 3430 | 3429 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3431 | 3430 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3432 | 3431 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -3450,7 +3449,7 @@ fn ptrElemVal( |
| 3450 | 3449 | ptr_ty: Type, |
| 3451 | 3450 | maybe_inst: ?Air.Inst.Index, |
| 3452 | 3451 | ) !MCValue { |
| 3453 | const mod = self.bin_file.options.module.?; | |
| 3452 | const mod = self.bin_file.comp.module.?; | |
| 3454 | 3453 | const elem_ty = ptr_ty.childType(mod); |
| 3455 | 3454 | const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod))); |
| 3456 | 3455 | |
| ... | ... | @@ -3492,7 +3491,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3492 | 3491 | } |
| 3493 | 3492 | |
| 3494 | 3493 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3495 | const mod = self.bin_file.options.module.?; | |
| 3494 | const mod = self.bin_file.comp.module.?; | |
| 3496 | 3495 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3497 | 3496 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3498 | 3497 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -3615,7 +3614,7 @@ fn reuseOperand( |
| 3615 | 3614 | } |
| 3616 | 3615 | |
| 3617 | 3616 | fn 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.?; | |
| 3619 | 3618 | const elem_ty = ptr_ty.childType(mod); |
| 3620 | 3619 | const elem_size = elem_ty.abiSize(mod); |
| 3621 | 3620 | |
| ... | ... | @@ -3863,7 +3862,7 @@ fn genInlineMemsetCode( |
| 3863 | 3862 | } |
| 3864 | 3863 | |
| 3865 | 3864 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3866 | const mod = self.bin_file.options.module.?; | |
| 3865 | const mod = self.bin_file.comp.module.?; | |
| 3867 | 3866 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3868 | 3867 | const elem_ty = self.typeOfIndex(inst); |
| 3869 | 3868 | const elem_size = elem_ty.abiSize(mod); |
| ... | ... | @@ -3894,7 +3893,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3894 | 3893 | } |
| 3895 | 3894 | |
| 3896 | 3895 | fn 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.?; | |
| 3898 | 3897 | const abi_size = ty.abiSize(mod); |
| 3899 | 3898 | |
| 3900 | 3899 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| ... | ... | @@ -3917,7 +3916,7 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3917 | 3916 | } |
| 3918 | 3917 | |
| 3919 | 3918 | fn 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.?; | |
| 3921 | 3920 | const abi_size = ty.abiSize(mod); |
| 3922 | 3921 | |
| 3923 | 3922 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| ... | ... | @@ -3939,7 +3938,7 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type |
| 3939 | 3938 | } |
| 3940 | 3939 | |
| 3941 | 3940 | fn 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.?; | |
| 3943 | 3942 | log.debug("store: storing {} to {}", .{ value, ptr }); |
| 3944 | 3943 | const abi_size = value_ty.abiSize(mod); |
| 3945 | 3944 | |
| ... | ... | @@ -4092,7 +4091,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 4092 | 4091 | |
| 4093 | 4092 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4094 | 4093 | 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.?; | |
| 4096 | 4095 | const mcv = try self.resolveInst(operand); |
| 4097 | 4096 | const ptr_ty = self.typeOf(operand); |
| 4098 | 4097 | const struct_ty = ptr_ty.childType(mod); |
| ... | ... | @@ -4117,7 +4116,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4117 | 4116 | const operand = extra.struct_operand; |
| 4118 | 4117 | const index = extra.field_index; |
| 4119 | 4118 | 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.?; | |
| 4121 | 4120 | const mcv = try self.resolveInst(operand); |
| 4122 | 4121 | const struct_ty = self.typeOf(operand); |
| 4123 | 4122 | const struct_field_ty = struct_ty.structFieldType(index, mod); |
| ... | ... | @@ -4167,7 +4166,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4167 | 4166 | } |
| 4168 | 4167 | |
| 4169 | 4168 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4170 | const mod = self.bin_file.options.module.?; | |
| 4169 | const mod = self.bin_file.comp.module.?; | |
| 4171 | 4170 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4172 | 4171 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 4173 | 4172 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -4195,7 +4194,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4195 | 4194 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4196 | 4195 | self.arg_index = arg_index + 1; |
| 4197 | 4196 | |
| 4198 | const mod = self.bin_file.options.module.?; | |
| 4197 | const mod = self.bin_file.comp.module.?; | |
| 4199 | 4198 | const ty = self.typeOfIndex(inst); |
| 4200 | 4199 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4201 | 4200 | 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 |
| 4250 | 4249 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 4251 | 4250 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len])); |
| 4252 | 4251 | const ty = self.typeOf(callee); |
| 4253 | const mod = self.bin_file.options.module.?; | |
| 4252 | const mod = self.bin_file.comp.module.?; | |
| 4254 | 4253 | |
| 4255 | 4254 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 4256 | 4255 | .Fn => ty, |
| ... | ... | @@ -4422,7 +4421,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4422 | 4421 | } |
| 4423 | 4422 | |
| 4424 | 4423 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4425 | const mod = self.bin_file.options.module.?; | |
| 4424 | const mod = self.bin_file.comp.module.?; | |
| 4426 | 4425 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4427 | 4426 | const operand = try self.resolveInst(un_op); |
| 4428 | 4427 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | ... | @@ -4454,7 +4453,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4454 | 4453 | } |
| 4455 | 4454 | |
| 4456 | 4455 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4457 | const mod = self.bin_file.options.module.?; | |
| 4456 | const mod = self.bin_file.comp.module.?; | |
| 4458 | 4457 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4459 | 4458 | const ptr = try self.resolveInst(un_op); |
| 4460 | 4459 | const ptr_ty = self.typeOf(un_op); |
| ... | ... | @@ -4514,7 +4513,7 @@ fn cmp( |
| 4514 | 4513 | lhs_ty: Type, |
| 4515 | 4514 | op: math.CompareOperator, |
| 4516 | 4515 | ) !MCValue { |
| 4517 | const mod = self.bin_file.options.module.?; | |
| 4516 | const mod = self.bin_file.comp.module.?; | |
| 4518 | 4517 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { |
| 4519 | 4518 | .Optional => blk: { |
| 4520 | 4519 | const payload_ty = lhs_ty.optionalChild(mod); |
| ... | ... | @@ -4622,7 +4621,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4622 | 4621 | |
| 4623 | 4622 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 4624 | 4623 | 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.?; | |
| 4626 | 4625 | const func = mod.funcInfo(ty_fn.func); |
| 4627 | 4626 | // TODO emit debug info for function change |
| 4628 | 4627 | _ = func; |
| ... | ... | @@ -4830,7 +4829,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 4830 | 4829 | } |
| 4831 | 4830 | |
| 4832 | 4831 | fn 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.?; | |
| 4834 | 4833 | const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: { |
| 4835 | 4834 | const payload_ty = operand_ty.optionalChild(mod); |
| 4836 | 4835 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) |
| ... | ... | @@ -4886,7 +4885,7 @@ fn isErr( |
| 4886 | 4885 | error_union_bind: ReadArg.Bind, |
| 4887 | 4886 | error_union_ty: Type, |
| 4888 | 4887 | ) !MCValue { |
| 4889 | const mod = self.bin_file.options.module.?; | |
| 4888 | const mod = self.bin_file.comp.module.?; | |
| 4890 | 4889 | const error_type = error_union_ty.errorUnionSet(mod); |
| 4891 | 4890 | |
| 4892 | 4891 | if (error_type.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -4928,7 +4927,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4928 | 4927 | } |
| 4929 | 4928 | |
| 4930 | 4929 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4931 | const mod = self.bin_file.options.module.?; | |
| 4930 | const mod = self.bin_file.comp.module.?; | |
| 4932 | 4931 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4933 | 4932 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4934 | 4933 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -4955,7 +4954,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4955 | 4954 | } |
| 4956 | 4955 | |
| 4957 | 4956 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4958 | const mod = self.bin_file.options.module.?; | |
| 4957 | const mod = self.bin_file.comp.module.?; | |
| 4959 | 4958 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4960 | 4959 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4961 | 4960 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -4982,7 +4981,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4982 | 4981 | } |
| 4983 | 4982 | |
| 4984 | 4983 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4985 | const mod = self.bin_file.options.module.?; | |
| 4984 | const mod = self.bin_file.comp.module.?; | |
| 4986 | 4985 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4987 | 4986 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4988 | 4987 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -5009,7 +5008,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 5009 | 5008 | } |
| 5010 | 5009 | |
| 5011 | 5010 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5012 | const mod = self.bin_file.options.module.?; | |
| 5011 | const mod = self.bin_file.comp.module.?; | |
| 5013 | 5012 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5014 | 5013 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5015 | 5014 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -5226,7 +5225,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5226 | 5225 | } |
| 5227 | 5226 | |
| 5228 | 5227 | fn 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.?; | |
| 5230 | 5229 | const block_data = self.blocks.getPtr(block).?; |
| 5231 | 5230 | |
| 5232 | 5231 | if (self.typeOf(operand).hasRuntimeBits(mod)) { |
| ... | ... | @@ -5403,7 +5402,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5403 | 5402 | } |
| 5404 | 5403 | |
| 5405 | 5404 | fn 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.?; | |
| 5407 | 5406 | const abi_size = @as(u32, @intCast(ty.abiSize(mod))); |
| 5408 | 5407 | switch (mcv) { |
| 5409 | 5408 | .dead => unreachable, |
| ... | ... | @@ -5573,7 +5572,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5573 | 5572 | } |
| 5574 | 5573 | |
| 5575 | 5574 | fn 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.?; | |
| 5577 | 5576 | switch (mcv) { |
| 5578 | 5577 | .dead => unreachable, |
| 5579 | 5578 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5735,7 +5734,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5735 | 5734 | } |
| 5736 | 5735 | |
| 5737 | 5736 | fn 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.?; | |
| 5739 | 5738 | const abi_size = @as(u32, @intCast(ty.abiSize(mod))); |
| 5740 | 5739 | switch (mcv) { |
| 5741 | 5740 | .dead => unreachable, |
| ... | ... | @@ -5934,7 +5933,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5934 | 5933 | } |
| 5935 | 5934 | |
| 5936 | 5935 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5937 | const mod = self.bin_file.options.module.?; | |
| 5936 | const mod = self.bin_file.comp.module.?; | |
| 5938 | 5937 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5939 | 5938 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5940 | 5939 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -6054,7 +6053,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6054 | 6053 | } |
| 6055 | 6054 | |
| 6056 | 6055 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6057 | const mod = self.bin_file.options.module.?; | |
| 6056 | const mod = self.bin_file.comp.module.?; | |
| 6058 | 6057 | const vector_ty = self.typeOfIndex(inst); |
| 6059 | 6058 | const len = vector_ty.vectorLen(mod); |
| 6060 | 6059 | 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 { |
| 6098 | 6097 | } |
| 6099 | 6098 | |
| 6100 | 6099 | fn airTry(self: *Self, inst: Air.Inst.Index) !void { |
| 6101 | const mod = self.bin_file.options.module.?; | |
| 6100 | const mod = self.bin_file.comp.module.?; | |
| 6102 | 6101 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6103 | 6102 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| 6104 | 6103 | 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 { |
| 6135 | 6134 | } |
| 6136 | 6135 | |
| 6137 | 6136 | fn 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.?; | |
| 6139 | 6138 | |
| 6140 | 6139 | // If the type has no codegen bits, no need to store it. |
| 6141 | 6140 | const inst_ty = self.typeOf(inst); |
| ... | ... | @@ -6200,7 +6199,7 @@ const CallMCValues = struct { |
| 6200 | 6199 | |
| 6201 | 6200 | /// Caller must call `CallMCValues.deinit`. |
| 6202 | 6201 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6203 | const mod = self.bin_file.options.module.?; | |
| 6202 | const mod = self.bin_file.comp.module.?; | |
| 6204 | 6203 | const ip = &mod.intern_pool; |
| 6205 | 6204 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 6206 | 6205 | const cc = fn_info.cc; |
| ... | ... | @@ -6333,7 +6332,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6333 | 6332 | |
| 6334 | 6333 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. |
| 6335 | 6334 | fn wantSafety(self: *Self) bool { |
| 6336 | return switch (self.bin_file.options.optimize_mode) { | |
| 6335 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | |
| 6337 | 6336 | .Debug => true, |
| 6338 | 6337 | .ReleaseSafe => true, |
| 6339 | 6338 | .ReleaseFast => false, |
| ... | ... | @@ -6344,14 +6343,14 @@ fn wantSafety(self: *Self) bool { |
| 6344 | 6343 | fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 6345 | 6344 | @setCold(true); |
| 6346 | 6345 | 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); | |
| 6348 | 6347 | return error.CodegenFail; |
| 6349 | 6348 | } |
| 6350 | 6349 | |
| 6351 | 6350 | fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 6352 | 6351 | @setCold(true); |
| 6353 | 6352 | 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); | |
| 6355 | 6354 | return error.CodegenFail; |
| 6356 | 6355 | } |
| 6357 | 6356 | |
| ... | ... | @@ -6363,7 +6362,7 @@ fn parseRegName(name: []const u8) ?Register { |
| 6363 | 6362 | } |
| 6364 | 6363 | |
| 6365 | 6364 | fn registerAlias(self: *Self, reg: Register, ty: Type) Register { |
| 6366 | const mod = self.bin_file.options.module.?; | |
| 6365 | const mod = self.bin_file.comp.module.?; | |
| 6367 | 6366 | const abi_size = ty.abiSize(mod); |
| 6368 | 6367 | |
| 6369 | 6368 | switch (reg.class()) { |
| ... | ... | @@ -6392,11 +6391,11 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register { |
| 6392 | 6391 | } |
| 6393 | 6392 | |
| 6394 | 6393 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 6395 | const mod = self.bin_file.options.module.?; | |
| 6394 | const mod = self.bin_file.comp.module.?; | |
| 6396 | 6395 | return self.air.typeOf(inst, &mod.intern_pool); |
| 6397 | 6396 | } |
| 6398 | 6397 | |
| 6399 | 6398 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 6400 | const mod = self.bin_file.options.module.?; | |
| 6399 | const mod = self.bin_file.comp.module.?; | |
| 6401 | 6400 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 6402 | 6401 | } |
src/arch/aarch64/Emit.zig+17-12| ... | ... | @@ -218,14 +218,16 @@ pub fn emitMir( |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | pub fn deinit(emit: *Emit) void { |
| 221 | const comp = emit.bin_file.comp; | |
| 222 | const gpa = comp.gpa; | |
| 221 | 223 | var iter = emit.branch_forward_origins.valueIterator(); |
| 222 | 224 | while (iter.next()) |origin_list| { |
| 223 | origin_list.deinit(emit.bin_file.allocator); | |
| 225 | origin_list.deinit(gpa); | |
| 224 | 226 | } |
| 225 | 227 | |
| 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); | |
| 229 | 231 | emit.* = undefined; |
| 230 | 232 | } |
| 231 | 233 | |
| ... | ... | @@ -314,8 +316,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index { |
| 314 | 316 | } |
| 315 | 317 | |
| 316 | 318 | fn lowerBranches(emit: *Emit) !void { |
| 319 | const comp = emit.bin_file.comp; | |
| 320 | const gpa = comp.gpa; | |
| 317 | 321 | const mir_tags = emit.mir.instructions.items(.tag); |
| 318 | const allocator = emit.bin_file.allocator; | |
| 319 | 322 | |
| 320 | 323 | // First pass: Note down all branches and their target |
| 321 | 324 | // instructions, i.e. populate branch_types, |
| ... | ... | @@ -329,7 +332,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 329 | 332 | const target_inst = emit.branchTarget(inst); |
| 330 | 333 | |
| 331 | 334 | // 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)); | |
| 333 | 336 | |
| 334 | 337 | // Forward branches require some extra stuff: We only |
| 335 | 338 | // know their offset once we arrive at the target |
| ... | ... | @@ -339,14 +342,14 @@ fn lowerBranches(emit: *Emit) !void { |
| 339 | 342 | // etc. |
| 340 | 343 | if (target_inst > inst) { |
| 341 | 344 | // 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); | |
| 343 | 346 | |
| 344 | 347 | if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { |
| 345 | try origin_list.append(allocator, inst); | |
| 348 | try origin_list.append(gpa, inst); | |
| 346 | 349 | } else { |
| 347 | 350 | 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); | |
| 350 | 353 | } |
| 351 | 354 | } |
| 352 | 355 | |
| ... | ... | @@ -356,7 +359,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 356 | 359 | // putNoClobber may not be used as the put operation |
| 357 | 360 | // may clobber the entry when multiple branches branch |
| 358 | 361 | // 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); | |
| 360 | 363 | } |
| 361 | 364 | } |
| 362 | 365 | |
| ... | ... | @@ -429,7 +432,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { |
| 429 | 432 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 430 | 433 | @setCold(true); |
| 431 | 434 | 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); | |
| 433 | 438 | return error.EmitFail; |
| 434 | 439 | } |
| 435 | 440 |
src/arch/arm/CodeGen.zig+97-96| ... | ... | @@ -260,7 +260,7 @@ const DbgInfoReloc = struct { |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | 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.?; | |
| 264 | 264 | switch (function.debug_output) { |
| 265 | 265 | .dwarf => |dw| { |
| 266 | 266 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) { |
| ... | ... | @@ -289,7 +289,7 @@ const DbgInfoReloc = struct { |
| 289 | 289 | } |
| 290 | 290 | |
| 291 | 291 | fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void { |
| 292 | const mod = function.bin_file.options.module.?; | |
| 292 | const mod = function.bin_file.comp.module.?; | |
| 293 | 293 | const is_ptr = switch (reloc.tag) { |
| 294 | 294 | .dbg_var_ptr => true, |
| 295 | 295 | .dbg_var_val => false, |
| ... | ... | @@ -336,7 +336,7 @@ const DbgInfoReloc = struct { |
| 336 | 336 | const Self = @This(); |
| 337 | 337 | |
| 338 | 338 | pub fn generate( |
| 339 | bin_file: *link.File, | |
| 339 | lf: *link.File, | |
| 340 | 340 | src_loc: Module.SrcLoc, |
| 341 | 341 | func_index: InternPool.Index, |
| 342 | 342 | air: Air, |
| ... | ... | @@ -344,30 +344,29 @@ pub fn generate( |
| 344 | 344 | code: *std.ArrayList(u8), |
| 345 | 345 | debug_output: DebugInfoOutput, |
| 346 | 346 | ) 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); | |
| 354 | 351 | assert(fn_owner_decl.has_tv); |
| 355 | 352 | 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; | |
| 356 | 355 | |
| 357 | var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); | |
| 356 | var branch_stack = std.ArrayList(Branch).init(gpa); | |
| 358 | 357 | defer { |
| 359 | 358 | assert(branch_stack.items.len == 1); |
| 360 | branch_stack.items[0].deinit(bin_file.allocator); | |
| 359 | branch_stack.items[0].deinit(gpa); | |
| 361 | 360 | branch_stack.deinit(); |
| 362 | 361 | } |
| 363 | 362 | try branch_stack.append(.{}); |
| 364 | 363 | |
| 365 | var function = Self{ | |
| 366 | .gpa = bin_file.allocator, | |
| 364 | var function: Self = .{ | |
| 365 | .gpa = gpa, | |
| 367 | 366 | .air = air, |
| 368 | 367 | .liveness = liveness, |
| 369 | .target = &bin_file.options.target, | |
| 370 | .bin_file = bin_file, | |
| 368 | .target = target, | |
| 369 | .bin_file = lf, | |
| 371 | 370 | .debug_output = debug_output, |
| 372 | 371 | .func_index = func_index, |
| 373 | 372 | .err_msg = null, |
| ... | ... | @@ -381,15 +380,15 @@ pub fn generate( |
| 381 | 380 | .end_di_line = func.rbrace_line, |
| 382 | 381 | .end_di_column = func.rbrace_column, |
| 383 | 382 | }; |
| 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); | |
| 388 | 387 | |
| 389 | 388 | var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) { |
| 390 | 389 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 391 | 390 | 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.", .{}), | |
| 393 | 392 | }, |
| 394 | 393 | else => |e| return e, |
| 395 | 394 | }; |
| ... | ... | @@ -403,7 +402,7 @@ pub fn generate( |
| 403 | 402 | function.gen() catch |err| switch (err) { |
| 404 | 403 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 405 | 404 | 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.", .{}), | |
| 407 | 406 | }, |
| 408 | 407 | else => |e| return e, |
| 409 | 408 | }; |
| ... | ... | @@ -414,15 +413,15 @@ pub fn generate( |
| 414 | 413 | |
| 415 | 414 | var mir = Mir{ |
| 416 | 415 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 417 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 416 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 418 | 417 | }; |
| 419 | defer mir.deinit(bin_file.allocator); | |
| 418 | defer mir.deinit(gpa); | |
| 420 | 419 | |
| 421 | 420 | var emit = Emit{ |
| 422 | 421 | .mir = mir, |
| 423 | .bin_file = bin_file, | |
| 422 | .bin_file = lf, | |
| 424 | 423 | .debug_output = debug_output, |
| 425 | .target = &bin_file.options.target, | |
| 424 | .target = target, | |
| 426 | 425 | .src_loc = src_loc, |
| 427 | 426 | .code = code, |
| 428 | 427 | .prev_di_pc = 0, |
| ... | ... | @@ -482,7 +481,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 482 | 481 | } |
| 483 | 482 | |
| 484 | 483 | fn gen(self: *Self) !void { |
| 485 | const mod = self.bin_file.options.module.?; | |
| 484 | const mod = self.bin_file.comp.module.?; | |
| 486 | 485 | const cc = self.fn_type.fnCallingConvention(mod); |
| 487 | 486 | if (cc != .Naked) { |
| 488 | 487 | // push {fp, lr} |
| ... | ... | @@ -642,7 +641,7 @@ fn gen(self: *Self) !void { |
| 642 | 641 | } |
| 643 | 642 | |
| 644 | 643 | fn 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.?; | |
| 646 | 645 | const ip = &mod.intern_pool; |
| 647 | 646 | const air_tags = self.air.instructions.items(.tag); |
| 648 | 647 | |
| ... | ... | @@ -1010,7 +1009,7 @@ fn allocMem( |
| 1010 | 1009 | |
| 1011 | 1010 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 1012 | 1011 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1013 | const mod = self.bin_file.options.module.?; | |
| 1012 | const mod = self.bin_file.comp.module.?; | |
| 1014 | 1013 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 1015 | 1014 | |
| 1016 | 1015 | if (!elem_ty.hasRuntimeBits(mod)) { |
| ... | ... | @@ -1031,7 +1030,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 1031 | 1030 | } |
| 1032 | 1031 | |
| 1033 | 1032 | fn 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.?; | |
| 1035 | 1034 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { |
| 1036 | 1035 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); |
| 1037 | 1036 | }; |
| ... | ... | @@ -1118,7 +1117,7 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { |
| 1118 | 1117 | } |
| 1119 | 1118 | |
| 1120 | 1119 | fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1121 | const mod = self.bin_file.options.module.?; | |
| 1120 | const mod = self.bin_file.comp.module.?; | |
| 1122 | 1121 | const result: MCValue = switch (self.ret_mcv) { |
| 1123 | 1122 | .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, |
| 1124 | 1123 | .stack_offset => blk: { |
| ... | ... | @@ -1151,7 +1150,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 1151 | 1150 | } |
| 1152 | 1151 | |
| 1153 | 1152 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1154 | const mod = self.bin_file.options.module.?; | |
| 1153 | const mod = self.bin_file.comp.module.?; | |
| 1155 | 1154 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1156 | 1155 | if (self.liveness.isUnused(inst)) |
| 1157 | 1156 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| ... | ... | @@ -1217,7 +1216,7 @@ fn trunc( |
| 1217 | 1216 | operand_ty: Type, |
| 1218 | 1217 | dest_ty: Type, |
| 1219 | 1218 | ) !MCValue { |
| 1220 | const mod = self.bin_file.options.module.?; | |
| 1219 | const mod = self.bin_file.comp.module.?; | |
| 1221 | 1220 | const info_a = operand_ty.intInfo(mod); |
| 1222 | 1221 | const info_b = dest_ty.intInfo(mod); |
| 1223 | 1222 | |
| ... | ... | @@ -1281,7 +1280,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 1281 | 1280 | |
| 1282 | 1281 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 1283 | 1282 | 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.?; | |
| 1285 | 1284 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1286 | 1285 | const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand }; |
| 1287 | 1286 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -1377,7 +1376,7 @@ fn minMax( |
| 1377 | 1376 | rhs_ty: Type, |
| 1378 | 1377 | maybe_inst: ?Air.Inst.Index, |
| 1379 | 1378 | ) !MCValue { |
| 1380 | const mod = self.bin_file.options.module.?; | |
| 1379 | const mod = self.bin_file.comp.module.?; | |
| 1381 | 1380 | switch (lhs_ty.zigTypeTag(mod)) { |
| 1382 | 1381 | .Float => return self.fail("TODO ARM min/max on floats", .{}), |
| 1383 | 1382 | .Vector => return self.fail("TODO ARM min/max on vectors", .{}), |
| ... | ... | @@ -1586,7 +1585,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1586 | 1585 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 1587 | 1586 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1588 | 1587 | 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.?; | |
| 1590 | 1589 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1591 | 1590 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1592 | 1591 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -1699,7 +1698,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1699 | 1698 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1700 | 1699 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1701 | 1700 | 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.?; | |
| 1703 | 1702 | const result: MCValue = result: { |
| 1704 | 1703 | const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs }; |
| 1705 | 1704 | const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs }; |
| ... | ... | @@ -1863,7 +1862,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1863 | 1862 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 1864 | 1863 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 1865 | 1864 | 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.?; | |
| 1867 | 1866 | const result: MCValue = result: { |
| 1868 | 1867 | const lhs_ty = self.typeOf(extra.lhs); |
| 1869 | 1868 | const rhs_ty = self.typeOf(extra.rhs); |
| ... | ... | @@ -2019,7 +2018,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 2019 | 2018 | } |
| 2020 | 2019 | |
| 2021 | 2020 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2022 | const mod = self.bin_file.options.module.?; | |
| 2021 | const mod = self.bin_file.comp.module.?; | |
| 2023 | 2022 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2024 | 2023 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2025 | 2024 | const optional_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -2042,7 +2041,7 @@ fn errUnionErr( |
| 2042 | 2041 | error_union_ty: Type, |
| 2043 | 2042 | maybe_inst: ?Air.Inst.Index, |
| 2044 | 2043 | ) !MCValue { |
| 2045 | const mod = self.bin_file.options.module.?; | |
| 2044 | const mod = self.bin_file.comp.module.?; | |
| 2046 | 2045 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 2047 | 2046 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2048 | 2047 | if (err_ty.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -2119,7 +2118,7 @@ fn errUnionPayload( |
| 2119 | 2118 | error_union_ty: Type, |
| 2120 | 2119 | maybe_inst: ?Air.Inst.Index, |
| 2121 | 2120 | ) !MCValue { |
| 2122 | const mod = self.bin_file.options.module.?; | |
| 2121 | const mod = self.bin_file.comp.module.?; | |
| 2123 | 2122 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 2124 | 2123 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 2125 | 2124 | if (err_ty.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -2229,7 +2228,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 2229 | 2228 | |
| 2230 | 2229 | /// T to E!T |
| 2231 | 2230 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2232 | const mod = self.bin_file.options.module.?; | |
| 2231 | const mod = self.bin_file.comp.module.?; | |
| 2233 | 2232 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2234 | 2233 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2235 | 2234 | const error_union_ty = ty_op.ty.toType(); |
| ... | ... | @@ -2253,7 +2252,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2253 | 2252 | |
| 2254 | 2253 | /// E to E!T |
| 2255 | 2254 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2256 | const mod = self.bin_file.options.module.?; | |
| 2255 | const mod = self.bin_file.comp.module.?; | |
| 2257 | 2256 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2258 | 2257 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2259 | 2258 | const error_union_ty = ty_op.ty.toType(); |
| ... | ... | @@ -2370,7 +2369,7 @@ fn ptrElemVal( |
| 2370 | 2369 | ptr_ty: Type, |
| 2371 | 2370 | maybe_inst: ?Air.Inst.Index, |
| 2372 | 2371 | ) !MCValue { |
| 2373 | const mod = self.bin_file.options.module.?; | |
| 2372 | const mod = self.bin_file.comp.module.?; | |
| 2374 | 2373 | const elem_ty = ptr_ty.childType(mod); |
| 2375 | 2374 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); |
| 2376 | 2375 | |
| ... | ... | @@ -2429,7 +2428,7 @@ fn ptrElemVal( |
| 2429 | 2428 | } |
| 2430 | 2429 | |
| 2431 | 2430 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2432 | const mod = self.bin_file.options.module.?; | |
| 2431 | const mod = self.bin_file.comp.module.?; | |
| 2433 | 2432 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2434 | 2433 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2435 | 2434 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -2472,7 +2471,7 @@ fn arrayElemVal( |
| 2472 | 2471 | array_ty: Type, |
| 2473 | 2472 | maybe_inst: ?Air.Inst.Index, |
| 2474 | 2473 | ) InnerError!MCValue { |
| 2475 | const mod = self.bin_file.options.module.?; | |
| 2474 | const mod = self.bin_file.comp.module.?; | |
| 2476 | 2475 | const elem_ty = array_ty.childType(mod); |
| 2477 | 2476 | |
| 2478 | 2477 | const mcv = try array_bind.resolveToMcv(self); |
| ... | ... | @@ -2528,7 +2527,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2528 | 2527 | } |
| 2529 | 2528 | |
| 2530 | 2529 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2531 | const mod = self.bin_file.options.module.?; | |
| 2530 | const mod = self.bin_file.comp.module.?; | |
| 2532 | 2531 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2533 | 2532 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 2534 | 2533 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -2662,7 +2661,7 @@ fn reuseOperand( |
| 2662 | 2661 | } |
| 2663 | 2662 | |
| 2664 | 2663 | fn 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.?; | |
| 2666 | 2665 | const elem_ty = ptr_ty.childType(mod); |
| 2667 | 2666 | const elem_size: u32 = @intCast(elem_ty.abiSize(mod)); |
| 2668 | 2667 | |
| ... | ... | @@ -2739,7 +2738,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2739 | 2738 | } |
| 2740 | 2739 | |
| 2741 | 2740 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2742 | const mod = self.bin_file.options.module.?; | |
| 2741 | const mod = self.bin_file.comp.module.?; | |
| 2743 | 2742 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2744 | 2743 | const elem_ty = self.typeOfIndex(inst); |
| 2745 | 2744 | const result: MCValue = result: { |
| ... | ... | @@ -2768,7 +2767,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2768 | 2767 | } |
| 2769 | 2768 | |
| 2770 | 2769 | fn 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.?; | |
| 2772 | 2771 | const elem_size: u32 = @intCast(value_ty.abiSize(mod)); |
| 2773 | 2772 | |
| 2774 | 2773 | switch (ptr) { |
| ... | ... | @@ -2888,7 +2887,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 2888 | 2887 | |
| 2889 | 2888 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 2890 | 2889 | 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.?; | |
| 2892 | 2891 | const mcv = try self.resolveInst(operand); |
| 2893 | 2892 | const ptr_ty = self.typeOf(operand); |
| 2894 | 2893 | const struct_ty = ptr_ty.childType(mod); |
| ... | ... | @@ -2912,7 +2911,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2912 | 2911 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 2913 | 2912 | const operand = extra.struct_operand; |
| 2914 | 2913 | const index = extra.field_index; |
| 2915 | const mod = self.bin_file.options.module.?; | |
| 2914 | const mod = self.bin_file.comp.module.?; | |
| 2916 | 2915 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2917 | 2916 | const mcv = try self.resolveInst(operand); |
| 2918 | 2917 | const struct_ty = self.typeOf(operand); |
| ... | ... | @@ -3002,7 +3001,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3002 | 3001 | } |
| 3003 | 3002 | |
| 3004 | 3003 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3005 | const mod = self.bin_file.options.module.?; | |
| 3004 | const mod = self.bin_file.comp.module.?; | |
| 3006 | 3005 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3007 | 3006 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 3008 | 3007 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| ... | ... | @@ -3396,7 +3395,7 @@ fn addSub( |
| 3396 | 3395 | rhs_ty: Type, |
| 3397 | 3396 | maybe_inst: ?Air.Inst.Index, |
| 3398 | 3397 | ) InnerError!MCValue { |
| 3399 | const mod = self.bin_file.options.module.?; | |
| 3398 | const mod = self.bin_file.comp.module.?; | |
| 3400 | 3399 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3401 | 3400 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3402 | 3401 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3452,7 +3451,7 @@ fn mul( |
| 3452 | 3451 | rhs_ty: Type, |
| 3453 | 3452 | maybe_inst: ?Air.Inst.Index, |
| 3454 | 3453 | ) InnerError!MCValue { |
| 3455 | const mod = self.bin_file.options.module.?; | |
| 3454 | const mod = self.bin_file.comp.module.?; | |
| 3456 | 3455 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3457 | 3456 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3458 | 3457 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3485,7 +3484,7 @@ fn divFloat( |
| 3485 | 3484 | _ = rhs_ty; |
| 3486 | 3485 | _ = maybe_inst; |
| 3487 | 3486 | |
| 3488 | const mod = self.bin_file.options.module.?; | |
| 3487 | const mod = self.bin_file.comp.module.?; | |
| 3489 | 3488 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3490 | 3489 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3491 | 3490 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3501,7 +3500,7 @@ fn divTrunc( |
| 3501 | 3500 | rhs_ty: Type, |
| 3502 | 3501 | maybe_inst: ?Air.Inst.Index, |
| 3503 | 3502 | ) InnerError!MCValue { |
| 3504 | const mod = self.bin_file.options.module.?; | |
| 3503 | const mod = self.bin_file.comp.module.?; | |
| 3505 | 3504 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3506 | 3505 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3507 | 3506 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3544,7 +3543,7 @@ fn divFloor( |
| 3544 | 3543 | rhs_ty: Type, |
| 3545 | 3544 | maybe_inst: ?Air.Inst.Index, |
| 3546 | 3545 | ) InnerError!MCValue { |
| 3547 | const mod = self.bin_file.options.module.?; | |
| 3546 | const mod = self.bin_file.comp.module.?; | |
| 3548 | 3547 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3549 | 3548 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3550 | 3549 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3592,7 +3591,7 @@ fn divExact( |
| 3592 | 3591 | _ = rhs_ty; |
| 3593 | 3592 | _ = maybe_inst; |
| 3594 | 3593 | |
| 3595 | const mod = self.bin_file.options.module.?; | |
| 3594 | const mod = self.bin_file.comp.module.?; | |
| 3596 | 3595 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3597 | 3596 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3598 | 3597 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3609,7 +3608,7 @@ fn rem( |
| 3609 | 3608 | rhs_ty: Type, |
| 3610 | 3609 | maybe_inst: ?Air.Inst.Index, |
| 3611 | 3610 | ) InnerError!MCValue { |
| 3612 | const mod = self.bin_file.options.module.?; | |
| 3611 | const mod = self.bin_file.comp.module.?; | |
| 3613 | 3612 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3614 | 3613 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3615 | 3614 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3678,7 +3677,7 @@ fn modulo( |
| 3678 | 3677 | _ = rhs_ty; |
| 3679 | 3678 | _ = maybe_inst; |
| 3680 | 3679 | |
| 3681 | const mod = self.bin_file.options.module.?; | |
| 3680 | const mod = self.bin_file.comp.module.?; | |
| 3682 | 3681 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3683 | 3682 | .Float => return self.fail("TODO ARM binary operations on floats", .{}), |
| 3684 | 3683 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| ... | ... | @@ -3696,7 +3695,7 @@ fn wrappingArithmetic( |
| 3696 | 3695 | rhs_ty: Type, |
| 3697 | 3696 | maybe_inst: ?Air.Inst.Index, |
| 3698 | 3697 | ) InnerError!MCValue { |
| 3699 | const mod = self.bin_file.options.module.?; | |
| 3698 | const mod = self.bin_file.comp.module.?; | |
| 3700 | 3699 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3701 | 3700 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3702 | 3701 | .Int => { |
| ... | ... | @@ -3734,7 +3733,7 @@ fn bitwise( |
| 3734 | 3733 | rhs_ty: Type, |
| 3735 | 3734 | maybe_inst: ?Air.Inst.Index, |
| 3736 | 3735 | ) InnerError!MCValue { |
| 3737 | const mod = self.bin_file.options.module.?; | |
| 3736 | const mod = self.bin_file.comp.module.?; | |
| 3738 | 3737 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3739 | 3738 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3740 | 3739 | .Int => { |
| ... | ... | @@ -3779,7 +3778,7 @@ fn shiftExact( |
| 3779 | 3778 | rhs_ty: Type, |
| 3780 | 3779 | maybe_inst: ?Air.Inst.Index, |
| 3781 | 3780 | ) InnerError!MCValue { |
| 3782 | const mod = self.bin_file.options.module.?; | |
| 3781 | const mod = self.bin_file.comp.module.?; | |
| 3783 | 3782 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3784 | 3783 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3785 | 3784 | .Int => { |
| ... | ... | @@ -3818,7 +3817,7 @@ fn shiftNormal( |
| 3818 | 3817 | rhs_ty: Type, |
| 3819 | 3818 | maybe_inst: ?Air.Inst.Index, |
| 3820 | 3819 | ) InnerError!MCValue { |
| 3821 | const mod = self.bin_file.options.module.?; | |
| 3820 | const mod = self.bin_file.comp.module.?; | |
| 3822 | 3821 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3823 | 3822 | .Vector => return self.fail("TODO ARM binary operations on vectors", .{}), |
| 3824 | 3823 | .Int => { |
| ... | ... | @@ -3861,7 +3860,7 @@ fn booleanOp( |
| 3861 | 3860 | rhs_ty: Type, |
| 3862 | 3861 | maybe_inst: ?Air.Inst.Index, |
| 3863 | 3862 | ) InnerError!MCValue { |
| 3864 | const mod = self.bin_file.options.module.?; | |
| 3863 | const mod = self.bin_file.comp.module.?; | |
| 3865 | 3864 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3866 | 3865 | .Bool => { |
| 3867 | 3866 | const lhs_immediate = try lhs_bind.resolveToImmediate(self); |
| ... | ... | @@ -3895,7 +3894,7 @@ fn ptrArithmetic( |
| 3895 | 3894 | rhs_ty: Type, |
| 3896 | 3895 | maybe_inst: ?Air.Inst.Index, |
| 3897 | 3896 | ) InnerError!MCValue { |
| 3898 | const mod = self.bin_file.options.module.?; | |
| 3897 | const mod = self.bin_file.comp.module.?; | |
| 3899 | 3898 | switch (lhs_ty.zigTypeTag(mod)) { |
| 3900 | 3899 | .Pointer => { |
| 3901 | 3900 | assert(rhs_ty.eql(Type.usize, mod)); |
| ... | ... | @@ -3932,7 +3931,7 @@ fn ptrArithmetic( |
| 3932 | 3931 | } |
| 3933 | 3932 | |
| 3934 | 3933 | fn 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.?; | |
| 3936 | 3935 | const abi_size = ty.abiSize(mod); |
| 3937 | 3936 | |
| 3938 | 3937 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| ... | ... | @@ -3967,7 +3966,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) |
| 3967 | 3966 | } |
| 3968 | 3967 | |
| 3969 | 3968 | fn 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.?; | |
| 3971 | 3970 | const abi_size = ty.abiSize(mod); |
| 3972 | 3971 | |
| 3973 | 3972 | const tag: Mir.Inst.Tag = switch (abi_size) { |
| ... | ... | @@ -4174,7 +4173,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4174 | 4173 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4175 | 4174 | self.arg_index = arg_index + 1; |
| 4176 | 4175 | |
| 4177 | const mod = self.bin_file.options.module.?; | |
| 4176 | const mod = self.bin_file.comp.module.?; | |
| 4178 | 4177 | const ty = self.typeOfIndex(inst); |
| 4179 | 4178 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 4180 | 4179 | 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 |
| 4229 | 4228 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 4230 | 4229 | const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]); |
| 4231 | 4230 | const ty = self.typeOf(callee); |
| 4232 | const mod = self.bin_file.options.module.?; | |
| 4231 | const mod = self.bin_file.comp.module.?; | |
| 4233 | 4232 | |
| 4234 | 4233 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 4235 | 4234 | .Fn => ty, |
| ... | ... | @@ -4380,7 +4379,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4380 | 4379 | } |
| 4381 | 4380 | |
| 4382 | 4381 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4383 | const mod = self.bin_file.options.module.?; | |
| 4382 | const mod = self.bin_file.comp.module.?; | |
| 4384 | 4383 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4385 | 4384 | const operand = try self.resolveInst(un_op); |
| 4386 | 4385 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | ... | @@ -4412,7 +4411,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4412 | 4411 | } |
| 4413 | 4412 | |
| 4414 | 4413 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4415 | const mod = self.bin_file.options.module.?; | |
| 4414 | const mod = self.bin_file.comp.module.?; | |
| 4416 | 4415 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4417 | 4416 | const ptr = try self.resolveInst(un_op); |
| 4418 | 4417 | const ptr_ty = self.typeOf(un_op); |
| ... | ... | @@ -4473,7 +4472,7 @@ fn cmp( |
| 4473 | 4472 | lhs_ty: Type, |
| 4474 | 4473 | op: math.CompareOperator, |
| 4475 | 4474 | ) !MCValue { |
| 4476 | const mod = self.bin_file.options.module.?; | |
| 4475 | const mod = self.bin_file.comp.module.?; | |
| 4477 | 4476 | const int_ty = switch (lhs_ty.zigTypeTag(mod)) { |
| 4478 | 4477 | .Optional => blk: { |
| 4479 | 4478 | const payload_ty = lhs_ty.optionalChild(mod); |
| ... | ... | @@ -4580,7 +4579,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 4580 | 4579 | |
| 4581 | 4580 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 4582 | 4581 | 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.?; | |
| 4584 | 4583 | const func = mod.funcInfo(ty_fn.func); |
| 4585 | 4584 | // TODO emit debug info for function change |
| 4586 | 4585 | _ = func; |
| ... | ... | @@ -4795,7 +4794,7 @@ fn isNull( |
| 4795 | 4794 | operand_bind: ReadArg.Bind, |
| 4796 | 4795 | operand_ty: Type, |
| 4797 | 4796 | ) !MCValue { |
| 4798 | const mod = self.bin_file.options.module.?; | |
| 4797 | const mod = self.bin_file.comp.module.?; | |
| 4799 | 4798 | if (operand_ty.isPtrLikeOptional(mod)) { |
| 4800 | 4799 | assert(operand_ty.abiSize(mod) == 4); |
| 4801 | 4800 | |
| ... | ... | @@ -4829,7 +4828,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4829 | 4828 | } |
| 4830 | 4829 | |
| 4831 | 4830 | fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4832 | const mod = self.bin_file.options.module.?; | |
| 4831 | const mod = self.bin_file.comp.module.?; | |
| 4833 | 4832 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4834 | 4833 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4835 | 4834 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -4856,7 +4855,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 4856 | 4855 | } |
| 4857 | 4856 | |
| 4858 | 4857 | fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4859 | const mod = self.bin_file.options.module.?; | |
| 4858 | const mod = self.bin_file.comp.module.?; | |
| 4860 | 4859 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4861 | 4860 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4862 | 4861 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -4876,7 +4875,7 @@ fn isErr( |
| 4876 | 4875 | error_union_bind: ReadArg.Bind, |
| 4877 | 4876 | error_union_ty: Type, |
| 4878 | 4877 | ) !MCValue { |
| 4879 | const mod = self.bin_file.options.module.?; | |
| 4878 | const mod = self.bin_file.comp.module.?; | |
| 4880 | 4879 | const error_type = error_union_ty.errorUnionSet(mod); |
| 4881 | 4880 | |
| 4882 | 4881 | if (error_type.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -4918,7 +4917,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4918 | 4917 | } |
| 4919 | 4918 | |
| 4920 | 4919 | fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4921 | const mod = self.bin_file.options.module.?; | |
| 4920 | const mod = self.bin_file.comp.module.?; | |
| 4922 | 4921 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4923 | 4922 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4924 | 4923 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -4945,7 +4944,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4945 | 4944 | } |
| 4946 | 4945 | |
| 4947 | 4946 | fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4948 | const mod = self.bin_file.options.module.?; | |
| 4947 | const mod = self.bin_file.comp.module.?; | |
| 4949 | 4948 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4950 | 4949 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 4951 | 4950 | const operand_ptr = try self.resolveInst(un_op); |
| ... | ... | @@ -5160,7 +5159,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 5160 | 5159 | } |
| 5161 | 5160 | |
| 5162 | 5161 | fn 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.?; | |
| 5164 | 5163 | const block_data = self.blocks.getPtr(block).?; |
| 5165 | 5164 | |
| 5166 | 5165 | if (self.typeOf(operand).hasRuntimeBits(mod)) { |
| ... | ... | @@ -5331,7 +5330,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void { |
| 5331 | 5330 | } |
| 5332 | 5331 | |
| 5333 | 5332 | fn 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.?; | |
| 5335 | 5334 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 5336 | 5335 | switch (mcv) { |
| 5337 | 5336 | .dead => unreachable, |
| ... | ... | @@ -5493,7 +5492,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 5493 | 5492 | } |
| 5494 | 5493 | |
| 5495 | 5494 | fn 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.?; | |
| 5497 | 5496 | switch (mcv) { |
| 5498 | 5497 | .dead => unreachable, |
| 5499 | 5498 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -5740,7 +5739,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5740 | 5739 | } |
| 5741 | 5740 | |
| 5742 | 5741 | fn 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.?; | |
| 5744 | 5743 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 5745 | 5744 | switch (mcv) { |
| 5746 | 5745 | .dead => unreachable, |
| ... | ... | @@ -5896,7 +5895,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 5896 | 5895 | } |
| 5897 | 5896 | |
| 5898 | 5897 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 5899 | const mod = self.bin_file.options.module.?; | |
| 5898 | const mod = self.bin_file.comp.module.?; | |
| 5900 | 5899 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5901 | 5900 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 5902 | 5901 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -6015,7 +6014,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 6015 | 6014 | } |
| 6016 | 6015 | |
| 6017 | 6016 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 6018 | const mod = self.bin_file.options.module.?; | |
| 6017 | const mod = self.bin_file.comp.module.?; | |
| 6019 | 6018 | const vector_ty = self.typeOfIndex(inst); |
| 6020 | 6019 | const len = vector_ty.vectorLen(mod); |
| 6021 | 6020 | 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 { |
| 6066 | 6065 | const result: MCValue = result: { |
| 6067 | 6066 | const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand }; |
| 6068 | 6067 | 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.?; | |
| 6070 | 6069 | const error_union_size: u32 = @intCast(error_union_ty.abiSize(mod)); |
| 6071 | 6070 | const error_union_align = error_union_ty.abiAlignment(mod); |
| 6072 | 6071 | |
| ... | ... | @@ -6097,7 +6096,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 6097 | 6096 | } |
| 6098 | 6097 | |
| 6099 | 6098 | fn 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.?; | |
| 6101 | 6100 | |
| 6102 | 6101 | // If the type has no codegen bits, no need to store it. |
| 6103 | 6102 | const inst_ty = self.typeOf(inst); |
| ... | ... | @@ -6125,7 +6124,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 6125 | 6124 | } |
| 6126 | 6125 | |
| 6127 | 6126 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 6128 | const mod = self.bin_file.options.module.?; | |
| 6127 | const mod = self.bin_file.comp.module.?; | |
| 6129 | 6128 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 6130 | 6129 | self.bin_file, |
| 6131 | 6130 | self.src_loc, |
| ... | ... | @@ -6161,7 +6160,7 @@ const CallMCValues = struct { |
| 6161 | 6160 | |
| 6162 | 6161 | /// Caller must call `CallMCValues.deinit`. |
| 6163 | 6162 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6164 | const mod = self.bin_file.options.module.?; | |
| 6163 | const mod = self.bin_file.comp.module.?; | |
| 6165 | 6164 | const ip = &mod.intern_pool; |
| 6166 | 6165 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 6167 | 6166 | const cc = fn_info.cc; |
| ... | ... | @@ -6282,7 +6281,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6282 | 6281 | |
| 6283 | 6282 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. |
| 6284 | 6283 | fn wantSafety(self: *Self) bool { |
| 6285 | return switch (self.bin_file.options.optimize_mode) { | |
| 6284 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | |
| 6286 | 6285 | .Debug => true, |
| 6287 | 6286 | .ReleaseSafe => true, |
| 6288 | 6287 | .ReleaseFast => false, |
| ... | ... | @@ -6293,14 +6292,16 @@ fn wantSafety(self: *Self) bool { |
| 6293 | 6292 | fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 6294 | 6293 | @setCold(true); |
| 6295 | 6294 | 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); | |
| 6297 | 6297 | return error.CodegenFail; |
| 6298 | 6298 | } |
| 6299 | 6299 | |
| 6300 | 6300 | fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 6301 | 6301 | @setCold(true); |
| 6302 | 6302 | 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); | |
| 6304 | 6305 | return error.CodegenFail; |
| 6305 | 6306 | } |
| 6306 | 6307 | |
| ... | ... | @@ -6312,11 +6313,11 @@ fn parseRegName(name: []const u8) ?Register { |
| 6312 | 6313 | } |
| 6313 | 6314 | |
| 6314 | 6315 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 6315 | const mod = self.bin_file.options.module.?; | |
| 6316 | const mod = self.bin_file.comp.module.?; | |
| 6316 | 6317 | return self.air.typeOf(inst, &mod.intern_pool); |
| 6317 | 6318 | } |
| 6318 | 6319 | |
| 6319 | 6320 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 6320 | const mod = self.bin_file.options.module.?; | |
| 6321 | const mod = self.bin_file.comp.module.?; | |
| 6321 | 6322 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 6322 | 6323 | } |
src/arch/arm/Emit.zig+18-12| ... | ... | @@ -152,14 +152,17 @@ pub fn emitMir( |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | pub fn deinit(emit: *Emit) void { |
| 155 | const comp = emit.bin_file.comp; | |
| 156 | const gpa = comp.gpa; | |
| 157 | ||
| 155 | 158 | var iter = emit.branch_forward_origins.valueIterator(); |
| 156 | 159 | while (iter.next()) |origin_list| { |
| 157 | origin_list.deinit(emit.bin_file.allocator); | |
| 160 | origin_list.deinit(gpa); | |
| 158 | 161 | } |
| 159 | 162 | |
| 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); | |
| 163 | 166 | emit.* = undefined; |
| 164 | 167 | } |
| 165 | 168 | |
| ... | ... | @@ -231,8 +234,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index { |
| 231 | 234 | } |
| 232 | 235 | |
| 233 | 236 | fn lowerBranches(emit: *Emit) !void { |
| 237 | const comp = emit.bin_file.comp; | |
| 238 | const gpa = comp.gpa; | |
| 234 | 239 | const mir_tags = emit.mir.instructions.items(.tag); |
| 235 | const allocator = emit.bin_file.allocator; | |
| 236 | 240 | |
| 237 | 241 | // First pass: Note down all branches and their target |
| 238 | 242 | // instructions, i.e. populate branch_types, |
| ... | ... | @@ -246,7 +250,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 246 | 250 | const target_inst = emit.branchTarget(inst); |
| 247 | 251 | |
| 248 | 252 | // 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)); | |
| 250 | 254 | |
| 251 | 255 | // Forward branches require some extra stuff: We only |
| 252 | 256 | // know their offset once we arrive at the target |
| ... | ... | @@ -256,14 +260,14 @@ fn lowerBranches(emit: *Emit) !void { |
| 256 | 260 | // etc. |
| 257 | 261 | if (target_inst > inst) { |
| 258 | 262 | // 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); | |
| 260 | 264 | |
| 261 | 265 | if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { |
| 262 | try origin_list.append(allocator, inst); | |
| 266 | try origin_list.append(gpa, inst); | |
| 263 | 267 | } else { |
| 264 | 268 | 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); | |
| 267 | 271 | } |
| 268 | 272 | } |
| 269 | 273 | |
| ... | ... | @@ -273,7 +277,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 273 | 277 | // putNoClobber may not be used as the put operation |
| 274 | 278 | // may clobber the entry when multiple branches branch |
| 275 | 279 | // 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); | |
| 277 | 281 | } |
| 278 | 282 | } |
| 279 | 283 | |
| ... | ... | @@ -346,7 +350,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { |
| 346 | 350 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 347 | 351 | @setCold(true); |
| 348 | 352 | 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); | |
| 350 | 356 | return error.EmitFail; |
| 351 | 357 | } |
| 352 | 358 |
src/arch/riscv64/CodeGen.zig+45-46| ... | ... | @@ -217,7 +217,7 @@ const BigTomb = struct { |
| 217 | 217 | const Self = @This(); |
| 218 | 218 | |
| 219 | 219 | pub fn generate( |
| 220 | bin_file: *link.File, | |
| 220 | lf: *link.File, | |
| 221 | 221 | src_loc: Module.SrcLoc, |
| 222 | 222 | func_index: InternPool.Index, |
| 223 | 223 | air: Air, |
| ... | ... | @@ -225,30 +225,29 @@ pub fn generate( |
| 225 | 225 | code: *std.ArrayList(u8), |
| 226 | 226 | debug_output: DebugInfoOutput, |
| 227 | 227 | ) 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); | |
| 235 | 232 | assert(fn_owner_decl.has_tv); |
| 236 | 233 | 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; | |
| 237 | 236 | |
| 238 | var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); | |
| 237 | var branch_stack = std.ArrayList(Branch).init(gpa); | |
| 239 | 238 | defer { |
| 240 | 239 | assert(branch_stack.items.len == 1); |
| 241 | branch_stack.items[0].deinit(bin_file.allocator); | |
| 240 | branch_stack.items[0].deinit(gpa); | |
| 242 | 241 | branch_stack.deinit(); |
| 243 | 242 | } |
| 244 | 243 | try branch_stack.append(.{}); |
| 245 | 244 | |
| 246 | 245 | var function = Self{ |
| 247 | .gpa = bin_file.allocator, | |
| 246 | .gpa = gpa, | |
| 248 | 247 | .air = air, |
| 249 | 248 | .liveness = liveness, |
| 250 | .target = &bin_file.options.target, | |
| 251 | .bin_file = bin_file, | |
| 249 | .target = target, | |
| 250 | .bin_file = lf, | |
| 252 | 251 | .func_index = func_index, |
| 253 | 252 | .code = code, |
| 254 | 253 | .debug_output = debug_output, |
| ... | ... | @@ -263,14 +262,14 @@ pub fn generate( |
| 263 | 262 | .end_di_line = func.rbrace_line, |
| 264 | 263 | .end_di_column = func.rbrace_column, |
| 265 | 264 | }; |
| 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); | |
| 269 | 268 | |
| 270 | 269 | var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) { |
| 271 | 270 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 272 | 271 | 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.", .{}), | |
| 274 | 273 | }, |
| 275 | 274 | else => |e| return e, |
| 276 | 275 | }; |
| ... | ... | @@ -284,22 +283,22 @@ pub fn generate( |
| 284 | 283 | function.gen() catch |err| switch (err) { |
| 285 | 284 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 286 | 285 | 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.", .{}), | |
| 288 | 287 | }, |
| 289 | 288 | else => |e| return e, |
| 290 | 289 | }; |
| 291 | 290 | |
| 292 | 291 | var mir = Mir{ |
| 293 | 292 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 294 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 293 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 295 | 294 | }; |
| 296 | defer mir.deinit(bin_file.allocator); | |
| 295 | defer mir.deinit(gpa); | |
| 297 | 296 | |
| 298 | 297 | var emit = Emit{ |
| 299 | 298 | .mir = mir, |
| 300 | .bin_file = bin_file, | |
| 299 | .bin_file = lf, | |
| 301 | 300 | .debug_output = debug_output, |
| 302 | .target = &bin_file.options.target, | |
| 301 | .target = target, | |
| 303 | 302 | .src_loc = src_loc, |
| 304 | 303 | .code = code, |
| 305 | 304 | .prev_di_pc = 0, |
| ... | ... | @@ -350,7 +349,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 { |
| 350 | 349 | } |
| 351 | 350 | |
| 352 | 351 | fn gen(self: *Self) !void { |
| 353 | const mod = self.bin_file.options.module.?; | |
| 352 | const mod = self.bin_file.comp.module.?; | |
| 354 | 353 | const cc = self.fn_type.fnCallingConvention(mod); |
| 355 | 354 | if (cc != .Naked) { |
| 356 | 355 | // TODO Finish function prologue and epilogue for riscv64. |
| ... | ... | @@ -474,7 +473,7 @@ fn gen(self: *Self) !void { |
| 474 | 473 | } |
| 475 | 474 | |
| 476 | 475 | fn 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.?; | |
| 478 | 477 | const ip = &mod.intern_pool; |
| 479 | 478 | const air_tags = self.air.instructions.items(.tag); |
| 480 | 479 | |
| ... | ... | @@ -805,7 +804,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme |
| 805 | 804 | |
| 806 | 805 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 807 | 806 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 808 | const mod = self.bin_file.options.module.?; | |
| 807 | const mod = self.bin_file.comp.module.?; | |
| 809 | 808 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 810 | 809 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { |
| 811 | 810 | 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 { |
| 816 | 815 | } |
| 817 | 816 | |
| 818 | 817 | fn 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.?; | |
| 820 | 819 | const elem_ty = self.typeOfIndex(inst); |
| 821 | 820 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { |
| 822 | 821 | 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 { |
| 893 | 892 | if (self.liveness.isUnused(inst)) |
| 894 | 893 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 895 | 894 | |
| 896 | const mod = self.bin_file.options.module.?; | |
| 895 | const mod = self.bin_file.comp.module.?; | |
| 897 | 896 | const operand_ty = self.typeOf(ty_op.operand); |
| 898 | 897 | const operand = try self.resolveInst(ty_op.operand); |
| 899 | 898 | const info_a = operand_ty.intInfo(mod); |
| ... | ... | @@ -1069,7 +1068,7 @@ fn binOp( |
| 1069 | 1068 | lhs_ty: Type, |
| 1070 | 1069 | rhs_ty: Type, |
| 1071 | 1070 | ) InnerError!MCValue { |
| 1072 | const mod = self.bin_file.options.module.?; | |
| 1071 | const mod = self.bin_file.comp.module.?; | |
| 1073 | 1072 | switch (tag) { |
| 1074 | 1073 | // Arithmetic operations on integers and floats |
| 1075 | 1074 | .add, |
| ... | ... | @@ -1332,7 +1331,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 1332 | 1331 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 1333 | 1332 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1334 | 1333 | 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.?; | |
| 1336 | 1335 | const optional_ty = self.typeOfIndex(inst); |
| 1337 | 1336 | |
| 1338 | 1337 | // 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 |
| 1506 | 1505 | } |
| 1507 | 1506 | |
| 1508 | 1507 | fn 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.?; | |
| 1510 | 1509 | const elem_ty = ptr_ty.childType(mod); |
| 1511 | 1510 | switch (ptr) { |
| 1512 | 1511 | .none => unreachable, |
| ... | ... | @@ -1532,7 +1531,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1532 | 1531 | } |
| 1533 | 1532 | |
| 1534 | 1533 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1535 | const mod = self.bin_file.options.module.?; | |
| 1534 | const mod = self.bin_file.comp.module.?; | |
| 1536 | 1535 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1537 | 1536 | const elem_ty = self.typeOfIndex(inst); |
| 1538 | 1537 | const result: MCValue = result: { |
| ... | ... | @@ -1633,7 +1632,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1633 | 1632 | } |
| 1634 | 1633 | |
| 1635 | 1634 | fn 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.?; | |
| 1637 | 1636 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 1638 | 1637 | const ty = arg.ty.toType(); |
| 1639 | 1638 | const owner_decl = mod.funcOwnerDeclIndex(self.func_index); |
| ... | ... | @@ -1710,7 +1709,7 @@ fn airFence(self: *Self) !void { |
| 1710 | 1709 | } |
| 1711 | 1710 | |
| 1712 | 1711 | fn 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.?; | |
| 1714 | 1713 | if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{}); |
| 1715 | 1714 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 1716 | 1715 | const fn_ty = self.typeOf(pl_op.operand); |
| ... | ... | @@ -1812,7 +1811,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 1812 | 1811 | } |
| 1813 | 1812 | |
| 1814 | 1813 | fn ret(self: *Self, mcv: MCValue) !void { |
| 1815 | const mod = self.bin_file.options.module.?; | |
| 1814 | const mod = self.bin_file.comp.module.?; | |
| 1816 | 1815 | const ret_ty = self.fn_type.fnReturnType(mod); |
| 1817 | 1816 | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); |
| 1818 | 1817 | // 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 { |
| 1843 | 1842 | if (self.liveness.isUnused(inst)) |
| 1844 | 1843 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1845 | 1844 | const ty = self.typeOf(bin_op.lhs); |
| 1846 | const mod = self.bin_file.options.module.?; | |
| 1845 | const mod = self.bin_file.comp.module.?; | |
| 1847 | 1846 | assert(ty.eql(self.typeOf(bin_op.rhs), mod)); |
| 1848 | 1847 | if (ty.zigTypeTag(mod) == .ErrorSet) |
| 1849 | 1848 | return self.fail("TODO implement cmp for errors", .{}); |
| ... | ... | @@ -1887,7 +1886,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1887 | 1886 | |
| 1888 | 1887 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 1889 | 1888 | 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.?; | |
| 1891 | 1890 | const func = mod.funcInfo(ty_fn.func); |
| 1892 | 1891 | // TODO emit debug info for function change |
| 1893 | 1892 | _ = func; |
| ... | ... | @@ -2125,7 +2124,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void { |
| 2125 | 2124 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 2126 | 2125 | const block_data = self.blocks.getPtr(block).?; |
| 2127 | 2126 | |
| 2128 | const mod = self.bin_file.options.module.?; | |
| 2127 | const mod = self.bin_file.comp.module.?; | |
| 2129 | 2128 | if (self.typeOf(operand).hasRuntimeBits(mod)) { |
| 2130 | 2129 | const operand_mcv = try self.resolveInst(operand); |
| 2131 | 2130 | const block_mcv = block_data.mcv; |
| ... | ... | @@ -2508,7 +2507,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 2508 | 2507 | } |
| 2509 | 2508 | |
| 2510 | 2509 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 2511 | const mod = self.bin_file.options.module.?; | |
| 2510 | const mod = self.bin_file.comp.module.?; | |
| 2512 | 2511 | const vector_ty = self.typeOfIndex(inst); |
| 2513 | 2512 | const len = vector_ty.vectorLen(mod); |
| 2514 | 2513 | 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 { |
| 2553 | 2552 | } |
| 2554 | 2553 | |
| 2555 | 2554 | fn 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.?; | |
| 2557 | 2556 | |
| 2558 | 2557 | // If the type has no codegen bits, no need to store it. |
| 2559 | 2558 | const inst_ty = self.typeOf(inst); |
| ... | ... | @@ -2581,7 +2580,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 2581 | 2580 | } |
| 2582 | 2581 | |
| 2583 | 2582 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 2584 | const mod = self.bin_file.options.module.?; | |
| 2583 | const mod = self.bin_file.comp.module.?; | |
| 2585 | 2584 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 2586 | 2585 | self.bin_file, |
| 2587 | 2586 | self.src_loc, |
| ... | ... | @@ -2617,7 +2616,7 @@ const CallMCValues = struct { |
| 2617 | 2616 | |
| 2618 | 2617 | /// Caller must call `CallMCValues.deinit`. |
| 2619 | 2618 | fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 2620 | const mod = self.bin_file.options.module.?; | |
| 2619 | const mod = self.bin_file.comp.module.?; | |
| 2621 | 2620 | const ip = &mod.intern_pool; |
| 2622 | 2621 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 2623 | 2622 | const cc = fn_info.cc; |
| ... | ... | @@ -2709,7 +2708,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 2709 | 2708 | |
| 2710 | 2709 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. |
| 2711 | 2710 | fn wantSafety(self: *Self) bool { |
| 2712 | return switch (self.bin_file.options.optimize_mode) { | |
| 2711 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | |
| 2713 | 2712 | .Debug => true, |
| 2714 | 2713 | .ReleaseSafe => true, |
| 2715 | 2714 | .ReleaseFast => false, |
| ... | ... | @@ -2720,14 +2719,14 @@ fn wantSafety(self: *Self) bool { |
| 2720 | 2719 | fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 2721 | 2720 | @setCold(true); |
| 2722 | 2721 | 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); | |
| 2724 | 2723 | return error.CodegenFail; |
| 2725 | 2724 | } |
| 2726 | 2725 | |
| 2727 | 2726 | fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 2728 | 2727 | @setCold(true); |
| 2729 | 2728 | 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); | |
| 2731 | 2730 | return error.CodegenFail; |
| 2732 | 2731 | } |
| 2733 | 2732 | |
| ... | ... | @@ -2739,11 +2738,11 @@ fn parseRegName(name: []const u8) ?Register { |
| 2739 | 2738 | } |
| 2740 | 2739 | |
| 2741 | 2740 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 2742 | const mod = self.bin_file.options.module.?; | |
| 2741 | const mod = self.bin_file.comp.module.?; | |
| 2743 | 2742 | return self.air.typeOf(inst, &mod.intern_pool); |
| 2744 | 2743 | } |
| 2745 | 2744 | |
| 2746 | 2745 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 2747 | const mod = self.bin_file.options.module.?; | |
| 2746 | const mod = self.bin_file.comp.module.?; | |
| 2748 | 2747 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 2749 | 2748 | } |
src/arch/riscv64/Emit.zig+3-1| ... | ... | @@ -80,7 +80,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void { |
| 80 | 80 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 81 | 81 | @setCold(true); |
| 82 | 82 | 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); | |
| 84 | 86 | return error.EmitFail; |
| 85 | 87 | } |
| 86 | 88 |
src/arch/sparc64/CodeGen.zig+66-66| ... | ... | @@ -260,7 +260,7 @@ const BigTomb = struct { |
| 260 | 260 | }; |
| 261 | 261 | |
| 262 | 262 | pub fn generate( |
| 263 | bin_file: *link.File, | |
| 263 | lf: *link.File, | |
| 264 | 264 | src_loc: Module.SrcLoc, |
| 265 | 265 | func_index: InternPool.Index, |
| 266 | 266 | air: Air, |
| ... | ... | @@ -268,31 +268,30 @@ pub fn generate( |
| 268 | 268 | code: *std.ArrayList(u8), |
| 269 | 269 | debug_output: DebugInfoOutput, |
| 270 | 270 | ) 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); | |
| 278 | 275 | assert(fn_owner_decl.has_tv); |
| 279 | 276 | 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; | |
| 280 | 279 | |
| 281 | var branch_stack = std.ArrayList(Branch).init(bin_file.allocator); | |
| 280 | var branch_stack = std.ArrayList(Branch).init(gpa); | |
| 282 | 281 | defer { |
| 283 | 282 | assert(branch_stack.items.len == 1); |
| 284 | branch_stack.items[0].deinit(bin_file.allocator); | |
| 283 | branch_stack.items[0].deinit(gpa); | |
| 285 | 284 | branch_stack.deinit(); |
| 286 | 285 | } |
| 287 | 286 | try branch_stack.append(.{}); |
| 288 | 287 | |
| 289 | 288 | var function = Self{ |
| 290 | .gpa = bin_file.allocator, | |
| 289 | .gpa = gpa, | |
| 291 | 290 | .air = air, |
| 292 | 291 | .liveness = liveness, |
| 293 | .target = &bin_file.options.target, | |
| 292 | .target = target, | |
| 294 | 293 | .func_index = func_index, |
| 295 | .bin_file = bin_file, | |
| 294 | .bin_file = lf, | |
| 296 | 295 | .code = code, |
| 297 | 296 | .debug_output = debug_output, |
| 298 | 297 | .err_msg = null, |
| ... | ... | @@ -306,14 +305,14 @@ pub fn generate( |
| 306 | 305 | .end_di_line = func.rbrace_line, |
| 307 | 306 | .end_di_column = func.rbrace_column, |
| 308 | 307 | }; |
| 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); | |
| 312 | 311 | |
| 313 | 312 | var call_info = function.resolveCallingConventionValues(fn_type, .callee) catch |err| switch (err) { |
| 314 | 313 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 315 | 314 | 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.", .{}), | |
| 317 | 316 | }, |
| 318 | 317 | else => |e| return e, |
| 319 | 318 | }; |
| ... | ... | @@ -327,22 +326,22 @@ pub fn generate( |
| 327 | 326 | function.gen() catch |err| switch (err) { |
| 328 | 327 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 329 | 328 | 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.", .{}), | |
| 331 | 330 | }, |
| 332 | 331 | else => |e| return e, |
| 333 | 332 | }; |
| 334 | 333 | |
| 335 | 334 | var mir = Mir{ |
| 336 | 335 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 337 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 336 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 338 | 337 | }; |
| 339 | defer mir.deinit(bin_file.allocator); | |
| 338 | defer mir.deinit(gpa); | |
| 340 | 339 | |
| 341 | 340 | var emit = Emit{ |
| 342 | 341 | .mir = mir, |
| 343 | .bin_file = bin_file, | |
| 342 | .bin_file = lf, | |
| 344 | 343 | .debug_output = debug_output, |
| 345 | .target = &bin_file.options.target, | |
| 344 | .target = target, | |
| 346 | 345 | .src_loc = src_loc, |
| 347 | 346 | .code = code, |
| 348 | 347 | .prev_di_pc = 0, |
| ... | ... | @@ -364,7 +363,7 @@ pub fn generate( |
| 364 | 363 | } |
| 365 | 364 | |
| 366 | 365 | fn gen(self: *Self) !void { |
| 367 | const mod = self.bin_file.options.module.?; | |
| 366 | const mod = self.bin_file.comp.module.?; | |
| 368 | 367 | const cc = self.fn_type.fnCallingConvention(mod); |
| 369 | 368 | if (cc != .Naked) { |
| 370 | 369 | // TODO Finish function prologue and epilogue for sparc64. |
| ... | ... | @@ -492,7 +491,7 @@ fn gen(self: *Self) !void { |
| 492 | 491 | } |
| 493 | 492 | |
| 494 | 493 | fn 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.?; | |
| 496 | 495 | const ip = &mod.intern_pool; |
| 497 | 496 | const air_tags = self.air.instructions.items(.tag); |
| 498 | 497 | |
| ... | ... | @@ -762,7 +761,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 762 | 761 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 763 | 762 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 764 | 763 | 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.?; | |
| 766 | 765 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 767 | 766 | const lhs = try self.resolveInst(extra.lhs); |
| 768 | 767 | const rhs = try self.resolveInst(extra.rhs); |
| ... | ... | @@ -840,7 +839,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 840 | 839 | } |
| 841 | 840 | |
| 842 | 841 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 843 | const mod = self.bin_file.options.module.?; | |
| 842 | const mod = self.bin_file.comp.module.?; | |
| 844 | 843 | const vector_ty = self.typeOfIndex(inst); |
| 845 | 844 | const len = vector_ty.vectorLen(mod); |
| 846 | 845 | 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 { |
| 874 | 873 | } |
| 875 | 874 | |
| 876 | 875 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 877 | const mod = self.bin_file.options.module.?; | |
| 876 | const mod = self.bin_file.comp.module.?; | |
| 878 | 877 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 879 | 878 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 880 | 879 | const ptr_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -1011,7 +1010,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 1011 | 1010 | } |
| 1012 | 1011 | |
| 1013 | 1012 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1014 | const mod = self.bin_file.options.module.?; | |
| 1013 | const mod = self.bin_file.comp.module.?; | |
| 1015 | 1014 | const arg_index = self.arg_index; |
| 1016 | 1015 | self.arg_index += 1; |
| 1017 | 1016 | |
| ... | ... | @@ -1206,7 +1205,7 @@ fn airBreakpoint(self: *Self) !void { |
| 1206 | 1205 | } |
| 1207 | 1206 | |
| 1208 | 1207 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 1209 | const mod = self.bin_file.options.module.?; | |
| 1208 | const mod = self.bin_file.comp.module.?; | |
| 1210 | 1209 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1211 | 1210 | |
| 1212 | 1211 | // 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 |
| 1298 | 1297 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 1299 | 1298 | const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len])); |
| 1300 | 1299 | const ty = self.typeOf(callee); |
| 1301 | const mod = self.bin_file.options.module.?; | |
| 1300 | const mod = self.bin_file.comp.module.?; | |
| 1302 | 1301 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 1303 | 1302 | .Fn => ty, |
| 1304 | 1303 | .Pointer => ty.childType(mod), |
| ... | ... | @@ -1430,7 +1429,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 1430 | 1429 | |
| 1431 | 1430 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1432 | 1431 | 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.?; | |
| 1434 | 1433 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1435 | 1434 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1436 | 1435 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -1662,7 +1661,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 1662 | 1661 | |
| 1663 | 1662 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { |
| 1664 | 1663 | 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.?; | |
| 1666 | 1665 | const func = mod.funcInfo(ty_fn.func); |
| 1667 | 1666 | // TODO emit debug info for function change |
| 1668 | 1667 | _ = func; |
| ... | ... | @@ -1758,7 +1757,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1758 | 1757 | if (self.liveness.isUnused(inst)) |
| 1759 | 1758 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 1760 | 1759 | |
| 1761 | const mod = self.bin_file.options.module.?; | |
| 1760 | const mod = self.bin_file.comp.module.?; | |
| 1762 | 1761 | const operand_ty = self.typeOf(ty_op.operand); |
| 1763 | 1762 | const operand = try self.resolveInst(ty_op.operand); |
| 1764 | 1763 | const info_a = operand_ty.intInfo(mod); |
| ... | ... | @@ -1819,7 +1818,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { |
| 1819 | 1818 | } |
| 1820 | 1819 | |
| 1821 | 1820 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1822 | const mod = self.bin_file.options.module.?; | |
| 1821 | const mod = self.bin_file.comp.module.?; | |
| 1823 | 1822 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 1824 | 1823 | const elem_ty = self.typeOfIndex(inst); |
| 1825 | 1824 | const elem_size = elem_ty.abiSize(mod); |
| ... | ... | @@ -1903,7 +1902,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 1903 | 1902 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1904 | 1903 | const lhs_ty = self.typeOf(bin_op.lhs); |
| 1905 | 1904 | 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.?)); | |
| 1907 | 1906 | |
| 1908 | 1907 | if (self.liveness.isUnused(inst)) |
| 1909 | 1908 | 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 { |
| 2045 | 2044 | //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 2046 | 2045 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2047 | 2046 | 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.?; | |
| 2049 | 2048 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2050 | 2049 | const lhs = try self.resolveInst(extra.lhs); |
| 2051 | 2050 | const rhs = try self.resolveInst(extra.rhs); |
| ... | ... | @@ -2109,7 +2108,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2109 | 2108 | |
| 2110 | 2109 | fn airNot(self: *Self, inst: Air.Inst.Index) !void { |
| 2111 | 2110 | 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.?; | |
| 2113 | 2112 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2114 | 2113 | const operand = try self.resolveInst(ty_op.operand); |
| 2115 | 2114 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -2341,7 +2340,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 2341 | 2340 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 2342 | 2341 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 2343 | 2342 | 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.?; | |
| 2345 | 2344 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2346 | 2345 | const lhs = try self.resolveInst(extra.lhs); |
| 2347 | 2346 | const rhs = try self.resolveInst(extra.rhs); |
| ... | ... | @@ -2446,7 +2445,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 2446 | 2445 | } |
| 2447 | 2446 | |
| 2448 | 2447 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2449 | const mod = self.bin_file.options.module.?; | |
| 2448 | const mod = self.bin_file.comp.module.?; | |
| 2450 | 2449 | const is_volatile = false; // TODO |
| 2451 | 2450 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2452 | 2451 | |
| ... | ... | @@ -2571,7 +2570,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2571 | 2570 | const operand = extra.struct_operand; |
| 2572 | 2571 | const index = extra.field_index; |
| 2573 | 2572 | 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.?; | |
| 2575 | 2574 | const mcv = try self.resolveInst(operand); |
| 2576 | 2575 | const struct_ty = self.typeOf(operand); |
| 2577 | 2576 | 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 { |
| 2704 | 2703 | } |
| 2705 | 2704 | |
| 2706 | 2705 | fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2707 | const mod = self.bin_file.options.module.?; | |
| 2706 | const mod = self.bin_file.comp.module.?; | |
| 2708 | 2707 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2709 | 2708 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2710 | 2709 | const error_union_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -2718,7 +2717,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2718 | 2717 | } |
| 2719 | 2718 | |
| 2720 | 2719 | fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2721 | const mod = self.bin_file.options.module.?; | |
| 2720 | const mod = self.bin_file.comp.module.?; | |
| 2722 | 2721 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2723 | 2722 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2724 | 2723 | const error_union_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -2732,7 +2731,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2732 | 2731 | |
| 2733 | 2732 | /// E to E!T |
| 2734 | 2733 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2735 | const mod = self.bin_file.options.module.?; | |
| 2734 | const mod = self.bin_file.comp.module.?; | |
| 2736 | 2735 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2737 | 2736 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2738 | 2737 | const error_union_ty = ty_op.ty.toType(); |
| ... | ... | @@ -2753,7 +2752,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2753 | 2752 | } |
| 2754 | 2753 | |
| 2755 | 2754 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2756 | const mod = self.bin_file.options.module.?; | |
| 2755 | const mod = self.bin_file.comp.module.?; | |
| 2757 | 2756 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2758 | 2757 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 2759 | 2758 | const optional_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -2793,7 +2792,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme |
| 2793 | 2792 | |
| 2794 | 2793 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2795 | 2794 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2796 | const mod = self.bin_file.options.module.?; | |
| 2795 | const mod = self.bin_file.comp.module.?; | |
| 2797 | 2796 | const elem_ty = self.typeOfIndex(inst).childType(mod); |
| 2798 | 2797 | |
| 2799 | 2798 | if (!elem_ty.hasRuntimeBits(mod)) { |
| ... | ... | @@ -2813,7 +2812,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { |
| 2813 | 2812 | } |
| 2814 | 2813 | |
| 2815 | 2814 | fn 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.?; | |
| 2817 | 2816 | const elem_ty = self.typeOfIndex(inst); |
| 2818 | 2817 | const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { |
| 2819 | 2818 | return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); |
| ... | ... | @@ -2860,7 +2859,7 @@ fn binOp( |
| 2860 | 2859 | rhs_ty: Type, |
| 2861 | 2860 | metadata: ?BinOpMetadata, |
| 2862 | 2861 | ) InnerError!MCValue { |
| 2863 | const mod = self.bin_file.options.module.?; | |
| 2862 | const mod = self.bin_file.comp.module.?; | |
| 2864 | 2863 | switch (tag) { |
| 2865 | 2864 | .add, |
| 2866 | 2865 | .sub, |
| ... | ... | @@ -3401,7 +3400,7 @@ fn binOpRegister( |
| 3401 | 3400 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 3402 | 3401 | const block_data = self.blocks.getPtr(block).?; |
| 3403 | 3402 | |
| 3404 | const mod = self.bin_file.options.module.?; | |
| 3403 | const mod = self.bin_file.comp.module.?; | |
| 3405 | 3404 | if (self.typeOf(operand).hasRuntimeBits(mod)) { |
| 3406 | 3405 | const operand_mcv = try self.resolveInst(operand); |
| 3407 | 3406 | const block_mcv = block_data.mcv; |
| ... | ... | @@ -3521,7 +3520,7 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void { |
| 3521 | 3520 | |
| 3522 | 3521 | /// Given an error union, returns the payload |
| 3523 | 3522 | fn 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.?; | |
| 3525 | 3524 | const err_ty = error_union_ty.errorUnionSet(mod); |
| 3526 | 3525 | const payload_ty = error_union_ty.errorUnionPayload(mod); |
| 3527 | 3526 | if (err_ty.errorSetIsEmpty(mod)) { |
| ... | ... | @@ -3547,7 +3546,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) |
| 3547 | 3546 | fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 3548 | 3547 | @setCold(true); |
| 3549 | 3548 | 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); | |
| 3551 | 3551 | return error.CodegenFail; |
| 3552 | 3552 | } |
| 3553 | 3553 | |
| ... | ... | @@ -3591,7 +3591,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live |
| 3591 | 3591 | } |
| 3592 | 3592 | |
| 3593 | 3593 | fn 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.?; | |
| 3595 | 3595 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 3596 | 3596 | const ty = arg.ty.toType(); |
| 3597 | 3597 | 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 |
| 3740 | 3740 | } |
| 3741 | 3741 | |
| 3742 | 3742 | fn 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.?; | |
| 3744 | 3744 | switch (mcv) { |
| 3745 | 3745 | .dead => unreachable, |
| 3746 | 3746 | .unreach, .none => return, // Nothing to do. |
| ... | ... | @@ -3951,7 +3951,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 3951 | 3951 | } |
| 3952 | 3952 | |
| 3953 | 3953 | fn 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.?; | |
| 3955 | 3955 | const abi_size = ty.abiSize(mod); |
| 3956 | 3956 | switch (mcv) { |
| 3957 | 3957 | .dead => unreachable, |
| ... | ... | @@ -4125,7 +4125,7 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re |
| 4125 | 4125 | } |
| 4126 | 4126 | |
| 4127 | 4127 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 4128 | const mod = self.bin_file.options.module.?; | |
| 4128 | const mod = self.bin_file.comp.module.?; | |
| 4129 | 4129 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 4130 | 4130 | self.bin_file, |
| 4131 | 4131 | self.src_loc, |
| ... | ... | @@ -4161,7 +4161,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue { |
| 4161 | 4161 | } |
| 4162 | 4162 | |
| 4163 | 4163 | fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue { |
| 4164 | const mod = self.bin_file.options.module.?; | |
| 4164 | const mod = self.bin_file.comp.module.?; | |
| 4165 | 4165 | const error_type = ty.errorUnionSet(mod); |
| 4166 | 4166 | const payload_type = ty.errorUnionPayload(mod); |
| 4167 | 4167 | |
| ... | ... | @@ -4259,7 +4259,7 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { |
| 4259 | 4259 | } |
| 4260 | 4260 | |
| 4261 | 4261 | fn 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.?; | |
| 4263 | 4263 | const elem_ty = ptr_ty.childType(mod); |
| 4264 | 4264 | const elem_size = elem_ty.abiSize(mod); |
| 4265 | 4265 | |
| ... | ... | @@ -4330,7 +4330,7 @@ fn minMax( |
| 4330 | 4330 | lhs_ty: Type, |
| 4331 | 4331 | rhs_ty: Type, |
| 4332 | 4332 | ) InnerError!MCValue { |
| 4333 | const mod = self.bin_file.options.module.?; | |
| 4333 | const mod = self.bin_file.comp.module.?; | |
| 4334 | 4334 | assert(lhs_ty.eql(rhs_ty, mod)); |
| 4335 | 4335 | switch (lhs_ty.zigTypeTag(mod)) { |
| 4336 | 4336 | .Float => return self.fail("TODO min/max on floats", .{}), |
| ... | ... | @@ -4450,7 +4450,7 @@ fn realStackOffset(off: u32) u32 { |
| 4450 | 4450 | |
| 4451 | 4451 | /// Caller must call `CallMCValues.deinit`. |
| 4452 | 4452 | fn 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.?; | |
| 4454 | 4454 | const ip = &mod.intern_pool; |
| 4455 | 4455 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 4456 | 4456 | const cc = fn_info.cc; |
| ... | ... | @@ -4542,7 +4542,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4542 | 4542 | } |
| 4543 | 4543 | |
| 4544 | 4544 | fn 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.?; | |
| 4546 | 4546 | const ty = self.typeOf(ref); |
| 4547 | 4547 | |
| 4548 | 4548 | // 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 { |
| 4559 | 4559 | } |
| 4560 | 4560 | |
| 4561 | 4561 | fn ret(self: *Self, mcv: MCValue) !void { |
| 4562 | const mod = self.bin_file.options.module.?; | |
| 4562 | const mod = self.bin_file.comp.module.?; | |
| 4563 | 4563 | const ret_ty = self.fn_type.fnReturnType(mod); |
| 4564 | 4564 | try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); |
| 4565 | 4565 | |
| ... | ... | @@ -4661,7 +4661,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void |
| 4661 | 4661 | } |
| 4662 | 4662 | |
| 4663 | 4663 | fn 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.?; | |
| 4665 | 4665 | const abi_size = value_ty.abiSize(mod); |
| 4666 | 4666 | |
| 4667 | 4667 | switch (ptr) { |
| ... | ... | @@ -4703,7 +4703,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 4703 | 4703 | |
| 4704 | 4704 | fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue { |
| 4705 | 4705 | 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.?; | |
| 4707 | 4707 | const mcv = try self.resolveInst(operand); |
| 4708 | 4708 | const ptr_ty = self.typeOf(operand); |
| 4709 | 4709 | const struct_ty = ptr_ty.childType(mod); |
| ... | ... | @@ -4745,7 +4745,7 @@ fn trunc( |
| 4745 | 4745 | operand_ty: Type, |
| 4746 | 4746 | dest_ty: Type, |
| 4747 | 4747 | ) !MCValue { |
| 4748 | const mod = self.bin_file.options.module.?; | |
| 4748 | const mod = self.bin_file.comp.module.?; | |
| 4749 | 4749 | const info_a = operand_ty.intInfo(mod); |
| 4750 | 4750 | const info_b = dest_ty.intInfo(mod); |
| 4751 | 4751 | |
| ... | ... | @@ -4857,7 +4857,7 @@ fn truncRegister( |
| 4857 | 4857 | |
| 4858 | 4858 | /// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`. |
| 4859 | 4859 | fn wantSafety(self: *Self) bool { |
| 4860 | return switch (self.bin_file.options.optimize_mode) { | |
| 4860 | return switch (self.bin_file.comp.root_mod.optimize_mode) { | |
| 4861 | 4861 | .Debug => true, |
| 4862 | 4862 | .ReleaseSafe => true, |
| 4863 | 4863 | .ReleaseFast => false, |
| ... | ... | @@ -4866,11 +4866,11 @@ fn wantSafety(self: *Self) bool { |
| 4866 | 4866 | } |
| 4867 | 4867 | |
| 4868 | 4868 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 4869 | const mod = self.bin_file.options.module.?; | |
| 4869 | const mod = self.bin_file.comp.module.?; | |
| 4870 | 4870 | return self.air.typeOf(inst, &mod.intern_pool); |
| 4871 | 4871 | } |
| 4872 | 4872 | |
| 4873 | 4873 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 4874 | const mod = self.bin_file.options.module.?; | |
| 4874 | const mod = self.bin_file.comp.module.?; | |
| 4875 | 4875 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 4876 | 4876 | } |
src/arch/sparc64/Emit.zig+17-12| ... | ... | @@ -152,14 +152,16 @@ pub fn emitMir( |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | pub fn deinit(emit: *Emit) void { |
| 155 | const comp = emit.bin_file.comp; | |
| 156 | const gpa = comp.gpa; | |
| 155 | 157 | var iter = emit.branch_forward_origins.valueIterator(); |
| 156 | 158 | while (iter.next()) |origin_list| { |
| 157 | origin_list.deinit(emit.bin_file.allocator); | |
| 159 | origin_list.deinit(gpa); | |
| 158 | 160 | } |
| 159 | 161 | |
| 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); | |
| 163 | 165 | emit.* = undefined; |
| 164 | 166 | } |
| 165 | 167 | |
| ... | ... | @@ -511,7 +513,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void { |
| 511 | 513 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 512 | 514 | @setCold(true); |
| 513 | 515 | 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); | |
| 515 | 519 | return error.EmitFail; |
| 516 | 520 | } |
| 517 | 521 | |
| ... | ... | @@ -537,8 +541,9 @@ fn isBranch(tag: Mir.Inst.Tag) bool { |
| 537 | 541 | } |
| 538 | 542 | |
| 539 | 543 | fn lowerBranches(emit: *Emit) !void { |
| 544 | const comp = emit.bin_file.comp; | |
| 545 | const gpa = comp.gpa; | |
| 540 | 546 | const mir_tags = emit.mir.instructions.items(.tag); |
| 541 | const allocator = emit.bin_file.allocator; | |
| 542 | 547 | |
| 543 | 548 | // First pass: Note down all branches and their target |
| 544 | 549 | // instructions, i.e. populate branch_types, |
| ... | ... | @@ -552,7 +557,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 552 | 557 | const target_inst = emit.branchTarget(inst); |
| 553 | 558 | |
| 554 | 559 | // 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)); | |
| 556 | 561 | |
| 557 | 562 | // Forward branches require some extra stuff: We only |
| 558 | 563 | // know their offset once we arrive at the target |
| ... | ... | @@ -562,14 +567,14 @@ fn lowerBranches(emit: *Emit) !void { |
| 562 | 567 | // etc. |
| 563 | 568 | if (target_inst > inst) { |
| 564 | 569 | // 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); | |
| 566 | 571 | |
| 567 | 572 | if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| { |
| 568 | try origin_list.append(allocator, inst); | |
| 573 | try origin_list.append(gpa, inst); | |
| 569 | 574 | } else { |
| 570 | 575 | 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); | |
| 573 | 578 | } |
| 574 | 579 | } |
| 575 | 580 | |
| ... | ... | @@ -579,7 +584,7 @@ fn lowerBranches(emit: *Emit) !void { |
| 579 | 584 | // putNoClobber may not be used as the put operation |
| 580 | 585 | // may clobber the entry when multiple branches branch |
| 581 | 586 | // 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); | |
| 583 | 588 | } |
| 584 | 589 | } |
| 585 | 590 |
src/arch/wasm/CodeGen.zig+131-123| ... | ... | @@ -766,7 +766,7 @@ pub fn deinit(func: *CodeGen) void { |
| 766 | 766 | |
| 767 | 767 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig |
| 768 | 768 | fn 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.?; | |
| 770 | 770 | const src = LazySrcLoc.nodeOffset(0); |
| 771 | 771 | const src_loc = src.toSrcLoc(func.decl, mod); |
| 772 | 772 | 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 { |
| 791 | 791 | const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref); |
| 792 | 792 | assert(!gop.found_existing); |
| 793 | 793 | |
| 794 | const mod = func.bin_file.base.options.module.?; | |
| 794 | const mod = func.bin_file.base.comp.module.?; | |
| 795 | 795 | const val = (try func.air.value(ref, mod)).?; |
| 796 | 796 | const ty = func.typeOf(ref); |
| 797 | 797 | 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 { |
| 1101 | 1101 | /// Creates one locals for a given `Type`. |
| 1102 | 1102 | /// Returns a corresponding `Wvalue` with `local` as active tag |
| 1103 | 1103 | fn 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.?; | |
| 1105 | 1105 | const valtype = typeToValtype(ty, mod); |
| 1106 | 1106 | switch (valtype) { |
| 1107 | 1107 | .i32 => if (func.free_locals_i32.popOrNull()) |index| { |
| ... | ... | @@ -1133,7 +1133,7 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue { |
| 1133 | 1133 | /// Ensures a new local will be created. This is useful when it's useful |
| 1134 | 1134 | /// to use a zero-initialized local. |
| 1135 | 1135 | fn 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.?; | |
| 1137 | 1137 | try func.locals.append(func.gpa, genValtype(ty, mod)); |
| 1138 | 1138 | const initial_index = func.local_index; |
| 1139 | 1139 | func.local_index += 1; |
| ... | ... | @@ -1210,18 +1210,23 @@ pub fn generate( |
| 1210 | 1210 | debug_output: codegen.DebugInfoOutput, |
| 1211 | 1211 | ) codegen.CodeGenError!codegen.Result { |
| 1212 | 1212 | _ = 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.?; | |
| 1214 | 1216 | 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; | |
| 1215 | 1220 | var code_gen: CodeGen = .{ |
| 1216 | .gpa = bin_file.allocator, | |
| 1221 | .gpa = gpa, | |
| 1217 | 1222 | .air = air, |
| 1218 | 1223 | .liveness = liveness, |
| 1219 | 1224 | .code = code, |
| 1220 | 1225 | .decl_index = func.owner_decl, |
| 1221 | .decl = mod.declPtr(func.owner_decl), | |
| 1226 | .decl = decl, | |
| 1222 | 1227 | .err_msg = undefined, |
| 1223 | 1228 | .locals = .{}, |
| 1224 | .target = bin_file.options.target, | |
| 1229 | .target = target, | |
| 1225 | 1230 | .bin_file = bin_file.cast(link.File.Wasm).?, |
| 1226 | 1231 | .debug_output = debug_output, |
| 1227 | 1232 | .func_index = func_index, |
| ... | ... | @@ -1237,7 +1242,7 @@ pub fn generate( |
| 1237 | 1242 | } |
| 1238 | 1243 | |
| 1239 | 1244 | fn genFunc(func: *CodeGen) InnerError!void { |
| 1240 | const mod = func.bin_file.base.options.module.?; | |
| 1245 | const mod = func.bin_file.base.comp.module.?; | |
| 1241 | 1246 | const ip = &mod.intern_pool; |
| 1242 | 1247 | const fn_info = mod.typeToFunc(func.decl.ty).?; |
| 1243 | 1248 | 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 { |
| 1348 | 1353 | }; |
| 1349 | 1354 | |
| 1350 | 1355 | fn 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.?; | |
| 1352 | 1357 | const ip = &mod.intern_pool; |
| 1353 | 1358 | const fn_info = mod.typeToFunc(fn_ty).?; |
| 1354 | 1359 | const cc = fn_info.cc; |
| ... | ... | @@ -1417,7 +1422,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: |
| 1417 | 1422 | return func.lowerToStack(value); |
| 1418 | 1423 | } |
| 1419 | 1424 | |
| 1420 | const mod = func.bin_file.base.options.module.?; | |
| 1425 | const mod = func.bin_file.base.comp.module.?; | |
| 1421 | 1426 | const ty_classes = abi.classifyType(ty, mod); |
| 1422 | 1427 | assert(ty_classes[0] != .none); |
| 1423 | 1428 | switch (ty.zigTypeTag(mod)) { |
| ... | ... | @@ -1516,7 +1521,7 @@ fn restoreStackPointer(func: *CodeGen) !void { |
| 1516 | 1521 | /// |
| 1517 | 1522 | /// Asserts Type has codegenbits |
| 1518 | 1523 | fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1519 | const mod = func.bin_file.base.options.module.?; | |
| 1524 | const mod = func.bin_file.base.comp.module.?; | |
| 1520 | 1525 | assert(ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 1521 | 1526 | if (func.initial_stack_value == .none) { |
| 1522 | 1527 | try func.initializeStack(); |
| ... | ... | @@ -1542,7 +1547,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue { |
| 1542 | 1547 | /// This is different from allocStack where this will use the pointer's alignment |
| 1543 | 1548 | /// if it is set, to ensure the stack alignment will be set correctly. |
| 1544 | 1549 | fn 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.?; | |
| 1546 | 1551 | const ptr_ty = func.typeOfIndex(inst); |
| 1547 | 1552 | const pointee_ty = ptr_ty.childType(mod); |
| 1548 | 1553 | |
| ... | ... | @@ -2072,7 +2077,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2072 | 2077 | } |
| 2073 | 2078 | |
| 2074 | 2079 | fn 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.?; | |
| 2076 | 2081 | const ip = &mod.intern_pool; |
| 2077 | 2082 | |
| 2078 | 2083 | for (body) |inst| { |
| ... | ... | @@ -2093,7 +2098,7 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 2093 | 2098 | } |
| 2094 | 2099 | |
| 2095 | 2100 | fn 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.?; | |
| 2097 | 2102 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2098 | 2103 | const operand = try func.resolveInst(un_op); |
| 2099 | 2104 | const fn_info = mod.typeToFunc(func.decl.ty).?; |
| ... | ... | @@ -2136,7 +2141,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2136 | 2141 | } |
| 2137 | 2142 | |
| 2138 | 2143 | fn 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.?; | |
| 2140 | 2145 | const child_type = func.typeOfIndex(inst).childType(mod); |
| 2141 | 2146 | |
| 2142 | 2147 | const result = result: { |
| ... | ... | @@ -2156,7 +2161,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2156 | 2161 | } |
| 2157 | 2162 | |
| 2158 | 2163 | fn 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.?; | |
| 2160 | 2165 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 2161 | 2166 | const operand = try func.resolveInst(un_op); |
| 2162 | 2167 | 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 |
| 2183 | 2188 | const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len])); |
| 2184 | 2189 | const ty = func.typeOf(pl_op.operand); |
| 2185 | 2190 | |
| 2186 | const mod = func.bin_file.base.options.module.?; | |
| 2191 | const mod = func.bin_file.base.comp.module.?; | |
| 2187 | 2192 | const ip = &mod.intern_pool; |
| 2188 | 2193 | const fn_ty = switch (ty.zigTypeTag(mod)) { |
| 2189 | 2194 | .Fn => ty, |
| ... | ... | @@ -2295,7 +2300,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2295 | 2300 | } |
| 2296 | 2301 | |
| 2297 | 2302 | fn 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.?; | |
| 2299 | 2304 | if (safety) { |
| 2300 | 2305 | // TODO if the value is undef, write 0xaa bytes to dest |
| 2301 | 2306 | } else { |
| ... | ... | @@ -2349,7 +2354,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 2349 | 2354 | |
| 2350 | 2355 | fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void { |
| 2351 | 2356 | assert(!(lhs != .stack and rhs == .stack)); |
| 2352 | const mod = func.bin_file.base.options.module.?; | |
| 2357 | const mod = func.bin_file.base.comp.module.?; | |
| 2353 | 2358 | const abi_size = ty.abiSize(mod); |
| 2354 | 2359 | switch (ty.zigTypeTag(mod)) { |
| 2355 | 2360 | .ErrorUnion => { |
| ... | ... | @@ -2428,7 +2433,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2428 | 2433 | }, |
| 2429 | 2434 | else => if (abi_size > 8) { |
| 2430 | 2435 | 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.?), | |
| 2432 | 2437 | abi_size, |
| 2433 | 2438 | }); |
| 2434 | 2439 | }, |
| ... | ... | @@ -2456,7 +2461,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE |
| 2456 | 2461 | } |
| 2457 | 2462 | |
| 2458 | 2463 | fn 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.?; | |
| 2460 | 2465 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2461 | 2466 | const operand = try func.resolveInst(ty_op.operand); |
| 2462 | 2467 | const ty = ty_op.ty.toType(); |
| ... | ... | @@ -2499,7 +2504,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2499 | 2504 | /// Loads an operand from the linear memory section. |
| 2500 | 2505 | /// NOTE: Leaves the value on the stack. |
| 2501 | 2506 | fn 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.?; | |
| 2503 | 2508 | // load local's value from memory by its stack position |
| 2504 | 2509 | try func.emitWValue(operand); |
| 2505 | 2510 | |
| ... | ... | @@ -2536,7 +2541,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu |
| 2536 | 2541 | } |
| 2537 | 2542 | |
| 2538 | 2543 | fn 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.?; | |
| 2540 | 2545 | const arg_index = func.arg_index; |
| 2541 | 2546 | const arg = func.args[arg_index]; |
| 2542 | 2547 | const cc = mod.typeToFunc(func.decl.ty).?.cc; |
| ... | ... | @@ -2555,7 +2560,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2555 | 2560 | if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) { |
| 2556 | 2561 | return func.fail( |
| 2557 | 2562 | "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.?)}, | |
| 2559 | 2564 | ); |
| 2560 | 2565 | } |
| 2561 | 2566 | const result = try func.allocStack(arg_ty); |
| ... | ... | @@ -2582,7 +2587,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2582 | 2587 | } |
| 2583 | 2588 | |
| 2584 | 2589 | fn 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.?; | |
| 2586 | 2591 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2587 | 2592 | const lhs = try func.resolveInst(bin_op.lhs); |
| 2588 | 2593 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -2619,7 +2624,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 2619 | 2624 | /// Performs a binary operation on the given `WValue`'s |
| 2620 | 2625 | /// NOTE: THis leaves the value on top of the stack. |
| 2621 | 2626 | fn 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.?; | |
| 2623 | 2628 | assert(!(lhs != .stack and rhs == .stack)); |
| 2624 | 2629 | |
| 2625 | 2630 | if (ty.isAnyFloat()) { |
| ... | ... | @@ -2633,7 +2638,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2633 | 2638 | } else { |
| 2634 | 2639 | return func.fail( |
| 2635 | 2640 | "TODO: Implement binary operation for type: {}", |
| 2636 | .{ty.fmt(func.bin_file.base.options.module.?)}, | |
| 2641 | .{ty.fmt(func.bin_file.base.comp.module.?)}, | |
| 2637 | 2642 | ); |
| 2638 | 2643 | } |
| 2639 | 2644 | } |
| ... | ... | @@ -2652,7 +2657,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError! |
| 2652 | 2657 | } |
| 2653 | 2658 | |
| 2654 | 2659 | fn 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.?; | |
| 2656 | 2661 | const int_info = ty.intInfo(mod); |
| 2657 | 2662 | if (int_info.bits > 128) { |
| 2658 | 2663 | return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{}); |
| ... | ... | @@ -2788,7 +2793,7 @@ const FloatOp = enum { |
| 2788 | 2793 | }; |
| 2789 | 2794 | |
| 2790 | 2795 | fn 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.?; | |
| 2792 | 2797 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2793 | 2798 | const operand = try func.resolveInst(ty_op.operand); |
| 2794 | 2799 | const ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -2873,7 +2878,7 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError |
| 2873 | 2878 | } |
| 2874 | 2879 | |
| 2875 | 2880 | fn 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.?; | |
| 2877 | 2882 | if (ty.zigTypeTag(mod) == .Vector) { |
| 2878 | 2883 | return func.fail("TODO: Implement floatOps for vectors", .{}); |
| 2879 | 2884 | } |
| ... | ... | @@ -2979,7 +2984,7 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue { |
| 2979 | 2984 | } |
| 2980 | 2985 | |
| 2981 | 2986 | fn 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.?; | |
| 2983 | 2988 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 2984 | 2989 | |
| 2985 | 2990 | 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 |
| 3030 | 3035 | /// Asserts `Type` is <= 128 bits. |
| 3031 | 3036 | /// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack. |
| 3032 | 3037 | fn 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.?; | |
| 3034 | 3039 | assert(ty.abiSize(mod) <= 16); |
| 3035 | 3040 | const bitsize = @as(u16, @intCast(ty.bitSize(mod))); |
| 3036 | 3041 | const wasm_bits = toWasmBits(bitsize) orelse { |
| ... | ... | @@ -3069,7 +3074,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue { |
| 3069 | 3074 | } |
| 3070 | 3075 | |
| 3071 | 3076 | fn 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.?; | |
| 3073 | 3078 | const ptr = mod.intern_pool.indexToKey(ptr_val.ip_index).ptr; |
| 3074 | 3079 | switch (ptr.addr) { |
| 3075 | 3080 | .decl => |decl_index| { |
| ... | ... | @@ -3132,7 +3137,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue |
| 3132 | 3137 | } |
| 3133 | 3138 | |
| 3134 | 3139 | fn 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.?; | |
| 3136 | 3141 | const decl = mod.declPtr(decl_index); |
| 3137 | 3142 | try mod.markDeclAlive(decl); |
| 3138 | 3143 | const ptr_ty = try mod.singleMutPtrType(decl.ty); |
| ... | ... | @@ -3144,7 +3149,7 @@ fn lowerAnonDeclRef( |
| 3144 | 3149 | anon_decl: InternPool.Key.Ptr.Addr.AnonDecl, |
| 3145 | 3150 | offset: u32, |
| 3146 | 3151 | ) InnerError!WValue { |
| 3147 | const mod = func.bin_file.base.options.module.?; | |
| 3152 | const mod = func.bin_file.base.comp.module.?; | |
| 3148 | 3153 | const decl_val = anon_decl.val; |
| 3149 | 3154 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 3150 | 3155 | |
| ... | ... | @@ -3172,7 +3177,7 @@ fn lowerAnonDeclRef( |
| 3172 | 3177 | } |
| 3173 | 3178 | |
| 3174 | 3179 | fn 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.?; | |
| 3176 | 3181 | if (tv.ty.isSlice(mod)) { |
| 3177 | 3182 | return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) }; |
| 3178 | 3183 | } |
| ... | ... | @@ -3225,7 +3230,7 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo( |
| 3225 | 3230 | /// This function is intended to assert that `isByRef` returns `false` for `ty`. |
| 3226 | 3231 | /// However such an assertion fails on the behavior tests currently. |
| 3227 | 3232 | fn 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.?; | |
| 3229 | 3234 | // TODO: enable this assertion |
| 3230 | 3235 | //assert(!isByRef(ty, mod)); |
| 3231 | 3236 | const ip = &mod.intern_pool; |
| ... | ... | @@ -3394,7 +3399,7 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue { |
| 3394 | 3399 | } |
| 3395 | 3400 | |
| 3396 | 3401 | fn 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.?; | |
| 3398 | 3403 | const ip = &mod.intern_pool; |
| 3399 | 3404 | switch (ty.zigTypeTag(mod)) { |
| 3400 | 3405 | .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa }, |
| ... | ... | @@ -3436,7 +3441,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3436 | 3441 | /// It's illegal to provide a value with a type that cannot be represented |
| 3437 | 3442 | /// as an integer value. |
| 3438 | 3443 | fn 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.?; | |
| 3440 | 3445 | |
| 3441 | 3446 | switch (val.ip_index) { |
| 3442 | 3447 | .none => {}, |
| ... | ... | @@ -3472,7 +3477,7 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 { |
| 3472 | 3477 | } |
| 3473 | 3478 | |
| 3474 | 3479 | fn 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.?; | |
| 3476 | 3481 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3477 | 3482 | const block_ty = ty_pl.ty.toType(); |
| 3478 | 3483 | 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 |
| 3593 | 3598 | /// NOTE: This leaves the result on top of the stack, rather than a new local. |
| 3594 | 3599 | fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue { |
| 3595 | 3600 | assert(!(lhs != .stack and rhs == .stack)); |
| 3596 | const mod = func.bin_file.base.options.module.?; | |
| 3601 | const mod = func.bin_file.base.comp.module.?; | |
| 3597 | 3602 | if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) { |
| 3598 | 3603 | const payload_ty = ty.optionalChild(mod); |
| 3599 | 3604 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| ... | ... | @@ -3711,7 +3716,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3711 | 3716 | const errors_len = WValue{ .memory = sym_index }; |
| 3712 | 3717 | |
| 3713 | 3718 | try func.emitWValue(operand); |
| 3714 | const mod = func.bin_file.base.options.module.?; | |
| 3719 | const mod = func.bin_file.base.comp.module.?; | |
| 3715 | 3720 | const err_int_ty = try mod.errorIntType(); |
| 3716 | 3721 | const errors_len_val = try func.load(errors_len, err_int_ty, 0); |
| 3717 | 3722 | 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 { |
| 3720 | 3725 | } |
| 3721 | 3726 | |
| 3722 | 3727 | fn 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.?; | |
| 3724 | 3729 | const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 3725 | 3730 | const block = func.blocks.get(br.block_inst).?; |
| 3726 | 3731 | |
| ... | ... | @@ -3747,7 +3752,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3747 | 3752 | |
| 3748 | 3753 | const operand = try func.resolveInst(ty_op.operand); |
| 3749 | 3754 | 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.?; | |
| 3751 | 3756 | |
| 3752 | 3757 | const result = result: { |
| 3753 | 3758 | if (operand_ty.zigTypeTag(mod) == .Bool) { |
| ... | ... | @@ -3818,7 +3823,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3818 | 3823 | const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand); |
| 3819 | 3824 | break :result try bitcast_result.toLocal(func, wanted_ty); |
| 3820 | 3825 | } |
| 3821 | const mod = func.bin_file.base.options.module.?; | |
| 3826 | const mod = func.bin_file.base.comp.module.?; | |
| 3822 | 3827 | if (isByRef(given_ty, mod) and !isByRef(wanted_ty, mod)) { |
| 3823 | 3828 | const loaded_memory = try func.load(operand, wanted_ty, 0); |
| 3824 | 3829 | break :result try loaded_memory.toLocal(func, wanted_ty); |
| ... | ... | @@ -3834,7 +3839,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3834 | 3839 | } |
| 3835 | 3840 | |
| 3836 | 3841 | fn 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.?; | |
| 3838 | 3843 | // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction |
| 3839 | 3844 | if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; |
| 3840 | 3845 | 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 |
| 3852 | 3857 | } |
| 3853 | 3858 | |
| 3854 | 3859 | fn 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.?; | |
| 3856 | 3861 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3857 | 3862 | const extra = func.air.extraData(Air.StructField, ty_pl.payload); |
| 3858 | 3863 | |
| ... | ... | @@ -3864,7 +3869,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3864 | 3869 | } |
| 3865 | 3870 | |
| 3866 | 3871 | fn 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.?; | |
| 3868 | 3873 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3869 | 3874 | const struct_ptr = try func.resolveInst(ty_op.operand); |
| 3870 | 3875 | const struct_ptr_ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -3883,7 +3888,7 @@ fn structFieldPtr( |
| 3883 | 3888 | struct_ty: Type, |
| 3884 | 3889 | index: u32, |
| 3885 | 3890 | ) InnerError!WValue { |
| 3886 | const mod = func.bin_file.base.options.module.?; | |
| 3891 | const mod = func.bin_file.base.comp.module.?; | |
| 3887 | 3892 | const result_ty = func.typeOfIndex(inst); |
| 3888 | 3893 | const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); |
| 3889 | 3894 | |
| ... | ... | @@ -3914,7 +3919,7 @@ fn structFieldPtr( |
| 3914 | 3919 | } |
| 3915 | 3920 | |
| 3916 | 3921 | fn 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.?; | |
| 3918 | 3923 | const ip = &mod.intern_pool; |
| 3919 | 3924 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3920 | 3925 | 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 { |
| 4013 | 4018 | } |
| 4014 | 4019 | |
| 4015 | 4020 | fn 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.?; | |
| 4017 | 4022 | // result type is always 'noreturn' |
| 4018 | 4023 | const blocktype = wasm.block_empty; |
| 4019 | 4024 | 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 { |
| 4193 | 4198 | } |
| 4194 | 4199 | |
| 4195 | 4200 | fn 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.?; | |
| 4197 | 4202 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4198 | 4203 | const operand = try func.resolveInst(un_op); |
| 4199 | 4204 | const err_union_ty = func.typeOf(un_op); |
| ... | ... | @@ -4228,7 +4233,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro |
| 4228 | 4233 | } |
| 4229 | 4234 | |
| 4230 | 4235 | fn 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.?; | |
| 4232 | 4237 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4233 | 4238 | |
| 4234 | 4239 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4256,7 +4261,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo |
| 4256 | 4261 | } |
| 4257 | 4262 | |
| 4258 | 4263 | fn 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.?; | |
| 4260 | 4265 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4261 | 4266 | |
| 4262 | 4267 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4280,7 +4285,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) |
| 4280 | 4285 | } |
| 4281 | 4286 | |
| 4282 | 4287 | fn 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.?; | |
| 4284 | 4289 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4285 | 4290 | |
| 4286 | 4291 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4310,7 +4315,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 4310 | 4315 | } |
| 4311 | 4316 | |
| 4312 | 4317 | fn 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.?; | |
| 4314 | 4319 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4315 | 4320 | |
| 4316 | 4321 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4342,7 +4347,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4342 | 4347 | const ty = ty_op.ty.toType(); |
| 4343 | 4348 | const operand = try func.resolveInst(ty_op.operand); |
| 4344 | 4349 | 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.?; | |
| 4346 | 4351 | if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) { |
| 4347 | 4352 | return func.fail("todo Wasm intcast for vectors", .{}); |
| 4348 | 4353 | } |
| ... | ... | @@ -4365,7 +4370,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4365 | 4370 | /// Asserts type's bitsize <= 128 |
| 4366 | 4371 | /// NOTE: May leave the result on the top of the stack. |
| 4367 | 4372 | fn 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.?; | |
| 4369 | 4374 | const given_bitsize = @as(u16, @intCast(given.bitSize(mod))); |
| 4370 | 4375 | const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(mod))); |
| 4371 | 4376 | assert(given_bitsize <= 128); |
| ... | ... | @@ -4433,7 +4438,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 4433 | 4438 | } |
| 4434 | 4439 | |
| 4435 | 4440 | fn 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.?; | |
| 4437 | 4442 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4438 | 4443 | const operand = try func.resolveInst(un_op); |
| 4439 | 4444 | |
| ... | ... | @@ -4447,7 +4452,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: |
| 4447 | 4452 | /// For a given type and operand, checks if it's considered `null`. |
| 4448 | 4453 | /// NOTE: Leaves the result on the stack |
| 4449 | 4454 | fn 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.?; | |
| 4451 | 4456 | try func.emitWValue(operand); |
| 4452 | 4457 | const payload_ty = optional_ty.optionalChild(mod); |
| 4453 | 4458 | if (!optional_ty.optionalReprIsPayload(mod)) { |
| ... | ... | @@ -4475,7 +4480,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod |
| 4475 | 4480 | } |
| 4476 | 4481 | |
| 4477 | 4482 | fn 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.?; | |
| 4479 | 4484 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4480 | 4485 | const opt_ty = func.typeOf(ty_op.operand); |
| 4481 | 4486 | const payload_ty = func.typeOfIndex(inst); |
| ... | ... | @@ -4498,7 +4503,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4498 | 4503 | } |
| 4499 | 4504 | |
| 4500 | 4505 | fn 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.?; | |
| 4502 | 4507 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4503 | 4508 | const operand = try func.resolveInst(ty_op.operand); |
| 4504 | 4509 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); |
| ... | ... | @@ -4515,7 +4520,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4515 | 4520 | } |
| 4516 | 4521 | |
| 4517 | 4522 | fn 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.?; | |
| 4519 | 4524 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4520 | 4525 | const operand = try func.resolveInst(ty_op.operand); |
| 4521 | 4526 | const opt_ty = func.typeOf(ty_op.operand).childType(mod); |
| ... | ... | @@ -4543,7 +4548,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi |
| 4543 | 4548 | fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4544 | 4549 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4545 | 4550 | 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.?; | |
| 4547 | 4552 | |
| 4548 | 4553 | const result = result: { |
| 4549 | 4554 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| ... | ... | @@ -4600,7 +4605,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4600 | 4605 | } |
| 4601 | 4606 | |
| 4602 | 4607 | fn 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.?; | |
| 4604 | 4609 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4605 | 4610 | |
| 4606 | 4611 | const slice_ty = func.typeOf(bin_op.lhs); |
| ... | ... | @@ -4630,7 +4635,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4630 | 4635 | } |
| 4631 | 4636 | |
| 4632 | 4637 | fn 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.?; | |
| 4634 | 4639 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4635 | 4640 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4636 | 4641 | |
| ... | ... | @@ -4683,7 +4688,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4683 | 4688 | /// Truncates a given operand to a given type, discarding any overflown bits. |
| 4684 | 4689 | /// NOTE: Resulting value is left on the stack. |
| 4685 | 4690 | fn 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.?; | |
| 4687 | 4692 | const given_bits = @as(u16, @intCast(given_ty.bitSize(mod))); |
| 4688 | 4693 | if (toWasmBits(given_bits) == null) { |
| 4689 | 4694 | 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 { |
| 4707 | 4712 | } |
| 4708 | 4713 | |
| 4709 | 4714 | fn 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.?; | |
| 4711 | 4716 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4712 | 4717 | |
| 4713 | 4718 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -4730,7 +4735,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4730 | 4735 | } |
| 4731 | 4736 | |
| 4732 | 4737 | fn 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.?; | |
| 4734 | 4739 | const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 4735 | 4740 | const operand = try func.resolveInst(un_op); |
| 4736 | 4741 | const ptr_ty = func.typeOf(un_op); |
| ... | ... | @@ -4745,7 +4750,7 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4745 | 4750 | } |
| 4746 | 4751 | |
| 4747 | 4752 | fn 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.?; | |
| 4749 | 4754 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4750 | 4755 | |
| 4751 | 4756 | const ptr_ty = func.typeOf(bin_op.lhs); |
| ... | ... | @@ -4782,7 +4787,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4782 | 4787 | } |
| 4783 | 4788 | |
| 4784 | 4789 | fn 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.?; | |
| 4786 | 4791 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4787 | 4792 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4788 | 4793 | |
| ... | ... | @@ -4812,7 +4817,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4812 | 4817 | } |
| 4813 | 4818 | |
| 4814 | 4819 | fn 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.?; | |
| 4816 | 4821 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 4817 | 4822 | const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 4818 | 4823 | |
| ... | ... | @@ -4840,7 +4845,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 4840 | 4845 | } |
| 4841 | 4846 | |
| 4842 | 4847 | fn 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.?; | |
| 4844 | 4849 | if (safety) { |
| 4845 | 4850 | // TODO if the value is undef, write 0xaa bytes to dest |
| 4846 | 4851 | } else { |
| ... | ... | @@ -4873,7 +4878,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void |
| 4873 | 4878 | /// this to wasm's memset instruction. When the feature is not present, |
| 4874 | 4879 | /// we implement it manually. |
| 4875 | 4880 | fn 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.?; | |
| 4877 | 4882 | const abi_size = @as(u32, @intCast(elem_ty.abiSize(mod))); |
| 4878 | 4883 | |
| 4879 | 4884 | // 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 |
| 4962 | 4967 | } |
| 4963 | 4968 | |
| 4964 | 4969 | fn 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.?; | |
| 4966 | 4971 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4967 | 4972 | |
| 4968 | 4973 | const array_ty = func.typeOf(bin_op.lhs); |
| ... | ... | @@ -5031,7 +5036,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5031 | 5036 | } |
| 5032 | 5037 | |
| 5033 | 5038 | fn 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.?; | |
| 5035 | 5040 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5036 | 5041 | |
| 5037 | 5042 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -5076,7 +5081,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5076 | 5081 | } |
| 5077 | 5082 | |
| 5078 | 5083 | fn 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.?; | |
| 5080 | 5085 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5081 | 5086 | |
| 5082 | 5087 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -5122,7 +5127,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5122 | 5127 | } |
| 5123 | 5128 | |
| 5124 | 5129 | fn 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.?; | |
| 5126 | 5131 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5127 | 5132 | const operand = try func.resolveInst(ty_op.operand); |
| 5128 | 5133 | const ty = func.typeOfIndex(inst); |
| ... | ... | @@ -5201,7 +5206,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5201 | 5206 | } |
| 5202 | 5207 | |
| 5203 | 5208 | fn 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.?; | |
| 5205 | 5210 | const inst_ty = func.typeOfIndex(inst); |
| 5206 | 5211 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5207 | 5212 | 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 { |
| 5270 | 5275 | } |
| 5271 | 5276 | |
| 5272 | 5277 | fn 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.?; | |
| 5274 | 5279 | const ip = &mod.intern_pool; |
| 5275 | 5280 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5276 | 5281 | const result_ty = func.typeOfIndex(inst); |
| ... | ... | @@ -5400,7 +5405,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5400 | 5405 | } |
| 5401 | 5406 | |
| 5402 | 5407 | fn 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.?; | |
| 5404 | 5409 | const ip = &mod.intern_pool; |
| 5405 | 5410 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5406 | 5411 | const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| ... | ... | @@ -5499,7 +5504,7 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void { |
| 5499 | 5504 | } |
| 5500 | 5505 | |
| 5501 | 5506 | fn 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.?; | |
| 5503 | 5508 | assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 5504 | 5509 | assert(op == .eq or op == .neq); |
| 5505 | 5510 | const payload_ty = operand_ty.optionalChild(mod); |
| ... | ... | @@ -5535,7 +5540,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: |
| 5535 | 5540 | /// NOTE: Leaves the result of the comparison on top of the stack. |
| 5536 | 5541 | /// TODO: Lower this to compiler_rt call when bitsize > 128 |
| 5537 | 5542 | fn 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.?; | |
| 5539 | 5544 | assert(operand_ty.abiSize(mod) >= 16); |
| 5540 | 5545 | assert(!(lhs != .stack and rhs == .stack)); |
| 5541 | 5546 | if (operand_ty.bitSize(mod) > 128) { |
| ... | ... | @@ -5577,7 +5582,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std |
| 5577 | 5582 | } |
| 5578 | 5583 | |
| 5579 | 5584 | fn 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.?; | |
| 5581 | 5586 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5582 | 5587 | const un_ty = func.typeOf(bin_op.lhs).childType(mod); |
| 5583 | 5588 | const tag_ty = func.typeOf(bin_op.rhs); |
| ... | ... | @@ -5601,7 +5606,7 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5601 | 5606 | } |
| 5602 | 5607 | |
| 5603 | 5608 | fn 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.?; | |
| 5605 | 5610 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5606 | 5611 | |
| 5607 | 5612 | const un_ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -5706,7 +5711,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro |
| 5706 | 5711 | } |
| 5707 | 5712 | |
| 5708 | 5713 | fn 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.?; | |
| 5710 | 5715 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5711 | 5716 | |
| 5712 | 5717 | 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 |
| 5732 | 5737 | } |
| 5733 | 5738 | |
| 5734 | 5739 | fn 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.?; | |
| 5736 | 5741 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5737 | 5742 | const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 5738 | 5743 | |
| ... | ... | @@ -5753,7 +5758,7 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5753 | 5758 | } |
| 5754 | 5759 | |
| 5755 | 5760 | fn 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.?; | |
| 5757 | 5762 | if (ptr_ty.isSlice(mod)) { |
| 5758 | 5763 | return func.slicePtr(ptr); |
| 5759 | 5764 | } else { |
| ... | ... | @@ -5762,7 +5767,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue |
| 5762 | 5767 | } |
| 5763 | 5768 | |
| 5764 | 5769 | fn 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.?; | |
| 5766 | 5771 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5767 | 5772 | const dst = try func.resolveInst(bin_op.lhs); |
| 5768 | 5773 | const dst_ty = func.typeOf(bin_op.lhs); |
| ... | ... | @@ -5802,7 +5807,7 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5802 | 5807 | } |
| 5803 | 5808 | |
| 5804 | 5809 | fn 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.?; | |
| 5806 | 5811 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5807 | 5812 | |
| 5808 | 5813 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -5863,7 +5868,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5863 | 5868 | // to make a copy of the ptr+value but can point towards them directly. |
| 5864 | 5869 | const error_table_symbol = try func.bin_file.getErrorTableSymbol(); |
| 5865 | 5870 | 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.?; | |
| 5867 | 5872 | const abi_size = name_ty.abiSize(mod); |
| 5868 | 5873 | |
| 5869 | 5874 | 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 |
| 5903 | 5908 | const lhs_op = try func.resolveInst(extra.lhs); |
| 5904 | 5909 | const rhs_op = try func.resolveInst(extra.rhs); |
| 5905 | 5910 | 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.?; | |
| 5907 | 5912 | |
| 5908 | 5913 | if (lhs_ty.zigTypeTag(mod) == .Vector) { |
| 5909 | 5914 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| ... | ... | @@ -5975,7 +5980,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro |
| 5975 | 5980 | } |
| 5976 | 5981 | |
| 5977 | 5982 | fn 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.?; | |
| 5979 | 5984 | assert(op == .add or op == .sub); |
| 5980 | 5985 | const int_info = ty.intInfo(mod); |
| 5981 | 5986 | const is_signed = int_info.signedness == .signed; |
| ... | ... | @@ -6040,7 +6045,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, |
| 6040 | 6045 | } |
| 6041 | 6046 | |
| 6042 | 6047 | fn 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.?; | |
| 6044 | 6049 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6045 | 6050 | const extra = func.air.extraData(Air.Bin, ty_pl.payload).data; |
| 6046 | 6051 | |
| ... | ... | @@ -6103,7 +6108,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6103 | 6108 | const lhs = try func.resolveInst(extra.lhs); |
| 6104 | 6109 | const rhs = try func.resolveInst(extra.rhs); |
| 6105 | 6110 | 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.?; | |
| 6107 | 6112 | |
| 6108 | 6113 | if (lhs_ty.zigTypeTag(mod) == .Vector) { |
| 6109 | 6114 | return func.fail("TODO: Implement overflow arithmetic for vectors", .{}); |
| ... | ... | @@ -6273,7 +6278,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6273 | 6278 | |
| 6274 | 6279 | fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6275 | 6280 | assert(op == .max or op == .min); |
| 6276 | const mod = func.bin_file.base.options.module.?; | |
| 6281 | const mod = func.bin_file.base.comp.module.?; | |
| 6277 | 6282 | const target = mod.getTarget(); |
| 6278 | 6283 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6279 | 6284 | |
| ... | ... | @@ -6317,7 +6322,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6317 | 6322 | } |
| 6318 | 6323 | |
| 6319 | 6324 | fn 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.?; | |
| 6321 | 6326 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6322 | 6327 | const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data; |
| 6323 | 6328 | |
| ... | ... | @@ -6351,7 +6356,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6351 | 6356 | } |
| 6352 | 6357 | |
| 6353 | 6358 | fn 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.?; | |
| 6355 | 6360 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6356 | 6361 | |
| 6357 | 6362 | const ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -6404,7 +6409,7 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6404 | 6409 | } |
| 6405 | 6410 | |
| 6406 | 6411 | fn 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.?; | |
| 6408 | 6413 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6409 | 6414 | |
| 6410 | 6415 | const ty = func.typeOf(ty_op.operand); |
| ... | ... | @@ -6471,7 +6476,7 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6471 | 6476 | fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void { |
| 6472 | 6477 | if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{}); |
| 6473 | 6478 | |
| 6474 | const mod = func.bin_file.base.options.module.?; | |
| 6479 | const mod = func.bin_file.base.comp.module.?; | |
| 6475 | 6480 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6476 | 6481 | const ty = func.typeOf(pl_op.operand); |
| 6477 | 6482 | const operand = try func.resolveInst(pl_op.operand); |
| ... | ... | @@ -6517,7 +6522,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6517 | 6522 | } |
| 6518 | 6523 | |
| 6519 | 6524 | fn 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.?; | |
| 6521 | 6526 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6522 | 6527 | const extra = func.air.extraData(Air.TryPtr, ty_pl.payload); |
| 6523 | 6528 | const err_union_ptr = try func.resolveInst(extra.data.ptr); |
| ... | ... | @@ -6535,7 +6540,7 @@ fn lowerTry( |
| 6535 | 6540 | err_union_ty: Type, |
| 6536 | 6541 | operand_is_ptr: bool, |
| 6537 | 6542 | ) InnerError!WValue { |
| 6538 | const mod = func.bin_file.base.options.module.?; | |
| 6543 | const mod = func.bin_file.base.comp.module.?; | |
| 6539 | 6544 | if (operand_is_ptr) { |
| 6540 | 6545 | return func.fail("TODO: lowerTry for pointers", .{}); |
| 6541 | 6546 | } |
| ... | ... | @@ -6584,7 +6589,7 @@ fn lowerTry( |
| 6584 | 6589 | } |
| 6585 | 6590 | |
| 6586 | 6591 | fn 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.?; | |
| 6588 | 6593 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6589 | 6594 | |
| 6590 | 6595 | const ty = func.typeOfIndex(inst); |
| ... | ... | @@ -6655,7 +6660,7 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6655 | 6660 | } |
| 6656 | 6661 | |
| 6657 | 6662 | fn 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.?; | |
| 6659 | 6664 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6660 | 6665 | |
| 6661 | 6666 | const ty = func.typeOfIndex(inst); |
| ... | ... | @@ -6670,7 +6675,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6670 | 6675 | } |
| 6671 | 6676 | |
| 6672 | 6677 | fn 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.?; | |
| 6674 | 6679 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6675 | 6680 | |
| 6676 | 6681 | const ty = func.typeOfIndex(inst); |
| ... | ... | @@ -6693,7 +6698,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6693 | 6698 | fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6694 | 6699 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6695 | 6700 | |
| 6696 | const mod = func.bin_file.base.options.module.?; | |
| 6701 | const mod = func.bin_file.base.comp.module.?; | |
| 6697 | 6702 | const ty = func.typeOfIndex(inst); |
| 6698 | 6703 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6699 | 6704 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -6806,7 +6811,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6806 | 6811 | } |
| 6807 | 6812 | |
| 6808 | 6813 | fn 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.?; | |
| 6810 | 6815 | const int_bits = ty.intInfo(mod).bits; |
| 6811 | 6816 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 6812 | 6817 | 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 |
| 6836 | 6841 | fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6837 | 6842 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6838 | 6843 | |
| 6839 | const mod = func.bin_file.base.options.module.?; | |
| 6844 | const mod = func.bin_file.base.comp.module.?; | |
| 6840 | 6845 | const ty = func.typeOfIndex(inst); |
| 6841 | 6846 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6842 | 6847 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -6883,7 +6888,7 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6883 | 6888 | /// The result will be sign extended to 32 bits if N <= 32 or 64 bits if N <= 64. |
| 6884 | 6889 | /// Support for integers wider than 64 bits has not yet been implemented. |
| 6885 | 6890 | fn 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.?; | |
| 6887 | 6892 | const int_bits = ty.intInfo(mod).bits; |
| 6888 | 6893 | const wasm_bits = toWasmBits(int_bits) orelse { |
| 6889 | 6894 | 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 { |
| 6919 | 6924 | assert(op == .add or op == .sub); |
| 6920 | 6925 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6921 | 6926 | |
| 6922 | const mod = func.bin_file.base.options.module.?; | |
| 6927 | const mod = func.bin_file.base.comp.module.?; | |
| 6923 | 6928 | const ty = func.typeOfIndex(inst); |
| 6924 | 6929 | const lhs = try func.resolveInst(bin_op.lhs); |
| 6925 | 6930 | const rhs = try func.resolveInst(bin_op.rhs); |
| ... | ... | @@ -6967,7 +6972,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { |
| 6967 | 6972 | } |
| 6968 | 6973 | |
| 6969 | 6974 | fn 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.?; | |
| 6971 | 6976 | const int_info = ty.intInfo(mod); |
| 6972 | 6977 | const wasm_bits = toWasmBits(int_info.bits).?; |
| 6973 | 6978 | 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, |
| 7034 | 7039 | fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7035 | 7040 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7036 | 7041 | |
| 7037 | const mod = func.bin_file.base.options.module.?; | |
| 7042 | const mod = func.bin_file.base.comp.module.?; | |
| 7038 | 7043 | const ty = func.typeOfIndex(inst); |
| 7039 | 7044 | const int_info = ty.intInfo(mod); |
| 7040 | 7045 | const is_signed = int_info.signedness == .signed; |
| ... | ... | @@ -7155,7 +7160,7 @@ fn callIntrinsic( |
| 7155 | 7160 | }; |
| 7156 | 7161 | |
| 7157 | 7162 | // Always pass over C-ABI |
| 7158 | const mod = func.bin_file.base.options.module.?; | |
| 7163 | const mod = func.bin_file.base.comp.module.?; | |
| 7159 | 7164 | var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod); |
| 7160 | 7165 | defer func_type.deinit(func.gpa); |
| 7161 | 7166 | 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 { |
| 7208 | 7213 | } |
| 7209 | 7214 | |
| 7210 | 7215 | fn 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.?; | |
| 7212 | 7217 | const enum_decl_index = enum_ty.getOwnerDecl(mod); |
| 7213 | 7218 | |
| 7214 | 7219 | var arena_allocator = std.heap.ArenaAllocator.init(func.gpa); |
| ... | ... | @@ -7364,7 +7369,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7364 | 7369 | } |
| 7365 | 7370 | |
| 7366 | 7371 | fn 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.?; | |
| 7368 | 7373 | const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7369 | 7374 | |
| 7370 | 7375 | const operand = try func.resolveInst(ty_op.operand); |
| ... | ... | @@ -7449,7 +7454,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool { |
| 7449 | 7454 | } |
| 7450 | 7455 | |
| 7451 | 7456 | fn 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.?; | |
| 7453 | 7458 | const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7454 | 7459 | const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7455 | 7460 | |
| ... | ... | @@ -7522,7 +7527,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7522 | 7527 | } |
| 7523 | 7528 | |
| 7524 | 7529 | fn 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.?; | |
| 7526 | 7531 | const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; |
| 7527 | 7532 | const ptr = try func.resolveInst(atomic_load.ptr); |
| 7528 | 7533 | const ty = func.typeOfIndex(inst); |
| ... | ... | @@ -7549,7 +7554,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7549 | 7554 | } |
| 7550 | 7555 | |
| 7551 | 7556 | fn 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.?; | |
| 7553 | 7558 | const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 7554 | 7559 | const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 7555 | 7560 | |
| ... | ... | @@ -7724,10 +7729,13 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7724 | 7729 | } |
| 7725 | 7730 | |
| 7726 | 7731 | fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7732 | const zcu = func.bin_file.base.comp.module.?; | |
| 7727 | 7733 | // Only when the atomic feature is enabled, and we're not building |
| 7728 | 7734 | // for a single-threaded build, can we emit the `fence` instruction. |
| 7729 | 7735 | // 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) { | |
| 7731 | 7739 | try func.addAtomicTag(.atomic_fence); |
| 7732 | 7740 | } |
| 7733 | 7741 | |
| ... | ... | @@ -7735,7 +7743,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7735 | 7743 | } |
| 7736 | 7744 | |
| 7737 | 7745 | fn 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.?; | |
| 7739 | 7747 | const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7740 | 7748 | |
| 7741 | 7749 | const ptr = try func.resolveInst(bin_op.lhs); |
| ... | ... | @@ -7774,11 +7782,11 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7774 | 7782 | } |
| 7775 | 7783 | |
| 7776 | 7784 | fn 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.?; | |
| 7778 | 7786 | return func.air.typeOf(inst, &mod.intern_pool); |
| 7779 | 7787 | } |
| 7780 | 7788 | |
| 7781 | 7789 | fn 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.?; | |
| 7783 | 7791 | return func.air.typeOfIndex(inst, &mod.intern_pool); |
| 7784 | 7792 | } |
src/arch/wasm/Emit.zig+18-7| ... | ... | @@ -254,8 +254,10 @@ fn offset(self: Emit) u32 { |
| 254 | 254 | fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 255 | 255 | @setCold(true); |
| 256 | 256 | 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); | |
| 259 | 261 | return error.EmitFail; |
| 260 | 262 | } |
| 261 | 263 | |
| ... | ... | @@ -299,6 +301,8 @@ fn emitLabel(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { |
| 299 | 301 | } |
| 300 | 302 | |
| 301 | 303 | fn 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; | |
| 302 | 306 | const label = emit.mir.instructions.items(.data)[inst].label; |
| 303 | 307 | try emit.code.append(@intFromEnum(tag)); |
| 304 | 308 | var buf: [5]u8 = undefined; |
| ... | ... | @@ -308,7 +312,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { |
| 308 | 312 | |
| 309 | 313 | const atom_index = emit.bin_file.decls.get(emit.decl_index).?; |
| 310 | 314 | const atom = emit.bin_file.getAtomPtr(atom_index); |
| 311 | try atom.relocs.append(emit.bin_file.base.allocator, .{ | |
| 315 | try atom.relocs.append(gpa, .{ | |
| 312 | 316 | .index = label, |
| 313 | 317 | .offset = global_offset, |
| 314 | 318 | .relocation_type = .R_WASM_GLOBAL_INDEX_LEB, |
| ... | ... | @@ -356,6 +360,8 @@ fn encodeMemArg(mem_arg: Mir.MemArg, writer: anytype) !void { |
| 356 | 360 | } |
| 357 | 361 | |
| 358 | 362 | fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 363 | const comp = emit.bin_file.base.comp; | |
| 364 | const gpa = comp.gpa; | |
| 359 | 365 | const label = emit.mir.instructions.items(.data)[inst].label; |
| 360 | 366 | try emit.code.append(std.wasm.opcode(.call)); |
| 361 | 367 | const call_offset = emit.offset(); |
| ... | ... | @@ -366,7 +372,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 366 | 372 | if (label != 0) { |
| 367 | 373 | const atom_index = emit.bin_file.decls.get(emit.decl_index).?; |
| 368 | 374 | const atom = emit.bin_file.getAtomPtr(atom_index); |
| 369 | try atom.relocs.append(emit.bin_file.base.allocator, .{ | |
| 375 | try atom.relocs.append(gpa, .{ | |
| 370 | 376 | .offset = call_offset, |
| 371 | 377 | .index = label, |
| 372 | 378 | .relocation_type = .R_WASM_FUNCTION_INDEX_LEB, |
| ... | ... | @@ -384,6 +390,8 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 384 | 390 | } |
| 385 | 391 | |
| 386 | 392 | fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 393 | const comp = emit.bin_file.base.comp; | |
| 394 | const gpa = comp.gpa; | |
| 387 | 395 | const symbol_index = emit.mir.instructions.items(.data)[inst].label; |
| 388 | 396 | try emit.code.append(std.wasm.opcode(.i32_const)); |
| 389 | 397 | const index_offset = emit.offset(); |
| ... | ... | @@ -394,7 +402,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 394 | 402 | if (symbol_index != 0) { |
| 395 | 403 | const atom_index = emit.bin_file.decls.get(emit.decl_index).?; |
| 396 | 404 | const atom = emit.bin_file.getAtomPtr(atom_index); |
| 397 | try atom.relocs.append(emit.bin_file.base.allocator, .{ | |
| 405 | try atom.relocs.append(gpa, .{ | |
| 398 | 406 | .offset = index_offset, |
| 399 | 407 | .index = symbol_index, |
| 400 | 408 | .relocation_type = .R_WASM_TABLE_INDEX_SLEB, |
| ... | ... | @@ -406,7 +414,10 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 406 | 414 | const extra_index = emit.mir.instructions.items(.data)[inst].payload; |
| 407 | 415 | const mem = emit.mir.extraData(Mir.Memory, extra_index).data; |
| 408 | 416 | 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; | |
| 410 | 421 | if (is_wasm32) { |
| 411 | 422 | try emit.code.append(std.wasm.opcode(.i32_const)); |
| 412 | 423 | var buf: [5]u8 = undefined; |
| ... | ... | @@ -422,7 +433,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 422 | 433 | if (mem.pointer != 0) { |
| 423 | 434 | const atom_index = emit.bin_file.decls.get(emit.decl_index).?; |
| 424 | 435 | const atom = emit.bin_file.getAtomPtr(atom_index); |
| 425 | try atom.relocs.append(emit.bin_file.base.allocator, .{ | |
| 436 | try atom.relocs.append(gpa, .{ | |
| 426 | 437 | .offset = mem_offset, |
| 427 | 438 | .index = mem.pointer, |
| 428 | 439 | .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"); |
| 25 | 25 | const Liveness = @import("../../Liveness.zig"); |
| 26 | 26 | const Lower = @import("Lower.zig"); |
| 27 | 27 | const Mir = @import("Mir.zig"); |
| 28 | const Package = @import("../../Package.zig"); | |
| 28 | 29 | const Module = @import("../../Module.zig"); |
| 30 | const Zcu = Module; | |
| 29 | 31 | const InternPool = @import("../../InternPool.zig"); |
| 30 | 32 | const Alignment = InternPool.Alignment; |
| 31 | 33 | const Target = std.Target; |
| ... | ... | @@ -56,6 +58,7 @@ bin_file: *link.File, |
| 56 | 58 | debug_output: DebugInfoOutput, |
| 57 | 59 | target: *const std.Target, |
| 58 | 60 | owner: Owner, |
| 61 | mod: *Package.Module, | |
| 59 | 62 | err_msg: ?*ErrorMsg, |
| 60 | 63 | args: []MCValue, |
| 61 | 64 | va_info: union { |
| ... | ... | @@ -131,7 +134,7 @@ const Owner = union(enum) { |
| 131 | 134 | fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 { |
| 132 | 135 | switch (owner) { |
| 133 | 136 | .func_index => |func_index| { |
| 134 | const mod = ctx.bin_file.options.module.?; | |
| 137 | const mod = ctx.bin_file.comp.module.?; | |
| 135 | 138 | const decl_index = mod.funcOwnerDeclIndex(func_index); |
| 136 | 139 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { |
| 137 | 140 | return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index); |
| ... | ... | @@ -795,22 +798,22 @@ pub fn generate( |
| 795 | 798 | code: *std.ArrayList(u8), |
| 796 | 799 | debug_output: DebugInfoOutput, |
| 797 | 800 | ) 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); | |
| 805 | 806 | assert(fn_owner_decl.has_tv); |
| 806 | 807 | const fn_type = fn_owner_decl.ty; |
| 808 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | |
| 809 | const mod = namespace.file_scope.mod; | |
| 807 | 810 | |
| 808 | const gpa = bin_file.allocator; | |
| 809 | 811 | var function = Self{ |
| 810 | 812 | .gpa = gpa, |
| 811 | 813 | .air = air, |
| 812 | 814 | .liveness = liveness, |
| 813 | .target = &bin_file.options.target, | |
| 815 | .target = &mod.resolved_target.result, | |
| 816 | .mod = mod, | |
| 814 | 817 | .bin_file = bin_file, |
| 815 | 818 | .debug_output = debug_output, |
| 816 | 819 | .owner = .{ .func_index = func_index }, |
| ... | ... | @@ -841,7 +844,7 @@ pub fn generate( |
| 841 | 844 | |
| 842 | 845 | wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)}); |
| 843 | 846 | |
| 844 | const ip = &mod.intern_pool; | |
| 847 | const ip = &zcu.intern_pool; | |
| 845 | 848 | |
| 846 | 849 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 847 | 850 | function.frame_allocs.set( |
| ... | ... | @@ -856,13 +859,13 @@ pub fn generate( |
| 856 | 859 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), |
| 857 | 860 | ); |
| 858 | 861 | |
| 859 | const fn_info = mod.typeToFunc(fn_type).?; | |
| 862 | const fn_info = zcu.typeToFunc(fn_type).?; | |
| 860 | 863 | const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*); |
| 861 | 864 | var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) { |
| 862 | 865 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 863 | 866 | error.OutOfRegisters => return Result{ |
| 864 | 867 | .fail = try ErrorMsg.create( |
| 865 | bin_file.allocator, | |
| 868 | gpa, | |
| 866 | 869 | src_loc, |
| 867 | 870 | "CodeGen ran out of registers. This is a bug in the Zig compiler.", |
| 868 | 871 | .{}, |
| ... | ... | @@ -875,14 +878,14 @@ pub fn generate( |
| 875 | 878 | function.args = call_info.args; |
| 876 | 879 | function.ret_mcv = call_info.return_value; |
| 877 | 880 | 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), | |
| 880 | 883 | })); |
| 881 | 884 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 882 | .size = Type.usize.abiSize(mod), | |
| 885 | .size = Type.usize.abiSize(zcu), | |
| 883 | 886 | .alignment = Alignment.min( |
| 884 | 887 | call_info.stack_align, |
| 885 | Alignment.fromNonzeroByteUnits(bin_file.options.target.stackAlignment()), | |
| 888 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), | |
| 886 | 889 | ), |
| 887 | 890 | })); |
| 888 | 891 | function.frame_allocs.set( |
| ... | ... | @@ -906,25 +909,28 @@ pub fn generate( |
| 906 | 909 | function.gen() catch |err| switch (err) { |
| 907 | 910 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 908 | 911 | 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.", .{}), | |
| 910 | 913 | }, |
| 911 | 914 | else => |e| return e, |
| 912 | 915 | }; |
| 913 | 916 | |
| 914 | 917 | var mir = Mir{ |
| 915 | 918 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 916 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 919 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 917 | 920 | .frame_locs = function.frame_locs.toOwnedSlice(), |
| 918 | 921 | }; |
| 919 | defer mir.deinit(bin_file.allocator); | |
| 922 | defer mir.deinit(gpa); | |
| 920 | 923 | |
| 921 | 924 | var emit = Emit{ |
| 922 | 925 | .lower = .{ |
| 923 | 926 | .bin_file = bin_file, |
| 924 | .allocator = bin_file.allocator, | |
| 927 | .allocator = gpa, | |
| 925 | 928 | .mir = mir, |
| 926 | 929 | .cc = cc, |
| 927 | 930 | .src_loc = src_loc, |
| 931 | .output_mode = comp.config.output_mode, | |
| 932 | .link_mode = comp.config.link_mode, | |
| 933 | .pic = mod.pic, | |
| 928 | 934 | }, |
| 929 | 935 | .debug_output = debug_output, |
| 930 | 936 | .code = code, |
| ... | ... | @@ -942,7 +948,7 @@ pub fn generate( |
| 942 | 948 | }; |
| 943 | 949 | return Result{ |
| 944 | 950 | .fail = try ErrorMsg.create( |
| 945 | bin_file.allocator, | |
| 951 | gpa, | |
| 946 | 952 | src_loc, |
| 947 | 953 | "{s} This is a bug in the Zig compiler.", |
| 948 | 954 | .{msg}, |
| ... | ... | @@ -966,12 +972,16 @@ pub fn generateLazy( |
| 966 | 972 | code: *std.ArrayList(u8), |
| 967 | 973 | debug_output: DebugInfoOutput, |
| 968 | 974 | ) 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; | |
| 970 | 979 | var function = Self{ |
| 971 | 980 | .gpa = gpa, |
| 972 | 981 | .air = undefined, |
| 973 | 982 | .liveness = undefined, |
| 974 | .target = &bin_file.options.target, | |
| 983 | .target = &mod.resolved_target.result, | |
| 984 | .mod = mod, | |
| 975 | 985 | .bin_file = bin_file, |
| 976 | 986 | .debug_output = debug_output, |
| 977 | 987 | .owner = .{ .lazy_sym = lazy_sym }, |
| ... | ... | @@ -993,25 +1003,28 @@ pub fn generateLazy( |
| 993 | 1003 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 994 | 1004 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| 995 | 1005 | 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.", .{}), | |
| 997 | 1007 | }, |
| 998 | 1008 | else => |e| return e, |
| 999 | 1009 | }; |
| 1000 | 1010 | |
| 1001 | 1011 | var mir = Mir{ |
| 1002 | 1012 | .instructions = function.mir_instructions.toOwnedSlice(), |
| 1003 | .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator), | |
| 1013 | .extra = try function.mir_extra.toOwnedSlice(gpa), | |
| 1004 | 1014 | .frame_locs = function.frame_locs.toOwnedSlice(), |
| 1005 | 1015 | }; |
| 1006 | defer mir.deinit(bin_file.allocator); | |
| 1016 | defer mir.deinit(gpa); | |
| 1007 | 1017 | |
| 1008 | 1018 | var emit = Emit{ |
| 1009 | 1019 | .lower = .{ |
| 1010 | 1020 | .bin_file = bin_file, |
| 1011 | .allocator = bin_file.allocator, | |
| 1021 | .allocator = gpa, | |
| 1012 | 1022 | .mir = mir, |
| 1013 | 1023 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), |
| 1014 | 1024 | .src_loc = src_loc, |
| 1025 | .output_mode = comp.config.output_mode, | |
| 1026 | .link_mode = comp.config.link_mode, | |
| 1027 | .pic = mod.pic, | |
| 1015 | 1028 | }, |
| 1016 | 1029 | .debug_output = debug_output, |
| 1017 | 1030 | .code = code, |
| ... | ... | @@ -1029,7 +1042,7 @@ pub fn generateLazy( |
| 1029 | 1042 | }; |
| 1030 | 1043 | return Result{ |
| 1031 | 1044 | .fail = try ErrorMsg.create( |
| 1032 | bin_file.allocator, | |
| 1045 | gpa, | |
| 1033 | 1046 | src_loc, |
| 1034 | 1047 | "{s} This is a bug in the Zig compiler.", |
| 1035 | 1048 | .{msg}, |
| ... | ... | @@ -1060,7 +1073,7 @@ fn formatDecl( |
| 1060 | 1073 | } |
| 1061 | 1074 | fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { |
| 1062 | 1075 | return .{ .data = .{ |
| 1063 | .mod = self.bin_file.options.module.?, | |
| 1076 | .mod = self.bin_file.comp.module.?, | |
| 1064 | 1077 | .decl_index = decl_index, |
| 1065 | 1078 | } }; |
| 1066 | 1079 | } |
| ... | ... | @@ -1077,7 +1090,7 @@ fn formatAir( |
| 1077 | 1090 | ) @TypeOf(writer).Error!void { |
| 1078 | 1091 | @import("../../print_air.zig").dumpInst( |
| 1079 | 1092 | data.inst, |
| 1080 | data.self.bin_file.options.module.?, | |
| 1093 | data.self.bin_file.comp.module.?, | |
| 1081 | 1094 | data.self.air, |
| 1082 | 1095 | data.self.liveness, |
| 1083 | 1096 | ); |
| ... | ... | @@ -1096,6 +1109,8 @@ fn formatWipMir( |
| 1096 | 1109 | _: std.fmt.FormatOptions, |
| 1097 | 1110 | writer: anytype, |
| 1098 | 1111 | ) @TypeOf(writer).Error!void { |
| 1112 | const comp = data.self.bin_file.comp; | |
| 1113 | const mod = comp.root_mod; | |
| 1099 | 1114 | var lower = Lower{ |
| 1100 | 1115 | .bin_file = data.self.bin_file, |
| 1101 | 1116 | .allocator = data.self.gpa, |
| ... | ... | @@ -1106,6 +1121,9 @@ fn formatWipMir( |
| 1106 | 1121 | }, |
| 1107 | 1122 | .cc = .Unspecified, |
| 1108 | 1123 | .src_loc = data.self.src_loc, |
| 1124 | .output_mode = comp.config.output_mode, | |
| 1125 | .link_mode = comp.config.link_mode, | |
| 1126 | .pic = mod.pic, | |
| 1109 | 1127 | }; |
| 1110 | 1128 | var first = true; |
| 1111 | 1129 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
| ... | ... | @@ -1683,7 +1701,7 @@ fn asmMemoryRegisterImmediate( |
| 1683 | 1701 | } |
| 1684 | 1702 | |
| 1685 | 1703 | fn gen(self: *Self) InnerError!void { |
| 1686 | const mod = self.bin_file.options.module.?; | |
| 1704 | const mod = self.bin_file.comp.module.?; | |
| 1687 | 1705 | const fn_info = mod.typeToFunc(self.fn_type).?; |
| 1688 | 1706 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); |
| 1689 | 1707 | if (cc != .Naked) { |
| ... | ... | @@ -1885,7 +1903,7 @@ fn gen(self: *Self) InnerError!void { |
| 1885 | 1903 | } |
| 1886 | 1904 | |
| 1887 | 1905 | fn 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.?; | |
| 1889 | 1907 | const ip = &mod.intern_pool; |
| 1890 | 1908 | const air_tags = self.air.instructions.items(.tag); |
| 1891 | 1909 | |
| ... | ... | @@ -2167,7 +2185,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2167 | 2185 | } |
| 2168 | 2186 | |
| 2169 | 2187 | fn 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.?; | |
| 2171 | 2189 | switch (lazy_sym.ty.zigTypeTag(mod)) { |
| 2172 | 2190 | .Enum => { |
| 2173 | 2191 | const enum_ty = lazy_sym.ty; |
| ... | ... | @@ -2418,7 +2436,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex { |
| 2418 | 2436 | |
| 2419 | 2437 | /// Use a pointer instruction as the basis for allocating stack memory. |
| 2420 | 2438 | fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { |
| 2421 | const mod = self.bin_file.options.module.?; | |
| 2439 | const mod = self.bin_file.comp.module.?; | |
| 2422 | 2440 | const ptr_ty = self.typeOfIndex(inst); |
| 2423 | 2441 | const val_ty = ptr_ty.childType(mod); |
| 2424 | 2442 | return self.allocFrameIndex(FrameAlloc.init(.{ |
| ... | ... | @@ -2438,7 +2456,7 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue { |
| 2438 | 2456 | } |
| 2439 | 2457 | |
| 2440 | 2458 | fn 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.?; | |
| 2442 | 2460 | const abi_size = math.cast(u32, ty.abiSize(mod)) orelse { |
| 2443 | 2461 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)}); |
| 2444 | 2462 | }; |
| ... | ... | @@ -2471,7 +2489,7 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b |
| 2471 | 2489 | } |
| 2472 | 2490 | |
| 2473 | 2491 | fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet { |
| 2474 | const mod = self.bin_file.options.module.?; | |
| 2492 | const mod = self.bin_file.comp.module.?; | |
| 2475 | 2493 | return switch (ty.zigTypeTag(mod)) { |
| 2476 | 2494 | .Float => switch (ty.floatBits(self.target.*)) { |
| 2477 | 2495 | 80 => abi.RegisterClass.x87, |
| ... | ... | @@ -2884,7 +2902,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void { |
| 2884 | 2902 | } |
| 2885 | 2903 | |
| 2886 | 2904 | fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2887 | const mod = self.bin_file.options.module.?; | |
| 2905 | const mod = self.bin_file.comp.module.?; | |
| 2888 | 2906 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2889 | 2907 | const result: MCValue = result: { |
| 2890 | 2908 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -2975,7 +2993,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 2975 | 2993 | } |
| 2976 | 2994 | |
| 2977 | 2995 | fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2978 | const mod = self.bin_file.options.module.?; | |
| 2996 | const mod = self.bin_file.comp.module.?; | |
| 2979 | 2997 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 2980 | 2998 | |
| 2981 | 2999 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -3102,7 +3120,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void { |
| 3102 | 3120 | } |
| 3103 | 3121 | |
| 3104 | 3122 | fn airSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3105 | const mod = self.bin_file.options.module.?; | |
| 3123 | const mod = self.bin_file.comp.module.?; | |
| 3106 | 3124 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3107 | 3125 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3108 | 3126 | |
| ... | ... | @@ -3131,7 +3149,7 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void { |
| 3131 | 3149 | } |
| 3132 | 3150 | |
| 3133 | 3151 | fn 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.?; | |
| 3135 | 3153 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3136 | 3154 | const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs); |
| 3137 | 3155 | |
| ... | ... | @@ -3172,7 +3190,7 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void |
| 3172 | 3190 | } |
| 3173 | 3191 | |
| 3174 | 3192 | fn 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.?; | |
| 3176 | 3194 | const air_tag = self.air.instructions.items(.tag); |
| 3177 | 3195 | const air_data = self.air.instructions.items(.data); |
| 3178 | 3196 | |
| ... | ... | @@ -3206,7 +3224,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 { |
| 3206 | 3224 | } |
| 3207 | 3225 | |
| 3208 | 3226 | fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3209 | const mod = self.bin_file.options.module.?; | |
| 3227 | const mod = self.bin_file.comp.module.?; | |
| 3210 | 3228 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3211 | 3229 | const result = result: { |
| 3212 | 3230 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| ... | ... | @@ -3432,7 +3450,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 3432 | 3450 | } |
| 3433 | 3451 | |
| 3434 | 3452 | fn airAddSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3435 | const mod = self.bin_file.options.module.?; | |
| 3453 | const mod = self.bin_file.comp.module.?; | |
| 3436 | 3454 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3437 | 3455 | const ty = self.typeOf(bin_op.lhs); |
| 3438 | 3456 | 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 { |
| 3515 | 3533 | } |
| 3516 | 3534 | |
| 3517 | 3535 | fn airSubSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3518 | const mod = self.bin_file.options.module.?; | |
| 3536 | const mod = self.bin_file.comp.module.?; | |
| 3519 | 3537 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3520 | 3538 | const ty = self.typeOf(bin_op.lhs); |
| 3521 | 3539 | 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 { |
| 3591 | 3609 | } |
| 3592 | 3610 | |
| 3593 | 3611 | fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3594 | const mod = self.bin_file.options.module.?; | |
| 3612 | const mod = self.bin_file.comp.module.?; | |
| 3595 | 3613 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 3596 | 3614 | const ty = self.typeOf(bin_op.lhs); |
| 3597 | 3615 | |
| ... | ... | @@ -3731,7 +3749,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void { |
| 3731 | 3749 | } |
| 3732 | 3750 | |
| 3733 | 3751 | fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3734 | const mod = self.bin_file.options.module.?; | |
| 3752 | const mod = self.bin_file.comp.module.?; | |
| 3735 | 3753 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3736 | 3754 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3737 | 3755 | const result: MCValue = result: { |
| ... | ... | @@ -3792,7 +3810,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3792 | 3810 | } |
| 3793 | 3811 | |
| 3794 | 3812 | fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3795 | const mod = self.bin_file.options.module.?; | |
| 3813 | const mod = self.bin_file.comp.module.?; | |
| 3796 | 3814 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3797 | 3815 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3798 | 3816 | const result: MCValue = result: { |
| ... | ... | @@ -3871,7 +3889,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3871 | 3889 | src_mcv: MCValue, |
| 3872 | 3890 | overflow_cc: ?Condition, |
| 3873 | 3891 | ) !void { |
| 3874 | const mod = self.bin_file.options.module.?; | |
| 3892 | const mod = self.bin_file.comp.module.?; | |
| 3875 | 3893 | const src_lock = switch (src_mcv) { |
| 3876 | 3894 | .register => |reg| self.register_manager.lockReg(reg), |
| 3877 | 3895 | else => null, |
| ... | ... | @@ -3935,7 +3953,7 @@ fn genSetFrameTruncatedOverflowCompare( |
| 3935 | 3953 | } |
| 3936 | 3954 | |
| 3937 | 3955 | fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3938 | const mod = self.bin_file.options.module.?; | |
| 3956 | const mod = self.bin_file.comp.module.?; | |
| 3939 | 3957 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 3940 | 3958 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3941 | 3959 | const tuple_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -4169,7 +4187,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 4169 | 4187 | /// Clobbers .rax and .rdx registers. |
| 4170 | 4188 | /// Quotient is saved in .rax and remainder in .rdx. |
| 4171 | 4189 | fn 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.?; | |
| 4173 | 4191 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 4174 | 4192 | const bit_size: u32 = @intCast(self.regBitSize(ty)); |
| 4175 | 4193 | if (abi_size > 8) { |
| ... | ... | @@ -4219,7 +4237,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue |
| 4219 | 4237 | /// Always returns a register. |
| 4220 | 4238 | /// Clobbers .rax and .rdx registers. |
| 4221 | 4239 | fn 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.?; | |
| 4223 | 4241 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 4224 | 4242 | const int_info = ty.intInfo(mod); |
| 4225 | 4243 | const dividend = switch (lhs) { |
| ... | ... | @@ -4271,7 +4289,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 4271 | 4289 | } |
| 4272 | 4290 | |
| 4273 | 4291 | fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void { |
| 4274 | const mod = self.bin_file.options.module.?; | |
| 4292 | const mod = self.bin_file.comp.module.?; | |
| 4275 | 4293 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 4276 | 4294 | |
| 4277 | 4295 | const air_tags = self.air.instructions.items(.tag); |
| ... | ... | @@ -4546,7 +4564,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void { |
| 4546 | 4564 | } |
| 4547 | 4565 | |
| 4548 | 4566 | fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 4549 | const mod = self.bin_file.options.module.?; | |
| 4567 | const mod = self.bin_file.comp.module.?; | |
| 4550 | 4568 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4551 | 4569 | const result: MCValue = result: { |
| 4552 | 4570 | const pl_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -4592,7 +4610,7 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4592 | 4610 | } |
| 4593 | 4611 | |
| 4594 | 4612 | fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4595 | const mod = self.bin_file.options.module.?; | |
| 4613 | const mod = self.bin_file.comp.module.?; | |
| 4596 | 4614 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4597 | 4615 | const result = result: { |
| 4598 | 4616 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -4626,7 +4644,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4626 | 4644 | } |
| 4627 | 4645 | |
| 4628 | 4646 | fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4629 | const mod = self.bin_file.options.module.?; | |
| 4647 | const mod = self.bin_file.comp.module.?; | |
| 4630 | 4648 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4631 | 4649 | const err_union_ty = self.typeOf(ty_op.operand); |
| 4632 | 4650 | const err_ty = err_union_ty.errorUnionSet(mod); |
| ... | ... | @@ -4678,7 +4696,7 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 4678 | 4696 | |
| 4679 | 4697 | // *(E!T) -> E |
| 4680 | 4698 | fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4681 | const mod = self.bin_file.options.module.?; | |
| 4699 | const mod = self.bin_file.comp.module.?; | |
| 4682 | 4700 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4683 | 4701 | |
| 4684 | 4702 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -4725,7 +4743,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4725 | 4743 | } |
| 4726 | 4744 | |
| 4727 | 4745 | fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { |
| 4728 | const mod = self.bin_file.options.module.?; | |
| 4746 | const mod = self.bin_file.comp.module.?; | |
| 4729 | 4747 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4730 | 4748 | const result: MCValue = result: { |
| 4731 | 4749 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -4785,7 +4803,7 @@ fn genUnwrapErrUnionPayloadMir( |
| 4785 | 4803 | err_union_ty: Type, |
| 4786 | 4804 | err_union: MCValue, |
| 4787 | 4805 | ) !MCValue { |
| 4788 | const mod = self.bin_file.options.module.?; | |
| 4806 | const mod = self.bin_file.comp.module.?; | |
| 4789 | 4807 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 4790 | 4808 | |
| 4791 | 4809 | const result: MCValue = result: { |
| ... | ... | @@ -4833,7 +4851,7 @@ fn genUnwrapErrUnionPayloadPtrMir( |
| 4833 | 4851 | ptr_ty: Type, |
| 4834 | 4852 | ptr_mcv: MCValue, |
| 4835 | 4853 | ) !MCValue { |
| 4836 | const mod = self.bin_file.options.module.?; | |
| 4854 | const mod = self.bin_file.comp.module.?; | |
| 4837 | 4855 | const err_union_ty = ptr_ty.childType(mod); |
| 4838 | 4856 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| 4839 | 4857 | |
| ... | ... | @@ -4867,7 +4885,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void { |
| 4867 | 4885 | } |
| 4868 | 4886 | |
| 4869 | 4887 | fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 4870 | const mod = self.bin_file.options.module.?; | |
| 4888 | const mod = self.bin_file.comp.module.?; | |
| 4871 | 4889 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4872 | 4890 | const result: MCValue = result: { |
| 4873 | 4891 | const pl_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -4921,7 +4939,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 4921 | 4939 | |
| 4922 | 4940 | /// T to E!T |
| 4923 | 4941 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 4924 | const mod = self.bin_file.options.module.?; | |
| 4942 | const mod = self.bin_file.comp.module.?; | |
| 4925 | 4943 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4926 | 4944 | |
| 4927 | 4945 | const eu_ty = ty_op.ty.toType(); |
| ... | ... | @@ -4944,7 +4962,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 4944 | 4962 | |
| 4945 | 4963 | /// E to E!T |
| 4946 | 4964 | fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 4947 | const mod = self.bin_file.options.module.?; | |
| 4965 | const mod = self.bin_file.comp.module.?; | |
| 4948 | 4966 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4949 | 4967 | |
| 4950 | 4968 | const eu_ty = ty_op.ty.toType(); |
| ... | ... | @@ -5003,7 +5021,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void { |
| 5003 | 5021 | } |
| 5004 | 5022 | |
| 5005 | 5023 | fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5006 | const mod = self.bin_file.options.module.?; | |
| 5024 | const mod = self.bin_file.comp.module.?; | |
| 5007 | 5025 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5008 | 5026 | |
| 5009 | 5027 | 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 |
| 5071 | 5089 | } |
| 5072 | 5090 | |
| 5073 | 5091 | fn 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.?; | |
| 5075 | 5093 | const slice_ty = self.typeOf(lhs); |
| 5076 | 5094 | const slice_mcv = try self.resolveInst(lhs); |
| 5077 | 5095 | 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 { |
| 5107 | 5125 | } |
| 5108 | 5126 | |
| 5109 | 5127 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5110 | const mod = self.bin_file.options.module.?; | |
| 5128 | const mod = self.bin_file.comp.module.?; | |
| 5111 | 5129 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5112 | 5130 | |
| 5113 | 5131 | const result: MCValue = result: { |
| ... | ... | @@ -5132,7 +5150,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5132 | 5150 | } |
| 5133 | 5151 | |
| 5134 | 5152 | fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5135 | const mod = self.bin_file.options.module.?; | |
| 5153 | const mod = self.bin_file.comp.module.?; | |
| 5136 | 5154 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5137 | 5155 | |
| 5138 | 5156 | const result: MCValue = result: { |
| ... | ... | @@ -5246,7 +5264,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5246 | 5264 | } |
| 5247 | 5265 | |
| 5248 | 5266 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5249 | const mod = self.bin_file.options.module.?; | |
| 5267 | const mod = self.bin_file.comp.module.?; | |
| 5250 | 5268 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5251 | 5269 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 5252 | 5270 | |
| ... | ... | @@ -5296,7 +5314,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 5296 | 5314 | } |
| 5297 | 5315 | |
| 5298 | 5316 | fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5299 | const mod = self.bin_file.options.module.?; | |
| 5317 | const mod = self.bin_file.comp.module.?; | |
| 5300 | 5318 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 5301 | 5319 | const extra = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 5302 | 5320 | |
| ... | ... | @@ -5341,7 +5359,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 5341 | 5359 | } |
| 5342 | 5360 | |
| 5343 | 5361 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5344 | const mod = self.bin_file.options.module.?; | |
| 5362 | const mod = self.bin_file.comp.module.?; | |
| 5345 | 5363 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 5346 | 5364 | const ptr_union_ty = self.typeOf(bin_op.lhs); |
| 5347 | 5365 | const union_ty = ptr_union_ty.childType(mod); |
| ... | ... | @@ -5385,7 +5403,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5385 | 5403 | } |
| 5386 | 5404 | |
| 5387 | 5405 | fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5388 | const mod = self.bin_file.options.module.?; | |
| 5406 | const mod = self.bin_file.comp.module.?; | |
| 5389 | 5407 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5390 | 5408 | |
| 5391 | 5409 | const tag_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -5439,7 +5457,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 5439 | 5457 | } |
| 5440 | 5458 | |
| 5441 | 5459 | fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 5442 | const mod = self.bin_file.options.module.?; | |
| 5460 | const mod = self.bin_file.comp.module.?; | |
| 5443 | 5461 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5444 | 5462 | const result = result: { |
| 5445 | 5463 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -5598,7 +5616,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| 5598 | 5616 | } |
| 5599 | 5617 | |
| 5600 | 5618 | fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 5601 | const mod = self.bin_file.options.module.?; | |
| 5619 | const mod = self.bin_file.comp.module.?; | |
| 5602 | 5620 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5603 | 5621 | const result = result: { |
| 5604 | 5622 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -5716,7 +5734,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void { |
| 5716 | 5734 | } |
| 5717 | 5735 | |
| 5718 | 5736 | fn airPopCount(self: *Self, inst: Air.Inst.Index) !void { |
| 5719 | const mod = self.bin_file.options.module.?; | |
| 5737 | const mod = self.bin_file.comp.module.?; | |
| 5720 | 5738 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5721 | 5739 | const result: MCValue = result: { |
| 5722 | 5740 | try self.spillEflagsIfOccupied(); |
| ... | ... | @@ -5779,7 +5797,7 @@ fn genPopCount( |
| 5779 | 5797 | src_mcv: MCValue, |
| 5780 | 5798 | dst_contains_src: bool, |
| 5781 | 5799 | ) !void { |
| 5782 | const mod = self.bin_file.options.module.?; | |
| 5800 | const mod = self.bin_file.comp.module.?; | |
| 5783 | 5801 | |
| 5784 | 5802 | const src_abi_size: u32 = @intCast(src_ty.abiSize(mod)); |
| 5785 | 5803 | if (self.hasFeature(.popcnt)) return self.genBinOpMir( |
| ... | ... | @@ -5871,7 +5889,7 @@ fn genByteSwap( |
| 5871 | 5889 | src_mcv: MCValue, |
| 5872 | 5890 | mem_ok: bool, |
| 5873 | 5891 | ) !MCValue { |
| 5874 | const mod = self.bin_file.options.module.?; | |
| 5892 | const mod = self.bin_file.comp.module.?; | |
| 5875 | 5893 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5876 | 5894 | |
| 5877 | 5895 | if (src_ty.zigTypeTag(mod) == .Vector) return self.fail( |
| ... | ... | @@ -5962,7 +5980,7 @@ fn genByteSwap( |
| 5962 | 5980 | } |
| 5963 | 5981 | |
| 5964 | 5982 | fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 5965 | const mod = self.bin_file.options.module.?; | |
| 5983 | const mod = self.bin_file.comp.module.?; | |
| 5966 | 5984 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5967 | 5985 | |
| 5968 | 5986 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -5984,7 +6002,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void { |
| 5984 | 6002 | } |
| 5985 | 6003 | |
| 5986 | 6004 | fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 5987 | const mod = self.bin_file.options.module.?; | |
| 6005 | const mod = self.bin_file.comp.module.?; | |
| 5988 | 6006 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 5989 | 6007 | |
| 5990 | 6008 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -6106,7 +6124,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void { |
| 6106 | 6124 | } |
| 6107 | 6125 | |
| 6108 | 6126 | fn 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.?; | |
| 6110 | 6128 | const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)]; |
| 6111 | 6129 | |
| 6112 | 6130 | const result = result: { |
| ... | ... | @@ -6282,7 +6300,7 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void { |
| 6282 | 6300 | } |
| 6283 | 6301 | |
| 6284 | 6302 | fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 6285 | const mod = self.bin_file.options.module.?; | |
| 6303 | const mod = self.bin_file.comp.module.?; | |
| 6286 | 6304 | return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) { |
| 6287 | 6305 | .Float => switch (ty.floatBits(self.target.*)) { |
| 6288 | 6306 | 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, |
| ... | ... | @@ -6314,7 +6332,7 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag { |
| 6314 | 6332 | } |
| 6315 | 6333 | |
| 6316 | 6334 | fn 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.?; | |
| 6318 | 6336 | if (self.getRoundTag(ty)) |_| return .none; |
| 6319 | 6337 | |
| 6320 | 6338 | if (ty.zigTypeTag(mod) != .Float) |
| ... | ... | @@ -6338,7 +6356,7 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC |
| 6338 | 6356 | } |
| 6339 | 6357 | |
| 6340 | 6358 | fn 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.?; | |
| 6342 | 6360 | const mir_tag = self.getRoundTag(ty) orelse { |
| 6343 | 6361 | const result = try self.genRoundLibcall(ty, src_mcv, mode); |
| 6344 | 6362 | 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 |
| 6380 | 6398 | } |
| 6381 | 6399 | |
| 6382 | 6400 | fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6383 | const mod = self.bin_file.options.module.?; | |
| 6401 | const mod = self.bin_file.comp.module.?; | |
| 6384 | 6402 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6385 | 6403 | const ty = self.typeOf(ty_op.operand); |
| 6386 | 6404 | |
| ... | ... | @@ -6520,7 +6538,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 6520 | 6538 | } |
| 6521 | 6539 | |
| 6522 | 6540 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 6523 | const mod = self.bin_file.options.module.?; | |
| 6541 | const mod = self.bin_file.comp.module.?; | |
| 6524 | 6542 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 6525 | 6543 | const ty = self.typeOf(un_op); |
| 6526 | 6544 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| ... | ... | @@ -6765,7 +6783,7 @@ fn reuseOperandAdvanced( |
| 6765 | 6783 | } |
| 6766 | 6784 | |
| 6767 | 6785 | fn 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.?; | |
| 6769 | 6787 | |
| 6770 | 6788 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 6771 | 6789 | 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 |
| 6864 | 6882 | } |
| 6865 | 6883 | |
| 6866 | 6884 | fn 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.?; | |
| 6868 | 6886 | const dst_ty = ptr_ty.childType(mod); |
| 6869 | 6887 | if (!dst_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| 6870 | 6888 | switch (ptr_mcv) { |
| ... | ... | @@ -6905,7 +6923,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro |
| 6905 | 6923 | } |
| 6906 | 6924 | |
| 6907 | 6925 | fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 6908 | const mod = self.bin_file.options.module.?; | |
| 6926 | const mod = self.bin_file.comp.module.?; | |
| 6909 | 6927 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 6910 | 6928 | const elem_ty = self.typeOfIndex(inst); |
| 6911 | 6929 | const result: MCValue = result: { |
| ... | ... | @@ -6962,7 +6980,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 6962 | 6980 | } |
| 6963 | 6981 | |
| 6964 | 6982 | fn 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.?; | |
| 6966 | 6984 | const ptr_info = ptr_ty.ptrInfo(mod); |
| 6967 | 6985 | const src_ty = Type.fromInterned(ptr_info.child); |
| 6968 | 6986 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| ... | ... | @@ -7059,7 +7077,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In |
| 7059 | 7077 | } |
| 7060 | 7078 | |
| 7061 | 7079 | fn 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.?; | |
| 7063 | 7081 | const src_ty = ptr_ty.childType(mod); |
| 7064 | 7082 | if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return; |
| 7065 | 7083 | switch (ptr_mcv) { |
| ... | ... | @@ -7100,7 +7118,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr |
| 7100 | 7118 | } |
| 7101 | 7119 | |
| 7102 | 7120 | fn 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.?; | |
| 7104 | 7122 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 7105 | 7123 | |
| 7106 | 7124 | result: { |
| ... | ... | @@ -7138,7 +7156,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void { |
| 7138 | 7156 | } |
| 7139 | 7157 | |
| 7140 | 7158 | fn 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.?; | |
| 7142 | 7160 | const ptr_field_ty = self.typeOfIndex(inst); |
| 7143 | 7161 | const ptr_container_ty = self.typeOf(operand); |
| 7144 | 7162 | 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 |
| 7163 | 7181 | } |
| 7164 | 7182 | |
| 7165 | 7183 | fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7166 | const mod = self.bin_file.options.module.?; | |
| 7184 | const mod = self.bin_file.comp.module.?; | |
| 7167 | 7185 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7168 | 7186 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 7169 | 7187 | const result: MCValue = result: { |
| ... | ... | @@ -7451,7 +7469,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 7451 | 7469 | } |
| 7452 | 7470 | |
| 7453 | 7471 | fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 7454 | const mod = self.bin_file.options.module.?; | |
| 7472 | const mod = self.bin_file.comp.module.?; | |
| 7455 | 7473 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 7456 | 7474 | const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; |
| 7457 | 7475 | |
| ... | ... | @@ -7470,7 +7488,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 7470 | 7488 | } |
| 7471 | 7489 | |
| 7472 | 7490 | fn 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.?; | |
| 7474 | 7492 | const src_ty = self.typeOf(src_air); |
| 7475 | 7493 | if (src_ty.zigTypeTag(mod) == .Vector) |
| 7476 | 7494 | 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: |
| 7558 | 7576 | } |
| 7559 | 7577 | |
| 7560 | 7578 | fn 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.?; | |
| 7562 | 7580 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); |
| 7563 | 7581 | if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(mod) }); |
| 7564 | 7582 | switch (dst_mcv) { |
| ... | ... | @@ -7605,7 +7623,7 @@ fn genShiftBinOpMir( |
| 7605 | 7623 | lhs_mcv: MCValue, |
| 7606 | 7624 | shift_mcv: MCValue, |
| 7607 | 7625 | ) !void { |
| 7608 | const mod = self.bin_file.options.module.?; | |
| 7626 | const mod = self.bin_file.comp.module.?; | |
| 7609 | 7627 | const rhs_mcv: MCValue = rhs: { |
| 7610 | 7628 | switch (shift_mcv) { |
| 7611 | 7629 | .immediate => |imm| switch (imm) { |
| ... | ... | @@ -7975,7 +7993,7 @@ fn genShiftBinOp( |
| 7975 | 7993 | lhs_ty: Type, |
| 7976 | 7994 | rhs_ty: Type, |
| 7977 | 7995 | ) !MCValue { |
| 7978 | const mod = self.bin_file.options.module.?; | |
| 7996 | const mod = self.bin_file.comp.module.?; | |
| 7979 | 7997 | if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{ |
| 7980 | 7998 | lhs_ty.fmt(mod), |
| 7981 | 7999 | }); |
| ... | ... | @@ -8041,7 +8059,7 @@ fn genMulDivBinOp( |
| 8041 | 8059 | lhs_mcv: MCValue, |
| 8042 | 8060 | rhs_mcv: MCValue, |
| 8043 | 8061 | ) !MCValue { |
| 8044 | const mod = self.bin_file.options.module.?; | |
| 8062 | const mod = self.bin_file.comp.module.?; | |
| 8045 | 8063 | if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail( |
| 8046 | 8064 | "TODO implement genMulDivBinOp for {s} from {} to {}", |
| 8047 | 8065 | .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) }, |
| ... | ... | @@ -8283,7 +8301,7 @@ fn genBinOp( |
| 8283 | 8301 | lhs_air: Air.Inst.Ref, |
| 8284 | 8302 | rhs_air: Air.Inst.Ref, |
| 8285 | 8303 | ) !MCValue { |
| 8286 | const mod = self.bin_file.options.module.?; | |
| 8304 | const mod = self.bin_file.comp.module.?; | |
| 8287 | 8305 | const lhs_ty = self.typeOf(lhs_air); |
| 8288 | 8306 | const rhs_ty = self.typeOf(rhs_air); |
| 8289 | 8307 | const abi_size: u32 = @intCast(lhs_ty.abiSize(mod)); |
| ... | ... | @@ -10015,7 +10033,7 @@ fn genBinOpMir( |
| 10015 | 10033 | dst_mcv: MCValue, |
| 10016 | 10034 | src_mcv: MCValue, |
| 10017 | 10035 | ) !void { |
| 10018 | const mod = self.bin_file.options.module.?; | |
| 10036 | const mod = self.bin_file.comp.module.?; | |
| 10019 | 10037 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 10020 | 10038 | try self.spillEflagsIfOccupied(); |
| 10021 | 10039 | switch (dst_mcv) { |
| ... | ... | @@ -10435,7 +10453,7 @@ fn genBinOpMir( |
| 10435 | 10453 | /// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv. |
| 10436 | 10454 | /// Does not support byte-size operands. |
| 10437 | 10455 | fn 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.?; | |
| 10439 | 10457 | const abi_size: u32 = @intCast(dst_ty.abiSize(mod)); |
| 10440 | 10458 | try self.spillEflagsIfOccupied(); |
| 10441 | 10459 | switch (dst_mcv) { |
| ... | ... | @@ -10560,7 +10578,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 10560 | 10578 | } |
| 10561 | 10579 | |
| 10562 | 10580 | fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 10563 | const mod = self.bin_file.options.module.?; | |
| 10581 | const mod = self.bin_file.comp.module.?; | |
| 10564 | 10582 | // skip zero-bit arguments as they don't have a corresponding arg instruction |
| 10565 | 10583 | var arg_index = self.arg_index; |
| 10566 | 10584 | while (self.args[arg_index] == .none) arg_index += 1; |
| ... | ... | @@ -10593,7 +10611,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 10593 | 10611 | } |
| 10594 | 10612 | |
| 10595 | 10613 | fn 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.?; | |
| 10597 | 10615 | switch (self.debug_output) { |
| 10598 | 10616 | .dwarf => |dw| { |
| 10599 | 10617 | const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) { |
| ... | ... | @@ -10629,7 +10647,7 @@ fn genVarDbgInfo( |
| 10629 | 10647 | mcv: MCValue, |
| 10630 | 10648 | name: [:0]const u8, |
| 10631 | 10649 | ) !void { |
| 10632 | const mod = self.bin_file.options.module.?; | |
| 10650 | const mod = self.bin_file.comp.module.?; | |
| 10633 | 10651 | const is_ptr = switch (tag) { |
| 10634 | 10652 | .dbg_var_ptr => true, |
| 10635 | 10653 | .dbg_var_val => false, |
| ... | ... | @@ -10748,7 +10766,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 10748 | 10766 | callee: []const u8, |
| 10749 | 10767 | }, |
| 10750 | 10768 | }, arg_types: []const Type, args: []const MCValue) !MCValue { |
| 10751 | const mod = self.bin_file.options.module.?; | |
| 10769 | const mod = self.bin_file.comp.module.?; | |
| 10752 | 10770 | |
| 10753 | 10771 | const fn_ty = switch (info) { |
| 10754 | 10772 | .air => |callee| fn_info: { |
| ... | ... | @@ -10901,7 +10919,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 10901 | 10919 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 10902 | 10920 | const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl); |
| 10903 | 10921 | const sym = elf_file.symbol(sym_index); |
| 10904 | if (self.bin_file.options.pic) { | |
| 10922 | if (self.mod.pic) { | |
| 10905 | 10923 | const callee_reg: Register = switch (resolved_cc) { |
| 10906 | 10924 | .SysV => callee: { |
| 10907 | 10925 | if (!fn_info.is_var_args) break :callee .rax; |
| ... | ... | @@ -10969,7 +10987,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 10969 | 10987 | } |
| 10970 | 10988 | |
| 10971 | 10989 | fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 10972 | const mod = self.bin_file.options.module.?; | |
| 10990 | const mod = self.bin_file.comp.module.?; | |
| 10973 | 10991 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 10974 | 10992 | |
| 10975 | 10993 | const ret_ty = self.fn_type.fnReturnType(mod); |
| ... | ... | @@ -11018,7 +11036,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 11018 | 11036 | } |
| 11019 | 11037 | |
| 11020 | 11038 | fn 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.?; | |
| 11022 | 11040 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 11023 | 11041 | const ty = self.typeOf(bin_op.lhs); |
| 11024 | 11042 | |
| ... | ... | @@ -11412,7 +11430,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void { |
| 11412 | 11430 | } |
| 11413 | 11431 | |
| 11414 | 11432 | fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void { |
| 11415 | const mod = self.bin_file.options.module.?; | |
| 11433 | const mod = self.bin_file.comp.module.?; | |
| 11416 | 11434 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 11417 | 11435 | |
| 11418 | 11436 | 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 { |
| 11551 | 11569 | } |
| 11552 | 11570 | |
| 11553 | 11571 | fn 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.?; | |
| 11555 | 11573 | const abi_size = ty.abiSize(mod); |
| 11556 | 11574 | switch (mcv) { |
| 11557 | 11575 | .eflags => |cc| { |
| ... | ... | @@ -11624,7 +11642,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 11624 | 11642 | } |
| 11625 | 11643 | |
| 11626 | 11644 | fn 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.?; | |
| 11628 | 11646 | switch (opt_mcv) { |
| 11629 | 11647 | .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() }, |
| 11630 | 11648 | else => {}, |
| ... | ... | @@ -11732,7 +11750,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 11732 | 11750 | } |
| 11733 | 11751 | |
| 11734 | 11752 | fn 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.?; | |
| 11736 | 11754 | const opt_ty = ptr_ty.childType(mod); |
| 11737 | 11755 | const pl_ty = opt_ty.optionalChild(mod); |
| 11738 | 11756 | |
| ... | ... | @@ -11768,7 +11786,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 11768 | 11786 | } |
| 11769 | 11787 | |
| 11770 | 11788 | fn 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.?; | |
| 11772 | 11790 | const err_ty = eu_ty.errorUnionSet(mod); |
| 11773 | 11791 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false |
| 11774 | 11792 | |
| ... | ... | @@ -11815,7 +11833,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) |
| 11815 | 11833 | } |
| 11816 | 11834 | |
| 11817 | 11835 | fn 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.?; | |
| 11819 | 11837 | const eu_ty = ptr_ty.childType(mod); |
| 11820 | 11838 | const err_ty = eu_ty.errorUnionSet(mod); |
| 11821 | 11839 | if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false |
| ... | ... | @@ -12097,7 +12115,7 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void { |
| 12097 | 12115 | } |
| 12098 | 12116 | |
| 12099 | 12117 | fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 12100 | const mod = self.bin_file.options.module.?; | |
| 12118 | const mod = self.bin_file.comp.module.?; | |
| 12101 | 12119 | const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br; |
| 12102 | 12120 | |
| 12103 | 12121 | const block_ty = self.typeOfIndex(br.block_inst); |
| ... | ... | @@ -12158,7 +12176,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 12158 | 12176 | } |
| 12159 | 12177 | |
| 12160 | 12178 | fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 12161 | const mod = self.bin_file.options.module.?; | |
| 12179 | const mod = self.bin_file.comp.module.?; | |
| 12162 | 12180 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 12163 | 12181 | const extra = self.air.extraData(Air.Asm, ty_pl.payload); |
| 12164 | 12182 | const clobbers_len: u31 = @truncate(extra.data.flags); |
| ... | ... | @@ -12865,7 +12883,7 @@ const MoveStrategy = union(enum) { |
| 12865 | 12883 | } |
| 12866 | 12884 | }; |
| 12867 | 12885 | fn 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.?; | |
| 12869 | 12887 | switch (class) { |
| 12870 | 12888 | .general_purpose, .segment => return .{ .move = .{ ._, .mov } }, |
| 12871 | 12889 | .x87 => return .x87_load_store, |
| ... | ... | @@ -13164,7 +13182,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo |
| 13164 | 13182 | } |
| 13165 | 13183 | |
| 13166 | 13184 | fn 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.?; | |
| 13168 | 13186 | |
| 13169 | 13187 | const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; |
| 13170 | 13188 | 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 |
| 13262 | 13280 | } |
| 13263 | 13281 | |
| 13264 | 13282 | fn 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.?; | |
| 13266 | 13284 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 13267 | 13285 | if (ty.bitSize(mod) > dst_reg.bitSize()) |
| 13268 | 13286 | 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 |
| 13561 | 13579 | } |
| 13562 | 13580 | |
| 13563 | 13581 | fn 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.?; | |
| 13565 | 13583 | const abi_size: u32 = @intCast(ty.abiSize(mod)); |
| 13566 | 13584 | const dst_ptr_mcv: MCValue = switch (base) { |
| 13567 | 13585 | .none => .{ .immediate = @bitCast(@as(i64, disp)) }, |
| ... | ... | @@ -13814,7 +13832,7 @@ fn genLazySymbolRef( |
| 13814 | 13832 | const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err| |
| 13815 | 13833 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 13816 | 13834 | const sym = elf_file.symbol(sym_index); |
| 13817 | if (self.bin_file.options.pic) { | |
| 13835 | if (self.mod.pic) { | |
| 13818 | 13836 | switch (tag) { |
| 13819 | 13837 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ |
| 13820 | 13838 | .load_symbol = .{ .sym = sym.esym_index }, |
| ... | ... | @@ -13922,7 +13940,7 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 13922 | 13940 | } |
| 13923 | 13941 | |
| 13924 | 13942 | fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 13925 | const mod = self.bin_file.options.module.?; | |
| 13943 | const mod = self.bin_file.comp.module.?; | |
| 13926 | 13944 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 13927 | 13945 | const dst_ty = self.typeOfIndex(inst); |
| 13928 | 13946 | const src_ty = self.typeOf(ty_op.operand); |
| ... | ... | @@ -13980,7 +13998,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { |
| 13980 | 13998 | } |
| 13981 | 13999 | |
| 13982 | 14000 | fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 13983 | const mod = self.bin_file.options.module.?; | |
| 14001 | const mod = self.bin_file.comp.module.?; | |
| 13984 | 14002 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 13985 | 14003 | |
| 13986 | 14004 | const slice_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -14003,7 +14021,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 14003 | 14021 | } |
| 14004 | 14022 | |
| 14005 | 14023 | fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 14006 | const mod = self.bin_file.options.module.?; | |
| 14024 | const mod = self.bin_file.comp.module.?; | |
| 14007 | 14025 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 14008 | 14026 | |
| 14009 | 14027 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -14082,7 +14100,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void { |
| 14082 | 14100 | } |
| 14083 | 14101 | |
| 14084 | 14102 | fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 14085 | const mod = self.bin_file.options.module.?; | |
| 14103 | const mod = self.bin_file.comp.module.?; | |
| 14086 | 14104 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 14087 | 14105 | |
| 14088 | 14106 | const dst_ty = self.typeOfIndex(inst); |
| ... | ... | @@ -14153,7 +14171,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void { |
| 14153 | 14171 | } |
| 14154 | 14172 | |
| 14155 | 14173 | fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void { |
| 14156 | const mod = self.bin_file.options.module.?; | |
| 14174 | const mod = self.bin_file.comp.module.?; | |
| 14157 | 14175 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 14158 | 14176 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 14159 | 14177 | |
| ... | ... | @@ -14249,7 +14267,7 @@ fn atomicOp( |
| 14249 | 14267 | rmw_op: ?std.builtin.AtomicRmwOp, |
| 14250 | 14268 | order: std.builtin.AtomicOrder, |
| 14251 | 14269 | ) InnerError!MCValue { |
| 14252 | const mod = self.bin_file.options.module.?; | |
| 14270 | const mod = self.bin_file.comp.module.?; | |
| 14253 | 14271 | const ptr_lock = switch (ptr_mcv) { |
| 14254 | 14272 | .register => |reg| self.register_manager.lockReg(reg), |
| 14255 | 14273 | else => null, |
| ... | ... | @@ -14653,7 +14671,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr |
| 14653 | 14671 | } |
| 14654 | 14672 | |
| 14655 | 14673 | fn 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.?; | |
| 14657 | 14675 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 14658 | 14676 | |
| 14659 | 14677 | result: { |
| ... | ... | @@ -14781,7 +14799,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 14781 | 14799 | } |
| 14782 | 14800 | |
| 14783 | 14801 | fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 14784 | const mod = self.bin_file.options.module.?; | |
| 14802 | const mod = self.bin_file.comp.module.?; | |
| 14785 | 14803 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 14786 | 14804 | |
| 14787 | 14805 | try self.spillRegisters(&.{ .rdi, .rsi, .rcx }); |
| ... | ... | @@ -14836,7 +14854,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 14836 | 14854 | } |
| 14837 | 14855 | |
| 14838 | 14856 | fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 14839 | const mod = self.bin_file.options.module.?; | |
| 14857 | const mod = self.bin_file.comp.module.?; | |
| 14840 | 14858 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 14841 | 14859 | const inst_ty = self.typeOfIndex(inst); |
| 14842 | 14860 | const enum_ty = self.typeOf(un_op); |
| ... | ... | @@ -14878,7 +14896,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 14878 | 14896 | } |
| 14879 | 14897 | |
| 14880 | 14898 | fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 14881 | const mod = self.bin_file.options.module.?; | |
| 14899 | const mod = self.bin_file.comp.module.?; | |
| 14882 | 14900 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 14883 | 14901 | |
| 14884 | 14902 | const err_ty = self.typeOf(un_op); |
| ... | ... | @@ -14980,7 +14998,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 14980 | 14998 | } |
| 14981 | 14999 | |
| 14982 | 15000 | fn airSplat(self: *Self, inst: Air.Inst.Index) !void { |
| 14983 | const mod = self.bin_file.options.module.?; | |
| 15001 | const mod = self.bin_file.comp.module.?; | |
| 14984 | 15002 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 14985 | 15003 | const vector_ty = self.typeOfIndex(inst); |
| 14986 | 15004 | const vector_len = vector_ty.vectorLen(mod); |
| ... | ... | @@ -15332,7 +15350,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void { |
| 15332 | 15350 | } |
| 15333 | 15351 | |
| 15334 | 15352 | fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 15335 | const mod = self.bin_file.options.module.?; | |
| 15353 | const mod = self.bin_file.comp.module.?; | |
| 15336 | 15354 | const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce; |
| 15337 | 15355 | |
| 15338 | 15356 | const result: MCValue = result: { |
| ... | ... | @@ -15389,7 +15407,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { |
| 15389 | 15407 | } |
| 15390 | 15408 | |
| 15391 | 15409 | fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15392 | const mod = self.bin_file.options.module.?; | |
| 15410 | const mod = self.bin_file.comp.module.?; | |
| 15393 | 15411 | const result_ty = self.typeOfIndex(inst); |
| 15394 | 15412 | const len: usize = @intCast(result_ty.arrayLen(mod)); |
| 15395 | 15413 | 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 { |
| 15562 | 15580 | } |
| 15563 | 15581 | |
| 15564 | 15582 | fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void { |
| 15565 | const mod = self.bin_file.options.module.?; | |
| 15583 | const mod = self.bin_file.comp.module.?; | |
| 15566 | 15584 | const ip = &mod.intern_pool; |
| 15567 | 15585 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 15568 | 15586 | const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data; |
| ... | ... | @@ -15613,7 +15631,7 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void { |
| 15613 | 15631 | } |
| 15614 | 15632 | |
| 15615 | 15633 | fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 15616 | const mod = self.bin_file.options.module.?; | |
| 15634 | const mod = self.bin_file.comp.module.?; | |
| 15617 | 15635 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 15618 | 15636 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 15619 | 15637 | const ty = self.typeOfIndex(inst); |
| ... | ... | @@ -15780,7 +15798,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { |
| 15780 | 15798 | } |
| 15781 | 15799 | |
| 15782 | 15800 | fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 15783 | const mod = self.bin_file.options.module.?; | |
| 15801 | const mod = self.bin_file.comp.module.?; | |
| 15784 | 15802 | const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty; |
| 15785 | 15803 | const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque); |
| 15786 | 15804 | |
| ... | ... | @@ -15833,7 +15851,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 15833 | 15851 | } |
| 15834 | 15852 | |
| 15835 | 15853 | fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 15836 | const mod = self.bin_file.options.module.?; | |
| 15854 | const mod = self.bin_file.comp.module.?; | |
| 15837 | 15855 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 15838 | 15856 | const ty = self.typeOfIndex(inst); |
| 15839 | 15857 | const promote_ty = self.promoteVarArg(ty); |
| ... | ... | @@ -16042,7 +16060,7 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void { |
| 16042 | 16060 | } |
| 16043 | 16061 | |
| 16044 | 16062 | fn 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.?; | |
| 16046 | 16064 | const ty = self.typeOf(ref); |
| 16047 | 16065 | |
| 16048 | 16066 | // 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 { |
| 16057 | 16075 | const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = Value.fromInterned(ip_index) }); |
| 16058 | 16076 | switch (const_mcv) { |
| 16059 | 16077 | .lea_tlv => |tlv_sym| if (self.bin_file.cast(link.File.Elf)) |_| { |
| 16060 | if (self.bin_file.options.pic) { | |
| 16078 | if (self.mod.pic) { | |
| 16061 | 16079 | try self.spillRegisters(&.{ .rdi, .rax }); |
| 16062 | 16080 | } else { |
| 16063 | 16081 | try self.spillRegisters(&.{.rax}); |
| ... | ... | @@ -16116,7 +16134,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV |
| 16116 | 16134 | } |
| 16117 | 16135 | |
| 16118 | 16136 | fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue { |
| 16119 | const mod = self.bin_file.options.module.?; | |
| 16137 | const mod = self.bin_file.comp.module.?; | |
| 16120 | 16138 | return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl(mod))) { |
| 16121 | 16139 | .mcv => |mcv| switch (mcv) { |
| 16122 | 16140 | .none => .none, |
| ... | ... | @@ -16156,7 +16174,7 @@ fn resolveCallingConventionValues( |
| 16156 | 16174 | var_args: []const Type, |
| 16157 | 16175 | stack_frame_base: FrameIndex, |
| 16158 | 16176 | ) !CallMCValues { |
| 16159 | const mod = self.bin_file.options.module.?; | |
| 16177 | const mod = self.bin_file.comp.module.?; | |
| 16160 | 16178 | const ip = &mod.intern_pool; |
| 16161 | 16179 | const cc = fn_info.cc; |
| 16162 | 16180 | const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len); |
| ... | ... | @@ -16413,14 +16431,16 @@ fn resolveCallingConventionValues( |
| 16413 | 16431 | fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 16414 | 16432 | @setCold(true); |
| 16415 | 16433 | 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); | |
| 16417 | 16436 | return error.CodegenFail; |
| 16418 | 16437 | } |
| 16419 | 16438 | |
| 16420 | 16439 | fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError { |
| 16421 | 16440 | @setCold(true); |
| 16422 | 16441 | 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); | |
| 16424 | 16444 | return error.CodegenFail; |
| 16425 | 16445 | } |
| 16426 | 16446 | |
| ... | ... | @@ -16468,7 +16488,7 @@ fn registerAlias(reg: Register, size_bytes: u32) Register { |
| 16468 | 16488 | } |
| 16469 | 16489 | |
| 16470 | 16490 | fn memSize(self: *Self, ty: Type) Memory.Size { |
| 16471 | const mod = self.bin_file.options.module.?; | |
| 16491 | const mod = self.bin_file.comp.module.?; | |
| 16472 | 16492 | return switch (ty.zigTypeTag(mod)) { |
| 16473 | 16493 | .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)), |
| 16474 | 16494 | else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))), |
| ... | ... | @@ -16476,7 +16496,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size { |
| 16476 | 16496 | } |
| 16477 | 16497 | |
| 16478 | 16498 | fn splitType(self: *Self, ty: Type) ![2]Type { |
| 16479 | const mod = self.bin_file.options.module.?; | |
| 16499 | const mod = self.bin_file.comp.module.?; | |
| 16480 | 16500 | const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none); |
| 16481 | 16501 | var parts: [2]Type = undefined; |
| 16482 | 16502 | if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| { |
| ... | ... | @@ -16505,7 +16525,7 @@ fn splitType(self: *Self, ty: Type) ![2]Type { |
| 16505 | 16525 | /// Truncates the value in the register in place. |
| 16506 | 16526 | /// Clobbers any remaining bits. |
| 16507 | 16527 | fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 16508 | const mod = self.bin_file.options.module.?; | |
| 16528 | const mod = self.bin_file.comp.module.?; | |
| 16509 | 16529 | const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{ |
| 16510 | 16530 | .signedness = .unsigned, |
| 16511 | 16531 | .bits = @intCast(ty.bitSize(mod)), |
| ... | ... | @@ -16550,7 +16570,7 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void { |
| 16550 | 16570 | } |
| 16551 | 16571 | |
| 16552 | 16572 | fn regBitSize(self: *Self, ty: Type) u64 { |
| 16553 | const mod = self.bin_file.options.module.?; | |
| 16573 | const mod = self.bin_file.comp.module.?; | |
| 16554 | 16574 | const abi_size = ty.abiSize(mod); |
| 16555 | 16575 | return switch (ty.zigTypeTag(mod)) { |
| 16556 | 16576 | else => switch (abi_size) { |
| ... | ... | @@ -16569,7 +16589,7 @@ fn regBitSize(self: *Self, ty: Type) u64 { |
| 16569 | 16589 | } |
| 16570 | 16590 | |
| 16571 | 16591 | fn regExtraBits(self: *Self, ty: Type) u64 { |
| 16572 | const mod = self.bin_file.options.module.?; | |
| 16592 | const mod = self.bin_file.comp.module.?; | |
| 16573 | 16593 | return self.regBitSize(ty) - ty.bitSize(mod); |
| 16574 | 16594 | } |
| 16575 | 16595 | |
| ... | ... | @@ -16584,12 +16604,12 @@ fn hasAllFeatures(self: *Self, features: anytype) bool { |
| 16584 | 16604 | } |
| 16585 | 16605 | |
| 16586 | 16606 | fn typeOf(self: *Self, inst: Air.Inst.Ref) Type { |
| 16587 | const mod = self.bin_file.options.module.?; | |
| 16607 | const mod = self.bin_file.comp.module.?; | |
| 16588 | 16608 | return self.air.typeOf(inst, &mod.intern_pool); |
| 16589 | 16609 | } |
| 16590 | 16610 | |
| 16591 | 16611 | fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type { |
| 16592 | const mod = self.bin_file.options.module.?; | |
| 16612 | const mod = self.bin_file.comp.module.?; | |
| 16593 | 16613 | return self.air.typeOfIndex(inst, &mod.intern_pool); |
| 16594 | 16614 | } |
| 16595 | 16615 | |
| ... | ... | @@ -16641,7 +16661,7 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 { |
| 16641 | 16661 | } |
| 16642 | 16662 | |
| 16643 | 16663 | fn promoteInt(self: *Self, ty: Type) Type { |
| 16644 | const mod = self.bin_file.options.module.?; | |
| 16664 | const mod = self.bin_file.comp.module.?; | |
| 16645 | 16665 | const int_info: InternPool.Key.IntType = switch (ty.toIntern()) { |
| 16646 | 16666 | .bool_type => .{ .signedness = .unsigned, .bits = 1 }, |
| 16647 | 16667 | 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 { |
| 103 | 103 | }); |
| 104 | 104 | }, |
| 105 | 105 | .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) { | |
| 107 | 107 | .Exe => false, |
| 108 | 108 | .Obj => true, |
| 109 | .Lib => emit.lower.bin_file.options.link_mode == .Static, | |
| 109 | .Lib => emit.lower.link_mode == .Static, | |
| 110 | 110 | }; |
| 111 | 111 | const atom = elf_file.symbol(data.atom_index).atom(elf_file).?; |
| 112 | 112 | const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index); |
| ... | ... | @@ -114,7 +114,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 114 | 114 | if (sym.flags.needs_zig_got and !is_obj_or_static_lib) { |
| 115 | 115 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 116 | 116 | } |
| 117 | if (emit.lower.bin_file.options.pic) { | |
| 117 | if (emit.lower.pic) { | |
| 118 | 118 | const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) |
| 119 | 119 | link.File.Elf.R_X86_64_ZIG_GOTPCREL |
| 120 | 120 | else if (sym.flags.needs_got) |
src/arch/x86_64/Lower.zig+7-4| ... | ... | @@ -1,6 +1,9 @@ |
| 1 | 1 | //! This file contains the functionality for lowering x86_64 MIR to Instructions |
| 2 | 2 | |
| 3 | 3 | bin_file: *link.File, |
| 4 | output_mode: std.builtin.OutputMode, | |
| 5 | link_mode: std.builtin.LinkMode, | |
| 6 | pic: bool, | |
| 4 | 7 | allocator: Allocator, |
| 5 | 8 | mir: Mir, |
| 6 | 9 | cc: std.builtin.CallingConvention, |
| ... | ... | @@ -336,10 +339,10 @@ fn isTls(sym: bits.Symbol, ctx: *link.File) bool { |
| 336 | 339 | } |
| 337 | 340 | |
| 338 | 341 | fn 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) { | |
| 340 | 343 | .Exe => false, |
| 341 | 344 | .Obj => true, |
| 342 | .Lib => lower.bin_file.options.link_mode == .Static, | |
| 345 | .Lib => lower.link_mode == .Static, | |
| 343 | 346 | }; |
| 344 | 347 | |
| 345 | 348 | const emit_prefix = prefix; |
| ... | ... | @@ -358,7 +361,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 358 | 361 | |
| 359 | 362 | if (isTls(sym, lower.bin_file)) { |
| 360 | 363 | // TODO handle extern TLS vars, i.e., emit GD model |
| 361 | if (lower.bin_file.options.pic) { | |
| 364 | if (lower.pic) { | |
| 362 | 365 | // Here, we currently assume local dynamic TLS vars, and so |
| 363 | 366 | // we emit LD model. |
| 364 | 367 | _ = lower.reloc(.{ .linker_tlsld = sym }); |
| ... | ... | @@ -403,7 +406,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 403 | 406 | } |
| 404 | 407 | |
| 405 | 408 | _ = lower.reloc(.{ .linker_reloc = sym }); |
| 406 | break :op if (lower.bin_file.options.pic) switch (mnemonic) { | |
| 409 | break :op if (lower.pic) switch (mnemonic) { | |
| 407 | 410 | .lea => { |
| 408 | 411 | break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }; |
| 409 | 412 | }, |
src/codegen.zig+158-130| ... | ... | @@ -45,7 +45,7 @@ pub const DebugInfoOutput = union(enum) { |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | 47 | pub fn generateFunction( |
| 48 | bin_file: *link.File, | |
| 48 | lf: *link.File, | |
| 49 | 49 | src_loc: Module.SrcLoc, |
| 50 | 50 | func_index: InternPool.Index, |
| 51 | 51 | air: Air, |
| ... | ... | @@ -53,33 +53,43 @@ pub fn generateFunction( |
| 53 | 53 | code: *std.ArrayList(u8), |
| 54 | 54 | debug_output: DebugInfoOutput, |
| 55 | 55 | ) 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) { | |
| 57 | 62 | .arm, |
| 58 | 63 | .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), | |
| 60 | 65 | .aarch64, |
| 61 | 66 | .aarch64_be, |
| 62 | 67 | .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), | |
| 67 | 72 | .wasm32, |
| 68 | 73 | .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), | |
| 70 | 75 | else => unreachable, |
| 71 | 76 | } |
| 72 | 77 | } |
| 73 | 78 | |
| 74 | 79 | pub fn generateLazyFunction( |
| 75 | bin_file: *link.File, | |
| 80 | lf: *link.File, | |
| 76 | 81 | src_loc: Module.SrcLoc, |
| 77 | 82 | lazy_sym: link.File.LazySymbol, |
| 78 | 83 | code: *std.ArrayList(u8), |
| 79 | 84 | debug_output: DebugInfoOutput, |
| 80 | 85 | ) 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), | |
| 83 | 93 | else => unreachable, |
| 84 | 94 | } |
| 85 | 95 | } |
| ... | ... | @@ -107,13 +117,15 @@ pub fn generateLazySymbol( |
| 107 | 117 | const tracy = trace(@src()); |
| 108 | 118 | defer tracy.end(); |
| 109 | 119 | |
| 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; | |
| 111 | 123 | const endian = target.cpu.arch.endian(); |
| 124 | const gpa = comp.gpa; | |
| 112 | 125 | |
| 113 | const mod = bin_file.options.module.?; | |
| 114 | 126 | log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ |
| 115 | 127 | @tagName(lazy_sym.kind), |
| 116 | lazy_sym.ty.fmt(mod), | |
| 128 | lazy_sym.ty.fmt(zcu), | |
| 117 | 129 | }); |
| 118 | 130 | |
| 119 | 131 | if (lazy_sym.kind == .code) { |
| ... | ... | @@ -121,14 +133,14 @@ pub fn generateLazySymbol( |
| 121 | 133 | return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output); |
| 122 | 134 | } |
| 123 | 135 | |
| 124 | if (lazy_sym.ty.isAnyError(mod)) { | |
| 136 | if (lazy_sym.ty.isAnyError(zcu)) { | |
| 125 | 137 | alignment.* = .@"4"; |
| 126 | const err_names = mod.global_error_set.keys(); | |
| 138 | const err_names = zcu.global_error_set.keys(); | |
| 127 | 139 | mem.writeInt(u32, try code.addManyAsArray(4), @as(u32, @intCast(err_names.len)), endian); |
| 128 | 140 | var offset = code.items.len; |
| 129 | 141 | try code.resize((1 + err_names.len + 1) * 4); |
| 130 | 142 | 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); | |
| 132 | 144 | mem.writeInt(u32, code.items[offset..][0..4], @as(u32, @intCast(code.items.len)), endian); |
| 133 | 145 | offset += 4; |
| 134 | 146 | try code.ensureUnusedCapacity(err_name.len + 1); |
| ... | ... | @@ -137,20 +149,20 @@ pub fn generateLazySymbol( |
| 137 | 149 | } |
| 138 | 150 | mem.writeInt(u32, code.items[offset..][0..4], @as(u32, @intCast(code.items.len)), endian); |
| 139 | 151 | return Result.ok; |
| 140 | } else if (lazy_sym.ty.zigTypeTag(mod) == .Enum) { | |
| 152 | } else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) { | |
| 141 | 153 | 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); | |
| 144 | 156 | try code.ensureUnusedCapacity(tag_name.len + 1); |
| 145 | 157 | code.appendSliceAssumeCapacity(tag_name); |
| 146 | 158 | code.appendAssumeCapacity(0); |
| 147 | 159 | } |
| 148 | 160 | return Result.ok; |
| 149 | 161 | } else return .{ .fail = try ErrorMsg.create( |
| 150 | bin_file.allocator, | |
| 162 | gpa, | |
| 151 | 163 | src_loc, |
| 152 | 164 | "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) }, | |
| 154 | 166 | ) }; |
| 155 | 167 | } |
| 156 | 168 | |
| ... | ... | @@ -165,7 +177,7 @@ pub fn generateSymbol( |
| 165 | 177 | const tracy = trace(@src()); |
| 166 | 178 | defer tracy.end(); |
| 167 | 179 | |
| 168 | const mod = bin_file.options.module.?; | |
| 180 | const mod = bin_file.comp.module.?; | |
| 169 | 181 | const ip = &mod.intern_pool; |
| 170 | 182 | const typed_value = arg_tv; |
| 171 | 183 | |
| ... | ... | @@ -662,7 +674,7 @@ fn lowerParentPtr( |
| 662 | 674 | debug_output: DebugInfoOutput, |
| 663 | 675 | reloc_info: RelocInfo, |
| 664 | 676 | ) CodeGenError!Result { |
| 665 | const mod = bin_file.options.module.?; | |
| 677 | const mod = bin_file.comp.module.?; | |
| 666 | 678 | const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr; |
| 667 | 679 | assert(ptr.len == .none); |
| 668 | 680 | return switch (ptr.addr) { |
| ... | ... | @@ -757,7 +769,7 @@ const RelocInfo = struct { |
| 757 | 769 | }; |
| 758 | 770 | |
| 759 | 771 | fn lowerAnonDeclRef( |
| 760 | bin_file: *link.File, | |
| 772 | lf: *link.File, | |
| 761 | 773 | src_loc: Module.SrcLoc, |
| 762 | 774 | anon_decl: InternPool.Key.Ptr.Addr.AnonDecl, |
| 763 | 775 | code: *std.ArrayList(u8), |
| ... | ... | @@ -765,27 +777,27 @@ fn lowerAnonDeclRef( |
| 765 | 777 | reloc_info: RelocInfo, |
| 766 | 778 | ) CodeGenError!Result { |
| 767 | 779 | _ = 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; | |
| 770 | 782 | |
| 771 | 783 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 772 | 784 | 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)) { | |
| 777 | 789 | try code.appendNTimes(0xaa, ptr_width_bytes); |
| 778 | 790 | return Result.ok; |
| 779 | 791 | } |
| 780 | 792 | |
| 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); | |
| 783 | 795 | switch (res) { |
| 784 | 796 | .ok => {}, |
| 785 | 797 | .fail => |em| return .{ .fail = em }, |
| 786 | 798 | } |
| 787 | 799 | |
| 788 | const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{ | |
| 800 | const vaddr = try lf.getAnonDeclVAddr(decl_val, .{ | |
| 789 | 801 | .parent_atom_index = reloc_info.parent_atom_index, |
| 790 | 802 | .offset = code.items.len, |
| 791 | 803 | .addend = reloc_info.addend orelse 0, |
| ... | ... | @@ -802,7 +814,7 @@ fn lowerAnonDeclRef( |
| 802 | 814 | } |
| 803 | 815 | |
| 804 | 816 | fn lowerDeclRef( |
| 805 | bin_file: *link.File, | |
| 817 | lf: *link.File, | |
| 806 | 818 | src_loc: Module.SrcLoc, |
| 807 | 819 | decl_index: InternPool.DeclIndex, |
| 808 | 820 | code: *std.ArrayList(u8), |
| ... | ... | @@ -811,20 +823,21 @@ fn lowerDeclRef( |
| 811 | 823 | ) CodeGenError!Result { |
| 812 | 824 | _ = src_loc; |
| 813 | 825 | _ = 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; | |
| 816 | 830 | |
| 817 | 831 | 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)) { | |
| 821 | 834 | try code.appendNTimes(0xaa, @divExact(ptr_width, 8)); |
| 822 | 835 | return Result.ok; |
| 823 | 836 | } |
| 824 | 837 | |
| 825 | try mod.markDeclAlive(decl); | |
| 838 | try zcu.markDeclAlive(decl); | |
| 826 | 839 | |
| 827 | const vaddr = try bin_file.getDeclVAddr(decl_index, .{ | |
| 840 | const vaddr = try lf.getDeclVAddr(decl_index, .{ | |
| 828 | 841 | .parent_atom_index = reloc_info.parent_atom_index, |
| 829 | 842 | .offset = code.items.len, |
| 830 | 843 | .addend = reloc_info.addend orelse 0, |
| ... | ... | @@ -897,27 +910,29 @@ pub const GenResult = union(enum) { |
| 897 | 910 | }; |
| 898 | 911 | |
| 899 | 912 | fn genDeclRef( |
| 900 | bin_file: *link.File, | |
| 913 | lf: *link.File, | |
| 901 | 914 | src_loc: Module.SrcLoc, |
| 902 | 915 | tv: TypedValue, |
| 903 | 916 | ptr_decl_index: InternPool.DeclIndex, |
| 904 | 917 | ) 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; | |
| 907 | 924 | |
| 908 | const target = bin_file.options.target; | |
| 909 | 925 | const ptr_bits = target.ptrBitWidth(); |
| 910 | 926 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 911 | 927 | |
| 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))) { | |
| 914 | 929 | .func => |func| func.owner_decl, |
| 915 | 930 | .extern_func => |extern_func| extern_func.decl, |
| 916 | 931 | else => ptr_decl_index, |
| 917 | 932 | }; |
| 918 | const decl = mod.declPtr(decl_index); | |
| 933 | const decl = zcu.declPtr(decl_index); | |
| 919 | 934 | |
| 920 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { | |
| 935 | if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) { | |
| 921 | 936 | const imm: u64 = switch (ptr_bytes) { |
| 922 | 937 | 1 => 0xaa, |
| 923 | 938 | 2 => 0xaaaa, |
| ... | ... | @@ -928,29 +943,34 @@ fn genDeclRef( |
| 928 | 943 | return GenResult.mcv(.{ .immediate = imm }); |
| 929 | 944 | } |
| 930 | 945 | |
| 946 | const comp = lf.comp; | |
| 947 | const gpa = comp.gpa; | |
| 948 | ||
| 931 | 949 | // 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().? }); | |
| 935 | 953 | } |
| 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().? }); | |
| 940 | 958 | } |
| 941 | 959 | } |
| 942 | 960 | |
| 943 | try mod.markDeclAlive(decl); | |
| 961 | try zcu.markDeclAlive(decl); | |
| 944 | 962 | |
| 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); | |
| 947 | 967 | |
| 948 | if (bin_file.cast(link.File.Elf)) |elf_file| { | |
| 968 | if (lf.cast(link.File.Elf)) |elf_file| { | |
| 949 | 969 | if (is_extern) { |
| 950 | const name = mod.intern_pool.stringToSlice(decl.name); | |
| 970 | const name = zcu.intern_pool.stringToSlice(decl.name); | |
| 951 | 971 | // 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) | |
| 954 | 974 | else |
| 955 | 975 | null; |
| 956 | 976 | const sym_index = try elf_file.getGlobalSymbol(name, lib_name); |
| ... | ... | @@ -963,12 +983,12 @@ fn genDeclRef( |
| 963 | 983 | return GenResult.mcv(.{ .load_tlv = sym.esym_index }); |
| 964 | 984 | } |
| 965 | 985 | 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| { | |
| 967 | 987 | if (is_extern) { |
| 968 | 988 | // 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); | |
| 972 | 992 | const global_index = try macho_file.addUndefined(sym_name, .{ .add_got = true }); |
| 973 | 993 | return GenResult.mcv(.{ .load_got = link.File.MachO.global_symbol_bit | global_index }); |
| 974 | 994 | } |
| ... | ... | @@ -978,110 +998,118 @@ fn genDeclRef( |
| 978 | 998 | return GenResult.mcv(.{ .load_tlv = sym_index }); |
| 979 | 999 | } |
| 980 | 1000 | 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| { | |
| 982 | 1002 | if (is_extern) { |
| 983 | const name = mod.intern_pool.stringToSlice(decl.name); | |
| 1003 | const name = zcu.intern_pool.stringToSlice(decl.name); | |
| 984 | 1004 | // 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) | |
| 987 | 1007 | else |
| 988 | 1008 | null; |
| 989 | 1009 | 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 | |
| 991 | 1011 | return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index }); |
| 992 | 1012 | } |
| 993 | 1013 | const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index); |
| 994 | 1014 | const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; |
| 995 | 1015 | 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| { | |
| 997 | 1017 | const atom_index = try p9.seeDecl(decl_index); |
| 998 | 1018 | const atom = p9.getAtom(atom_index); |
| 999 | 1019 | return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) }); |
| 1000 | 1020 | } 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}); | |
| 1002 | 1022 | } |
| 1003 | 1023 | } |
| 1004 | 1024 | |
| 1005 | 1025 | fn genUnnamedConst( |
| 1006 | bin_file: *link.File, | |
| 1026 | lf: *link.File, | |
| 1007 | 1027 | src_loc: Module.SrcLoc, |
| 1008 | 1028 | tv: TypedValue, |
| 1009 | 1029 | owner_decl_index: InternPool.DeclIndex, |
| 1010 | 1030 | ) 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) }); | |
| 1013 | 1034 | |
| 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)}); | |
| 1017 | 1037 | }; |
| 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", .{}), | |
| 1030 | 1056 | } |
| 1031 | 1057 | } |
| 1032 | 1058 | |
| 1033 | 1059 | pub fn genTypedValue( |
| 1034 | bin_file: *link.File, | |
| 1060 | lf: *link.File, | |
| 1035 | 1061 | src_loc: Module.SrcLoc, |
| 1036 | 1062 | arg_tv: TypedValue, |
| 1037 | 1063 | owner_decl_index: InternPool.DeclIndex, |
| 1038 | 1064 | ) CodeGenError!GenResult { |
| 1039 | const mod = bin_file.options.module.?; | |
| 1065 | const zcu = lf.comp.module.?; | |
| 1040 | 1066 | const typed_value = arg_tv; |
| 1041 | 1067 | |
| 1042 | 1068 | 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), | |
| 1045 | 1071 | }); |
| 1046 | 1072 | |
| 1047 | if (typed_value.val.isUndef(mod)) | |
| 1073 | if (typed_value.val.isUndef(zcu)) | |
| 1048 | 1074 | return GenResult.mcv(.undef); |
| 1049 | 1075 | |
| 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; | |
| 1051 | 1079 | const ptr_bits = target.ptrBitWidth(); |
| 1052 | 1080 | |
| 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())) { | |
| 1054 | 1082 | .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), | |
| 1057 | 1085 | else => {}, |
| 1058 | 1086 | }, |
| 1059 | 1087 | else => {}, |
| 1060 | 1088 | }; |
| 1061 | 1089 | |
| 1062 | switch (typed_value.ty.zigTypeTag(mod)) { | |
| 1090 | switch (typed_value.ty.zigTypeTag(zcu)) { | |
| 1063 | 1091 | .Void => return GenResult.mcv(.none), |
| 1064 | .Pointer => switch (typed_value.ty.ptrSize(mod)) { | |
| 1092 | .Pointer => switch (typed_value.ty.ptrSize(zcu)) { | |
| 1065 | 1093 | .Slice => {}, |
| 1066 | 1094 | else => switch (typed_value.val.toIntern()) { |
| 1067 | 1095 | .null_value => { |
| 1068 | 1096 | return GenResult.mcv(.{ .immediate = 0 }); |
| 1069 | 1097 | }, |
| 1070 | 1098 | .none => {}, |
| 1071 | else => switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) { | |
| 1099 | else => switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) { | |
| 1072 | 1100 | .int => { |
| 1073 | return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) }); | |
| 1101 | return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(zcu) }); | |
| 1074 | 1102 | }, |
| 1075 | 1103 | else => {}, |
| 1076 | 1104 | }, |
| 1077 | 1105 | }, |
| 1078 | 1106 | }, |
| 1079 | 1107 | .Int => { |
| 1080 | const info = typed_value.ty.intInfo(mod); | |
| 1108 | const info = typed_value.ty.intInfo(zcu); | |
| 1081 | 1109 | if (info.bits <= ptr_bits) { |
| 1082 | 1110 | 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), | |
| 1085 | 1113 | }; |
| 1086 | 1114 | return GenResult.mcv(.{ .immediate = unsigned }); |
| 1087 | 1115 | } |
| ... | ... | @@ -1090,45 +1118,45 @@ pub fn genTypedValue( |
| 1090 | 1118 | return GenResult.mcv(.{ .immediate = @intFromBool(typed_value.val.toBool()) }); |
| 1091 | 1119 | }, |
| 1092 | 1120 | .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 }), | |
| 1097 | 1125 | }, 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)) }); | |
| 1100 | 1128 | } |
| 1101 | 1129 | }, |
| 1102 | 1130 | .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, .{ | |
| 1106 | 1134 | .ty = Type.fromInterned(int_tag_ty), |
| 1107 | 1135 | .val = Value.fromInterned(enum_tag.int), |
| 1108 | 1136 | }, owner_decl_index); |
| 1109 | 1137 | }, |
| 1110 | 1138 | .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).?; | |
| 1113 | 1141 | return GenResult.mcv(.{ .immediate = error_index }); |
| 1114 | 1142 | }, |
| 1115 | 1143 | .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)) { | |
| 1119 | 1147 | // 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, .{ | |
| 1123 | 1151 | .ty = err_type, |
| 1124 | .val = Value.fromInterned((try mod.intern(.{ .err = .{ | |
| 1152 | .val = Value.fromInterned((try zcu.intern(.{ .err = .{ | |
| 1125 | 1153 | .ty = err_type.toIntern(), |
| 1126 | 1154 | .name = err_name, |
| 1127 | 1155 | } }))), |
| 1128 | 1156 | }, owner_decl_index), |
| 1129 | .payload => return genTypedValue(bin_file, src_loc, .{ | |
| 1157 | .payload => return genTypedValue(lf, src_loc, .{ | |
| 1130 | 1158 | .ty = err_int_ty, |
| 1131 | .val = try mod.intValue(err_int_ty, 0), | |
| 1159 | .val = try zcu.intValue(err_int_ty, 0), | |
| 1132 | 1160 | }, owner_decl_index), |
| 1133 | 1161 | } |
| 1134 | 1162 | } |
| ... | ... | @@ -1146,7 +1174,7 @@ pub fn genTypedValue( |
| 1146 | 1174 | else => {}, |
| 1147 | 1175 | } |
| 1148 | 1176 | |
| 1149 | return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index); | |
| 1177 | return genUnnamedConst(lf, src_loc, typed_value, owner_decl_index); | |
| 1150 | 1178 | } |
| 1151 | 1179 | |
| 1152 | 1180 | pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 { |
src/codegen/llvm.zig+318-309| ... | ... | @@ -15,6 +15,7 @@ const link = @import("../link.zig"); |
| 15 | 15 | const Compilation = @import("../Compilation.zig"); |
| 16 | 16 | const build_options = @import("build_options"); |
| 17 | 17 | const Module = @import("../Module.zig"); |
| 18 | const Zcu = Module; | |
| 18 | 19 | const InternPool = @import("../InternPool.zig"); |
| 19 | 20 | const Package = @import("../Package.zig"); |
| 20 | 21 | const TypedValue = @import("../TypedValue.zig"); |
| ... | ... | @@ -821,7 +822,7 @@ pub const Object = struct { |
| 821 | 822 | type_map: TypeMap, |
| 822 | 823 | di_type_map: DITypeMap, |
| 823 | 824 | /// 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 | |
| 825 | 826 | /// the compilation are known. |
| 826 | 827 | error_name_table: Builder.Variable.Index, |
| 827 | 828 | /// This map is usually very close to empty. It tracks only the cases when a |
| ... | ... | @@ -849,27 +850,25 @@ pub const Object = struct { |
| 849 | 850 | |
| 850 | 851 | pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type); |
| 851 | 852 | |
| 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 | |
| 853 | 854 | /// want to iterate over it while adding entries to it. |
| 854 | 855 | pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr); |
| 855 | 856 | |
| 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; | |
| 866 | 865 | |
| 867 | 866 | var builder = try Builder.init(.{ |
| 868 | 867 | .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, | |
| 873 | 872 | .triple = llvm_target_triple, |
| 874 | 873 | }); |
| 875 | 874 | errdefer builder.deinit(); |
| ... | ... | @@ -877,10 +876,11 @@ pub const Object = struct { |
| 877 | 876 | var target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void = undefined; |
| 878 | 877 | var target_data: if (build_options.have_llvm) *llvm.TargetData else void = undefined; |
| 879 | 878 | 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"), | |
| 884 | 884 | } |
| 885 | 885 | builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true); |
| 886 | 886 | |
| ... | ... | @@ -898,26 +898,29 @@ pub const Object = struct { |
| 898 | 898 | // very location dependent. |
| 899 | 899 | // TODO: the only concern I have with this is WASI as either host or target, should |
| 900 | 900 | // 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. | |
| 901 | 907 | 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, ""); | |
| 905 | 910 | if (d.len == 0) break :m; |
| 906 | 911 | 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); | |
| 910 | 914 | } |
| 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); | |
| 913 | 917 | }; |
| 914 | defer builder.gpa.free(compile_unit_dir_z); | |
| 915 | 918 | |
| 916 | 919 | builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit( |
| 917 | 920 | 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), | |
| 919 | 922 | producer.slice(&builder).?, |
| 920 | options.optimize_mode != .Debug, | |
| 923 | optimize_mode != .Debug, | |
| 921 | 924 | "", // flags |
| 922 | 925 | 0, // runtime version |
| 923 | 926 | "", // split name |
| ... | ... | @@ -926,19 +929,19 @@ pub const Object = struct { |
| 926 | 929 | ); |
| 927 | 930 | } |
| 928 | 931 | |
| 929 | const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) | |
| 932 | const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug) | |
| 930 | 933 | .None |
| 931 | 934 | else |
| 932 | 935 | .Aggressive; |
| 933 | 936 | |
| 934 | const reloc_mode: llvm.RelocMode = if (options.pic) | |
| 937 | const reloc_mode: llvm.RelocMode = if (pic) | |
| 935 | 938 | .PIC |
| 936 | else if (options.link_mode == .Dynamic) | |
| 939 | else if (comp.config.link_mode == .Dynamic) | |
| 937 | 940 | llvm.RelocMode.DynamicNoPIC |
| 938 | 941 | else |
| 939 | 942 | .Static; |
| 940 | 943 | |
| 941 | const code_model: llvm.CodeModel = switch (options.machine_code_model) { | |
| 944 | const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) { | |
| 942 | 945 | .default => .Default, |
| 943 | 946 | .tiny => .Tiny, |
| 944 | 947 | .small => .Small, |
| ... | ... | @@ -953,15 +956,15 @@ pub const Object = struct { |
| 953 | 956 | target_machine = llvm.TargetMachine.create( |
| 954 | 957 | builder.llvm.target.?, |
| 955 | 958 | 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.?, | |
| 958 | 961 | opt_level, |
| 959 | 962 | reloc_mode, |
| 960 | 963 | code_model, |
| 961 | options.function_sections, | |
| 962 | options.data_sections, | |
| 964 | comp.function_sections, | |
| 965 | comp.data_sections, | |
| 963 | 966 | 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, | |
| 965 | 968 | ); |
| 966 | 969 | errdefer target_machine.dispose(); |
| 967 | 970 | |
| ... | ... | @@ -970,15 +973,15 @@ pub const Object = struct { |
| 970 | 973 | |
| 971 | 974 | builder.llvm.module.?.setModuleDataLayout(target_data); |
| 972 | 975 | |
| 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(); | |
| 975 | 978 | if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model); |
| 976 | 979 | |
| 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); | |
| 979 | 982 | } |
| 980 | 983 | |
| 981 | builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }}); | |
| 984 | builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }}); | |
| 982 | 985 | if (std.debug.runtime_safety) { |
| 983 | 986 | const rep = target_data.stringRep(); |
| 984 | 987 | defer llvm.disposeMessage(rep); |
| ... | ... | @@ -989,16 +992,17 @@ pub const Object = struct { |
| 989 | 992 | } |
| 990 | 993 | } |
| 991 | 994 | |
| 992 | return .{ | |
| 995 | const obj = try arena.create(Object); | |
| 996 | obj.* = .{ | |
| 993 | 997 | .gpa = gpa, |
| 994 | 998 | .builder = builder, |
| 995 | .module = options.module.?, | |
| 999 | .module = comp.module.?, | |
| 996 | 1000 | .di_map = .{}, |
| 997 | 1001 | .di_builder = if (builder.useLibLlvm()) builder.llvm.di_builder else null, // TODO |
| 998 | 1002 | .di_compile_unit = if (builder.useLibLlvm()) builder.llvm.di_compile_unit else null, |
| 999 | 1003 | .target_machine = target_machine, |
| 1000 | 1004 | .target_data = target_data, |
| 1001 | .target = options.target, | |
| 1005 | .target = target, | |
| 1002 | 1006 | .decl_map = .{}, |
| 1003 | 1007 | .anon_decl_map = .{}, |
| 1004 | 1008 | .named_enum_map = .{}, |
| ... | ... | @@ -1009,9 +1013,11 @@ pub const Object = struct { |
| 1009 | 1013 | .null_opt_usize = .no_init, |
| 1010 | 1014 | .struct_field_map = .{}, |
| 1011 | 1015 | }; |
| 1016 | return obj; | |
| 1012 | 1017 | } |
| 1013 | 1018 | |
| 1014 | pub fn deinit(self: *Object, gpa: Allocator) void { | |
| 1019 | pub fn deinit(self: *Object) void { | |
| 1020 | const gpa = self.gpa; | |
| 1015 | 1021 | self.di_map.deinit(gpa); |
| 1016 | 1022 | self.di_type_map.deinit(gpa); |
| 1017 | 1023 | if (self.builder.useLibLlvm()) { |
| ... | ... | @@ -1028,22 +1034,6 @@ pub const Object = struct { |
| 1028 | 1034 | self.* = undefined; |
| 1029 | 1035 | } |
| 1030 | 1036 | |
| 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 | ||
| 1047 | 1037 | fn genErrorNameTable(o: *Object) Allocator.Error!void { |
| 1048 | 1038 | // If o.error_name_table is null, then it was not referenced by any instructions. |
| 1049 | 1039 | if (o.error_name_table == .none) return; |
| ... | ... | @@ -1182,12 +1172,22 @@ pub const Object = struct { |
| 1182 | 1172 | } |
| 1183 | 1173 | } |
| 1184 | 1174 | |
| 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 | }; | |
| 1190 | 1189 | |
| 1190 | pub fn emit(self: *Object, options: EmitOptions) !void { | |
| 1191 | 1191 | try self.resolveExportExternCollisions(); |
| 1192 | 1192 | try self.genErrorNameTable(); |
| 1193 | 1193 | try self.genCmpLtErrorsLenFunction(); |
| ... | ... | @@ -1213,7 +1213,7 @@ pub const Object = struct { |
| 1213 | 1213 | dib.finalize(); |
| 1214 | 1214 | } |
| 1215 | 1215 | |
| 1216 | if (comp.verbose_llvm_ir) |path| { | |
| 1216 | if (options.pre_ir_path) |path| { | |
| 1217 | 1217 | if (std.mem.eql(u8, path, "-")) { |
| 1218 | 1218 | self.builder.dump(); |
| 1219 | 1219 | } else { |
| ... | ... | @@ -1221,91 +1221,72 @@ pub const Object = struct { |
| 1221 | 1221 | } |
| 1222 | 1222 | } |
| 1223 | 1223 | |
| 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); | |
| 1232 | 1225 | |
| 1233 | 1226 | 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); | |
| 1236 | 1227 | @panic("LLVM module verification failed"); |
| 1237 | 1228 | } |
| 1238 | 1229 | |
| 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)"; | |
| 1252 | 1234 | 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, | |
| 1254 | 1236 | }); |
| 1255 | 1237 | |
| 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; | |
| 1258 | 1240 | |
| 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 | |
| 1263 | 1242 | |
| 1264 | 1243 | // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. |
| 1265 | 1244 | // So we call the entire pipeline multiple times if this is requested. |
| 1266 | 1245 | 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) { | |
| 1268 | 1249 | if (self.target_machine.emitToFile( |
| 1269 | 1250 | self.builder.llvm.module.?, |
| 1270 | 1251 | &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, | |
| 1276 | 1257 | null, |
| 1277 | 1258 | emit_bin_path, |
| 1278 | emit_llvm_ir_path, | |
| 1259 | post_ir_path, | |
| 1279 | 1260 | null, |
| 1280 | 1261 | )) { |
| 1281 | 1262 | defer llvm.disposeMessage(error_message); |
| 1282 | 1263 | |
| 1283 | 1264 | 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, | |
| 1285 | 1266 | }); |
| 1286 | 1267 | return error.FailedToEmit; |
| 1287 | 1268 | } |
| 1288 | 1269 | emit_bin_path = null; |
| 1289 | emit_llvm_ir_path = null; | |
| 1270 | post_ir_path = null; | |
| 1290 | 1271 | } |
| 1291 | 1272 | |
| 1292 | 1273 | if (self.target_machine.emitToFile( |
| 1293 | 1274 | self.builder.llvm.module.?, |
| 1294 | 1275 | &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, | |
| 1301 | 1282 | emit_bin_path, |
| 1302 | emit_llvm_ir_path, | |
| 1303 | emit_llvm_bc_path, | |
| 1283 | post_ir_path, | |
| 1284 | options.post_bc_path, | |
| 1304 | 1285 | )) { |
| 1305 | 1286 | defer llvm.disposeMessage(error_message); |
| 1306 | 1287 | |
| 1307 | 1288 | 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, | |
| 1309 | 1290 | error_message, |
| 1310 | 1291 | }); |
| 1311 | 1292 | return error.FailedToEmit; |
| ... | ... | @@ -1314,17 +1295,19 @@ pub const Object = struct { |
| 1314 | 1295 | |
| 1315 | 1296 | pub fn updateFunc( |
| 1316 | 1297 | o: *Object, |
| 1317 | mod: *Module, | |
| 1298 | zcu: *Module, | |
| 1318 | 1299 | func_index: InternPool.Index, |
| 1319 | 1300 | air: Air, |
| 1320 | 1301 | liveness: Liveness, |
| 1321 | 1302 | ) !void { |
| 1322 | const func = mod.funcInfo(func_index); | |
| 1303 | const func = zcu.funcInfo(func_index); | |
| 1323 | 1304 | 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; | |
| 1328 | 1311 | |
| 1329 | 1312 | var dg: DeclGen = .{ |
| 1330 | 1313 | .object = o, |
| ... | ... | @@ -1359,7 +1342,7 @@ pub const Object = struct { |
| 1359 | 1342 | } |
| 1360 | 1343 | |
| 1361 | 1344 | // 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; | |
| 1363 | 1346 | if (ssp_buf_size != 0) { |
| 1364 | 1347 | try attributes.addFnAttr(.sspstrong, &o.builder); |
| 1365 | 1348 | try attributes.addFnAttr(.{ .string = .{ |
| ... | ... | @@ -1369,7 +1352,7 @@ pub const Object = struct { |
| 1369 | 1352 | } |
| 1370 | 1353 | |
| 1371 | 1354 | // 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) { | |
| 1373 | 1356 | try attributes.addFnAttr(.{ .string = .{ |
| 1374 | 1357 | .kind = try o.builder.string("probe-stack"), |
| 1375 | 1358 | .value = try o.builder.string("__zig_probe_stack"), |
| ... | ... | @@ -1392,20 +1375,22 @@ pub const Object = struct { |
| 1392 | 1375 | var llvm_arg_i: u32 = 0; |
| 1393 | 1376 | |
| 1394 | 1377 | // 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); | |
| 1396 | 1379 | const ret_ptr: Builder.Value = if (sret) param: { |
| 1397 | 1380 | const param = wip.arg(llvm_arg_i); |
| 1398 | 1381 | llvm_arg_i += 1; |
| 1399 | 1382 | break :param param; |
| 1400 | 1383 | } else .none; |
| 1401 | 1384 | |
| 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) { | |
| 1403 | 1386 | .signed => try attributes.addRetAttr(.signext, &o.builder), |
| 1404 | 1387 | .unsigned => try attributes.addRetAttr(.zeroext, &o.builder), |
| 1405 | 1388 | }; |
| 1406 | 1389 | |
| 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; | |
| 1409 | 1394 | |
| 1410 | 1395 | const err_ret_trace: Builder.Value = if (err_return_tracing) param: { |
| 1411 | 1396 | const param = wip.arg(llvm_arg_i); |
| ... | ... | @@ -1433,8 +1418,8 @@ pub const Object = struct { |
| 1433 | 1418 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]); |
| 1434 | 1419 | const param = wip.arg(llvm_arg_i); |
| 1435 | 1420 | |
| 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(); | |
| 1438 | 1423 | const param_llvm_ty = param.typeOfWip(&wip); |
| 1439 | 1424 | const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target); |
| 1440 | 1425 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| ... | ... | @@ -1450,12 +1435,12 @@ pub const Object = struct { |
| 1450 | 1435 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1451 | 1436 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1452 | 1437 | const param = wip.arg(llvm_arg_i); |
| 1453 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | |
| 1438 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1454 | 1439 | |
| 1455 | 1440 | try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty); |
| 1456 | 1441 | llvm_arg_i += 1; |
| 1457 | 1442 | |
| 1458 | if (isByRef(param_ty, mod)) { | |
| 1443 | if (isByRef(param_ty, zcu)) { | |
| 1459 | 1444 | args.appendAssumeCapacity(param); |
| 1460 | 1445 | } else { |
| 1461 | 1446 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | ... | @@ -1465,12 +1450,12 @@ pub const Object = struct { |
| 1465 | 1450 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1466 | 1451 | const param_llvm_ty = try o.lowerType(param_ty); |
| 1467 | 1452 | const param = wip.arg(llvm_arg_i); |
| 1468 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | |
| 1453 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1469 | 1454 | |
| 1470 | 1455 | try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder); |
| 1471 | 1456 | llvm_arg_i += 1; |
| 1472 | 1457 | |
| 1473 | if (isByRef(param_ty, mod)) { | |
| 1458 | if (isByRef(param_ty, zcu)) { | |
| 1474 | 1459 | args.appendAssumeCapacity(param); |
| 1475 | 1460 | } else { |
| 1476 | 1461 | args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, "")); |
| ... | ... | @@ -1483,11 +1468,11 @@ pub const Object = struct { |
| 1483 | 1468 | llvm_arg_i += 1; |
| 1484 | 1469 | |
| 1485 | 1470 | 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(); | |
| 1487 | 1472 | const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target); |
| 1488 | 1473 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1489 | 1474 | |
| 1490 | args.appendAssumeCapacity(if (isByRef(param_ty, mod)) | |
| 1475 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1491 | 1476 | arg_ptr |
| 1492 | 1477 | else |
| 1493 | 1478 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1495,14 +1480,14 @@ pub const Object = struct { |
| 1495 | 1480 | .slice => { |
| 1496 | 1481 | assert(!it.byval_attr); |
| 1497 | 1482 | 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); | |
| 1499 | 1484 | |
| 1500 | 1485 | if (math.cast(u5, it.zig_index - 1)) |i| { |
| 1501 | 1486 | if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) { |
| 1502 | 1487 | try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder); |
| 1503 | 1488 | } |
| 1504 | 1489 | } |
| 1505 | if (param_ty.zigTypeTag(mod) != .Optional) { | |
| 1490 | if (param_ty.zigTypeTag(zcu) != .Optional) { | |
| 1506 | 1491 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| 1507 | 1492 | } |
| 1508 | 1493 | if (ptr_info.flags.is_const) { |
| ... | ... | @@ -1511,7 +1496,7 @@ pub const Object = struct { |
| 1511 | 1496 | const elem_align = (if (ptr_info.flags.alignment != .none) |
| 1512 | 1497 | @as(InternPool.Alignment, ptr_info.flags.alignment) |
| 1513 | 1498 | else |
| 1514 | Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm(); | |
| 1499 | Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm(); | |
| 1515 | 1500 | try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder); |
| 1516 | 1501 | const ptr_param = wip.arg(llvm_arg_i); |
| 1517 | 1502 | llvm_arg_i += 1; |
| ... | ... | @@ -1528,7 +1513,7 @@ pub const Object = struct { |
| 1528 | 1513 | const field_types = it.types_buffer[0..it.types_len]; |
| 1529 | 1514 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 1530 | 1515 | 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(); | |
| 1532 | 1517 | const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, param_alignment, target); |
| 1533 | 1518 | const llvm_ty = try o.builder.structType(.normal, field_types); |
| 1534 | 1519 | for (0..field_types.len) |field_i| { |
| ... | ... | @@ -1540,7 +1525,7 @@ pub const Object = struct { |
| 1540 | 1525 | _ = try wip.store(.normal, param, field_ptr, alignment); |
| 1541 | 1526 | } |
| 1542 | 1527 | |
| 1543 | const is_by_ref = isByRef(param_ty, mod); | |
| 1528 | const is_by_ref = isByRef(param_ty, zcu); | |
| 1544 | 1529 | args.appendAssumeCapacity(if (is_by_ref) |
| 1545 | 1530 | arg_ptr |
| 1546 | 1531 | else |
| ... | ... | @@ -1558,11 +1543,11 @@ pub const Object = struct { |
| 1558 | 1543 | const param = wip.arg(llvm_arg_i); |
| 1559 | 1544 | llvm_arg_i += 1; |
| 1560 | 1545 | |
| 1561 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | |
| 1546 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1562 | 1547 | const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target); |
| 1563 | 1548 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1564 | 1549 | |
| 1565 | args.appendAssumeCapacity(if (isByRef(param_ty, mod)) | |
| 1550 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1566 | 1551 | arg_ptr |
| 1567 | 1552 | else |
| 1568 | 1553 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1573,11 +1558,11 @@ pub const Object = struct { |
| 1573 | 1558 | const param = wip.arg(llvm_arg_i); |
| 1574 | 1559 | llvm_arg_i += 1; |
| 1575 | 1560 | |
| 1576 | const alignment = param_ty.abiAlignment(mod).toLlvm(); | |
| 1561 | const alignment = param_ty.abiAlignment(zcu).toLlvm(); | |
| 1577 | 1562 | const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target); |
| 1578 | 1563 | _ = try wip.store(.normal, param, arg_ptr, alignment); |
| 1579 | 1564 | |
| 1580 | args.appendAssumeCapacity(if (isByRef(param_ty, mod)) | |
| 1565 | args.appendAssumeCapacity(if (isByRef(param_ty, zcu)) | |
| 1581 | 1566 | arg_ptr |
| 1582 | 1567 | else |
| 1583 | 1568 | try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, "")); |
| ... | ... | @@ -1592,11 +1577,11 @@ pub const Object = struct { |
| 1592 | 1577 | var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null; |
| 1593 | 1578 | |
| 1594 | 1579 | 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); | |
| 1596 | 1581 | |
| 1597 | 1582 | 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); | |
| 1600 | 1585 | const noret_bit: c_uint = if (fn_info.return_type == .noreturn_type) |
| 1601 | 1586 | llvm.DIFlags.NoReturn |
| 1602 | 1587 | else |
| ... | ... | @@ -1613,7 +1598,7 @@ pub const Object = struct { |
| 1613 | 1598 | true, // is definition |
| 1614 | 1599 | line_number + func.lbrace_line, // scope line |
| 1615 | 1600 | llvm.DIFlags.StaticMember | noret_bit, |
| 1616 | mod.comp.bin_file.options.optimize_mode != .Debug, | |
| 1601 | owner_mod.optimize_mode != .Debug, | |
| 1617 | 1602 | null, // decl_subprogram |
| 1618 | 1603 | ); |
| 1619 | 1604 | try o.di_map.put(gpa, decl, subprogram.toNode()); |
| ... | ... | @@ -1634,7 +1619,7 @@ pub const Object = struct { |
| 1634 | 1619 | .arg_index = 0, |
| 1635 | 1620 | .func_inst_table = .{}, |
| 1636 | 1621 | .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, | |
| 1638 | 1623 | .di_scope = di_scope, |
| 1639 | 1624 | .di_file = di_file, |
| 1640 | 1625 | .base_line = dg.decl.src_line, |
| ... | ... | @@ -1648,7 +1633,7 @@ pub const Object = struct { |
| 1648 | 1633 | fg.genBody(air.getMainBody()) catch |err| switch (err) { |
| 1649 | 1634 | error.CodegenFail => { |
| 1650 | 1635 | 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.?); | |
| 1652 | 1637 | dg.err_msg = null; |
| 1653 | 1638 | return; |
| 1654 | 1639 | }, |
| ... | ... | @@ -1657,7 +1642,7 @@ pub const Object = struct { |
| 1657 | 1642 | |
| 1658 | 1643 | try fg.wip.finish(); |
| 1659 | 1644 | |
| 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)); | |
| 1661 | 1646 | } |
| 1662 | 1647 | |
| 1663 | 1648 | pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void { |
| ... | ... | @@ -1695,6 +1680,7 @@ pub const Object = struct { |
| 1695 | 1680 | // because we call `updateExports` at the end of `updateFunc` and `updateDecl`. |
| 1696 | 1681 | const global_index = self.decl_map.get(decl_index) orelse return; |
| 1697 | 1682 | const decl = mod.declPtr(decl_index); |
| 1683 | const comp = mod.comp; | |
| 1698 | 1684 | if (decl.isExtern(mod)) { |
| 1699 | 1685 | const decl_name = decl_name: { |
| 1700 | 1686 | const decl_name = mod.intern_pool.stringToSlice(decl.name); |
| ... | ... | @@ -1719,7 +1705,8 @@ pub const Object = struct { |
| 1719 | 1705 | try global_index.rename(decl_name, &self.builder); |
| 1720 | 1706 | global_index.setLinkage(.external, &self.builder); |
| 1721 | 1707 | 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); | |
| 1723 | 1710 | if (self.di_map.get(decl)) |di_node| { |
| 1724 | 1711 | const decl_name_slice = decl_name.slice(&self.builder).?; |
| 1725 | 1712 | if (try decl.isFunction(mod)) { |
| ... | ... | @@ -1785,11 +1772,14 @@ pub const Object = struct { |
| 1785 | 1772 | ); |
| 1786 | 1773 | try global_index.rename(fqn, &self.builder); |
| 1787 | 1774 | 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); | |
| 1789 | 1777 | global_index.setUnnamedAddr(.unnamed_addr, &self.builder); |
| 1790 | 1778 | 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; | |
| 1791 | 1781 | 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) | |
| 1793 | 1783 | .generaldynamic |
| 1794 | 1784 | else |
| 1795 | 1785 | .default, |
| ... | ... | @@ -1842,7 +1832,9 @@ pub const Object = struct { |
| 1842 | 1832 | exports: []const *Module.Export, |
| 1843 | 1833 | ) link.File.UpdateExportsError!void { |
| 1844 | 1834 | 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); | |
| 1846 | 1838 | global_index.setLinkage(switch (exports[0].opts.linkage) { |
| 1847 | 1839 | .Internal => unreachable, |
| 1848 | 1840 | .Strong => .external, |
| ... | ... | @@ -2821,7 +2813,7 @@ pub const Object = struct { |
| 2821 | 2813 | } |
| 2822 | 2814 | |
| 2823 | 2815 | 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) | |
| 2825 | 2817 | { |
| 2826 | 2818 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); |
| 2827 | 2819 | try param_di_types.append(try o.lowerDebugType(ptr_ty, .full)); |
| ... | ... | @@ -2899,7 +2891,7 @@ pub const Object = struct { |
| 2899 | 2891 | fn getStackTraceType(o: *Object) Allocator.Error!Type { |
| 2900 | 2892 | const mod = o.module; |
| 2901 | 2893 | |
| 2902 | const std_mod = mod.main_mod.deps.get("std").?; | |
| 2894 | const std_mod = mod.std_mod; | |
| 2903 | 2895 | const std_file = (mod.importPkg(std_mod) catch unreachable).file; |
| 2904 | 2896 | |
| 2905 | 2897 | const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin"); |
| ... | ... | @@ -2934,22 +2926,24 @@ pub const Object = struct { |
| 2934 | 2926 | o: *Object, |
| 2935 | 2927 | decl_index: InternPool.DeclIndex, |
| 2936 | 2928 | ) 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; | |
| 2939 | 2931 | 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; | |
| 2941 | 2935 | const zig_fn_type = decl.ty; |
| 2942 | 2936 | const gop = try o.decl_map.getOrPut(gpa, decl_index); |
| 2943 | 2937 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| 2944 | 2938 | |
| 2945 | 2939 | 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); | |
| 2949 | 2943 | |
| 2950 | 2944 | const function_index = try o.builder.addFunction( |
| 2951 | 2945 | 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))), | |
| 2953 | 2947 | toLlvmAddressSpace(decl.@"addrspace", target), |
| 2954 | 2948 | ); |
| 2955 | 2949 | gop.value_ptr.* = function_index.ptrConst(&o.builder).global; |
| ... | ... | @@ -2957,7 +2951,7 @@ pub const Object = struct { |
| 2957 | 2951 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 2958 | 2952 | defer attributes.deinit(&o.builder); |
| 2959 | 2953 | |
| 2960 | const is_extern = decl.isExtern(mod); | |
| 2954 | const is_extern = decl.isExtern(zcu); | |
| 2961 | 2955 | if (!is_extern) { |
| 2962 | 2956 | function_index.setLinkage(.internal, &o.builder); |
| 2963 | 2957 | function_index.setUnnamedAddr(.unnamed_addr, &o.builder); |
| ... | ... | @@ -2967,7 +2961,7 @@ pub const Object = struct { |
| 2967 | 2961 | .kind = try o.builder.string("wasm-import-name"), |
| 2968 | 2962 | .value = try o.builder.string(ip.stringToSlice(decl.name)), |
| 2969 | 2963 | } }, &o.builder); |
| 2970 | if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| { | |
| 2964 | if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(zcu).?.lib_name)) |lib_name| { | |
| 2971 | 2965 | if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{ |
| 2972 | 2966 | .kind = try o.builder.string("wasm-import-module"), |
| 2973 | 2967 | .value = try o.builder.string(lib_name), |
| ... | ... | @@ -2988,8 +2982,8 @@ pub const Object = struct { |
| 2988 | 2982 | llvm_arg_i += 1; |
| 2989 | 2983 | } |
| 2990 | 2984 | |
| 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; | |
| 2993 | 2987 | |
| 2994 | 2988 | if (err_return_tracing) { |
| 2995 | 2989 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| ... | ... | @@ -3010,7 +3004,7 @@ pub const Object = struct { |
| 3010 | 3004 | function_index.setAlignment(fn_info.alignment.toLlvm(), &o.builder); |
| 3011 | 3005 | |
| 3012 | 3006 | // Function attributes that are independent of analysis results of the function body. |
| 3013 | try o.addCommonFnAttributes(&attributes); | |
| 3007 | try o.addCommonFnAttributes(&attributes, owner_mod); | |
| 3014 | 3008 | |
| 3015 | 3009 | if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder); |
| 3016 | 3010 | |
| ... | ... | @@ -3023,14 +3017,14 @@ pub const Object = struct { |
| 3023 | 3017 | .byval => { |
| 3024 | 3018 | const param_index = it.zig_index - 1; |
| 3025 | 3019 | 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)) { | |
| 3027 | 3021 | try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1); |
| 3028 | 3022 | } |
| 3029 | 3023 | }, |
| 3030 | 3024 | .byref => { |
| 3031 | 3025 | const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]); |
| 3032 | 3026 | const param_llvm_ty = try o.lowerType(param_ty); |
| 3033 | const alignment = param_ty.abiAlignment(mod); | |
| 3027 | const alignment = param_ty.abiAlignment(zcu); | |
| 3034 | 3028 | try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty); |
| 3035 | 3029 | }, |
| 3036 | 3030 | .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder), |
| ... | ... | @@ -3056,13 +3050,14 @@ pub const Object = struct { |
| 3056 | 3050 | fn addCommonFnAttributes( |
| 3057 | 3051 | o: *Object, |
| 3058 | 3052 | attributes: *Builder.FunctionAttributes.Wip, |
| 3053 | owner_mod: *Package.Module, | |
| 3059 | 3054 | ) Allocator.Error!void { |
| 3060 | 3055 | const comp = o.module.comp; |
| 3061 | 3056 | |
| 3062 | if (!comp.bin_file.options.red_zone) { | |
| 3057 | if (!owner_mod.red_zone) { | |
| 3063 | 3058 | try attributes.addFnAttr(.noredzone, &o.builder); |
| 3064 | 3059 | } |
| 3065 | if (comp.bin_file.options.omit_frame_pointer) { | |
| 3060 | if (owner_mod.omit_frame_pointer) { | |
| 3066 | 3061 | try attributes.addFnAttr(.{ .string = .{ |
| 3067 | 3062 | .kind = try o.builder.string("frame-pointer"), |
| 3068 | 3063 | .value = try o.builder.string("none"), |
| ... | ... | @@ -3074,12 +3069,10 @@ pub const Object = struct { |
| 3074 | 3069 | } }, &o.builder); |
| 3075 | 3070 | } |
| 3076 | 3071 | try attributes.addFnAttr(.nounwind, &o.builder); |
| 3077 | if (comp.unwind_tables) { | |
| 3072 | if (owner_mod.unwind_tables) { | |
| 3078 | 3073 | try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder); |
| 3079 | 3074 | } |
| 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) { | |
| 3083 | 3076 | // The intent here is for compiler-rt and libc functions to not generate |
| 3084 | 3077 | // infinite recursion. For example, if we are compiling the memcpy function, |
| 3085 | 3078 | // and llvm detects that the body is equivalent to memcpy, it may replace the |
| ... | ... | @@ -3087,26 +3080,27 @@ pub const Object = struct { |
| 3087 | 3080 | // overflow instead of performing memcpy. |
| 3088 | 3081 | try attributes.addFnAttr(.nobuiltin, &o.builder); |
| 3089 | 3082 | } |
| 3090 | if (comp.bin_file.options.optimize_mode == .ReleaseSmall) { | |
| 3083 | if (owner_mod.optimize_mode == .ReleaseSmall) { | |
| 3091 | 3084 | try attributes.addFnAttr(.minsize, &o.builder); |
| 3092 | 3085 | try attributes.addFnAttr(.optsize, &o.builder); |
| 3093 | 3086 | } |
| 3094 | if (comp.bin_file.options.tsan) { | |
| 3087 | if (owner_mod.sanitize_thread) { | |
| 3095 | 3088 | try attributes.addFnAttr(.sanitize_thread, &o.builder); |
| 3096 | 3089 | } |
| 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| { | |
| 3098 | 3092 | try attributes.addFnAttr(.{ .string = .{ |
| 3099 | 3093 | .kind = try o.builder.string("target-cpu"), |
| 3100 | 3094 | .value = try o.builder.string(s), |
| 3101 | 3095 | } }, &o.builder); |
| 3102 | 3096 | } |
| 3103 | if (comp.bin_file.options.llvm_cpu_features) |s| { | |
| 3097 | if (owner_mod.resolved_target.llvm_cpu_features) |s| { | |
| 3104 | 3098 | try attributes.addFnAttr(.{ .string = .{ |
| 3105 | 3099 | .kind = try o.builder.string("target-features"), |
| 3106 | 3100 | .value = try o.builder.string(std.mem.span(s)), |
| 3107 | 3101 | } }, &o.builder); |
| 3108 | 3102 | } |
| 3109 | if (comp.getTarget().cpu.arch.isBpf()) { | |
| 3103 | if (target.cpu.arch.isBpf()) { | |
| 3110 | 3104 | try attributes.addFnAttr(.{ .string = .{ |
| 3111 | 3105 | .kind = try o.builder.string("no-builtins"), |
| 3112 | 3106 | .value = .empty, |
| ... | ... | @@ -3176,7 +3170,8 @@ pub const Object = struct { |
| 3176 | 3170 | variable_index.setLinkage(.external, &o.builder); |
| 3177 | 3171 | variable_index.setUnnamedAddr(.default, &o.builder); |
| 3178 | 3172 | 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; | |
| 3180 | 3175 | variable_index.setThreadLocal( |
| 3181 | 3176 | if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default, |
| 3182 | 3177 | &o.builder, |
| ... | ... | @@ -3679,7 +3674,7 @@ pub const Object = struct { |
| 3679 | 3674 | } |
| 3680 | 3675 | |
| 3681 | 3676 | 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) | |
| 3683 | 3678 | { |
| 3684 | 3679 | const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); |
| 3685 | 3680 | try llvm_params.append(o.gpa, try o.lowerType(ptr_ty)); |
| ... | ... | @@ -4648,6 +4643,100 @@ pub const Object = struct { |
| 4648 | 4643 | .field_index = @intCast(field_index), |
| 4649 | 4644 | }); |
| 4650 | 4645 | } |
| 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 | } | |
| 4651 | 4740 | }; |
| 4652 | 4741 | |
| 4653 | 4742 | pub const DeclGen = struct { |
| ... | ... | @@ -4656,6 +4745,13 @@ pub const DeclGen = struct { |
| 4656 | 4745 | decl_index: InternPool.DeclIndex, |
| 4657 | 4746 | err_msg: ?*Module.ErrorMsg, |
| 4658 | 4747 | |
| 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 | ||
| 4659 | 4755 | fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error { |
| 4660 | 4756 | @setCold(true); |
| 4661 | 4757 | assert(dg.err_msg == null); |
| ... | ... | @@ -5144,7 +5240,7 @@ pub const FuncGen = struct { |
| 5144 | 5240 | }; |
| 5145 | 5241 | |
| 5146 | 5242 | 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; | |
| 5148 | 5244 | if (err_return_tracing) { |
| 5149 | 5245 | assert(self.err_ret_trace != .none); |
| 5150 | 5246 | try llvm_args.append(self.err_ret_trace); |
| ... | ... | @@ -5616,7 +5712,7 @@ pub const FuncGen = struct { |
| 5616 | 5712 | const o = self.dg.object; |
| 5617 | 5713 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 5618 | 5714 | const operand = try self.resolveInst(un_op); |
| 5619 | const llvm_fn = try self.getCmpLtErrorsLenFunction(); | |
| 5715 | const llvm_fn = try o.getCmpLtErrorsLenFunction(); | |
| 5620 | 5716 | return self.wip.call( |
| 5621 | 5717 | .normal, |
| 5622 | 5718 | .fastcc, |
| ... | ... | @@ -6549,11 +6645,13 @@ pub const FuncGen = struct { |
| 6549 | 6645 | const dib = o.di_builder orelse return .none; |
| 6550 | 6646 | const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn; |
| 6551 | 6647 | |
| 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); | |
| 6554 | 6650 | 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); | |
| 6557 | 6655 | self.di_file = di_file; |
| 6558 | 6656 | const line_number = decl.src_line + 1; |
| 6559 | 6657 | const cur_debug_location = self.wip.llvm.builder.getCurrentDebugLocation2(); |
| ... | ... | @@ -6564,18 +6662,18 @@ pub const FuncGen = struct { |
| 6564 | 6662 | .base_line = self.base_line, |
| 6565 | 6663 | }); |
| 6566 | 6664 | |
| 6567 | const fqn = try decl.getFullyQualifiedName(mod); | |
| 6665 | const fqn = try decl.getFullyQualifiedName(zcu); | |
| 6568 | 6666 | |
| 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(.{ | |
| 6571 | 6669 | .param_types = &.{}, |
| 6572 | 6670 | .return_type = .void_type, |
| 6573 | 6671 | }); |
| 6574 | 6672 | const fn_di_ty = try o.lowerDebugType(fn_ty, .full); |
| 6575 | 6673 | const subprogram = dib.createFunction( |
| 6576 | 6674 | 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), | |
| 6579 | 6677 | di_file, |
| 6580 | 6678 | line_number, |
| 6581 | 6679 | fn_di_ty, |
| ... | ... | @@ -6583,7 +6681,7 @@ pub const FuncGen = struct { |
| 6583 | 6681 | true, // is definition |
| 6584 | 6682 | line_number + func.lbrace_line, // scope line |
| 6585 | 6683 | llvm.DIFlags.StaticMember, |
| 6586 | mod.comp.bin_file.options.optimize_mode != .Debug, | |
| 6684 | owner_mod.optimize_mode != .Debug, | |
| 6587 | 6685 | null, // decl_subprogram |
| 6588 | 6686 | ); |
| 6589 | 6687 | |
| ... | ... | @@ -6678,11 +6776,12 @@ pub const FuncGen = struct { |
| 6678 | 6776 | null; |
| 6679 | 6777 | const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at); |
| 6680 | 6778 | 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)) { | |
| 6683 | 6782 | _ = 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(); | |
| 6686 | 6785 | const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment); |
| 6687 | 6786 | _ = try self.wip.store(.normal, operand, alloca, alignment); |
| 6688 | 6787 | _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block); |
| ... | ... | @@ -8731,9 +8830,10 @@ pub const FuncGen = struct { |
| 8731 | 8830 | |
| 8732 | 8831 | const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null); |
| 8733 | 8832 | const insert_block = self.wip.cursor.block.toLlvm(&self.wip); |
| 8833 | const owner_mod = self.dg.ownerModule(); | |
| 8734 | 8834 | if (isByRef(inst_ty, mod)) { |
| 8735 | 8835 | _ = 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) { | |
| 8737 | 8837 | const alignment = inst_ty.abiAlignment(mod).toLlvm(); |
| 8738 | 8838 | const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment); |
| 8739 | 8839 | _ = try self.wip.store(.normal, arg_val, alloca, alignment); |
| ... | ... | @@ -8823,7 +8923,8 @@ pub const FuncGen = struct { |
| 8823 | 8923 | len, |
| 8824 | 8924 | if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal, |
| 8825 | 8925 | ); |
| 8826 | if (safety and mod.comp.bin_file.options.valgrind) { | |
| 8926 | const owner_mod = self.dg.ownerModule(); | |
| 8927 | if (safety and owner_mod.valgrind) { | |
| 8827 | 8928 | try self.valgrindMarkUndef(dest_ptr, len); |
| 8828 | 8929 | } |
| 8829 | 8930 | return .none; |
| ... | ... | @@ -9139,7 +9240,8 @@ pub const FuncGen = struct { |
| 9139 | 9240 | } else { |
| 9140 | 9241 | _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind); |
| 9141 | 9242 | } |
| 9142 | if (safety and mod.comp.bin_file.options.valgrind) { | |
| 9243 | const owner_mod = self.dg.ownerModule(); | |
| 9244 | if (safety and owner_mod.valgrind) { | |
| 9143 | 9245 | try self.valgrindMarkUndef(dest_ptr, len); |
| 9144 | 9246 | } |
| 9145 | 9247 | return .none; |
| ... | ... | @@ -9490,24 +9592,25 @@ pub const FuncGen = struct { |
| 9490 | 9592 | |
| 9491 | 9593 | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index { |
| 9492 | 9594 | 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; | |
| 9495 | 9597 | |
| 9496 | 9598 | // TODO: detect when the type changes and re-emit this function. |
| 9497 | 9599 | const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl); |
| 9498 | 9600 | if (gop.found_existing) return gop.value_ptr.*; |
| 9499 | 9601 | errdefer assert(o.named_enum_map.remove(enum_type.decl)); |
| 9500 | 9602 | |
| 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; | |
| 9502 | 9605 | const function_index = try o.builder.addFunction( |
| 9503 | 9606 | 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), | |
| 9506 | 9609 | ); |
| 9507 | 9610 | |
| 9508 | 9611 | var attributes: Builder.FunctionAttributes.Wip = .{}; |
| 9509 | 9612 | defer attributes.deinit(&o.builder); |
| 9510 | try o.addCommonFnAttributes(&attributes); | |
| 9613 | try o.addCommonFnAttributes(&attributes, zcu.root_mod); | |
| 9511 | 9614 | |
| 9512 | 9615 | function_index.setLinkage(.internal, &o.builder); |
| 9513 | 9616 | function_index.setCallConv(.fastcc, &o.builder); |
| ... | ... | @@ -9526,7 +9629,7 @@ pub const FuncGen = struct { |
| 9526 | 9629 | |
| 9527 | 9630 | for (0..enum_type.names.len) |field_index| { |
| 9528 | 9631 | 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(), | |
| 9530 | 9633 | ); |
| 9531 | 9634 | try wip_switch.addCase(this_tag_int_value, named_block, &wip); |
| 9532 | 9635 | } |
| ... | ... | @@ -9546,7 +9649,7 @@ pub const FuncGen = struct { |
| 9546 | 9649 | const operand = try self.resolveInst(un_op); |
| 9547 | 9650 | const enum_ty = self.typeOf(un_op); |
| 9548 | 9651 | |
| 9549 | const llvm_fn = try self.getEnumTagNameFunction(enum_ty); | |
| 9652 | const llvm_fn = try o.getEnumTagNameFunction(enum_ty); | |
| 9550 | 9653 | return self.wip.call( |
| 9551 | 9654 | .normal, |
| 9552 | 9655 | .fastcc, |
| ... | ... | @@ -9558,100 +9661,6 @@ pub const FuncGen = struct { |
| 9558 | 9661 | ); |
| 9559 | 9662 | } |
| 9560 | 9663 | |
| 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 | ||
| 9655 | 9664 | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9656 | 9665 | const o = self.dg.object; |
| 9657 | 9666 | 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 { |
| 191 | 191 | air: Air, |
| 192 | 192 | liveness: Liveness, |
| 193 | 193 | ) !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; | |
| 201 | 197 | |
| 202 | 198 | var decl_gen = DeclGen{ |
| 203 | 199 | .gpa = self.gpa, |
| ... | ... | @@ -208,7 +204,7 @@ pub const Object = struct { |
| 208 | 204 | .air = air, |
| 209 | 205 | .liveness = liveness, |
| 210 | 206 | .type_map = &self.type_map, |
| 211 | .control_flow = switch (want_structured_cfg) { | |
| 207 | .control_flow = switch (structured_cfg) { | |
| 212 | 208 | true => .{ .structured = .{} }, |
| 213 | 209 | false => .{ .unstructured = .{} }, |
| 214 | 210 | }, |
src/glibc.zig+68-32| ... | ... | @@ -12,7 +12,7 @@ const Compilation = @import("Compilation.zig"); |
| 12 | 12 | const build_options = @import("build_options"); |
| 13 | 13 | const trace = @import("tracy.zig").trace; |
| 14 | 14 | const Cache = std.Build.Cache; |
| 15 | const Package = @import("Package.zig"); | |
| 15 | const Module = @import("Package/Module.zig"); | |
| 16 | 16 | |
| 17 | 17 | pub const Lib = struct { |
| 18 | 18 | name: []const u8, |
| ... | ... | @@ -170,7 +170,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 170 | 170 | defer arena_allocator.deinit(); |
| 171 | 171 | const arena = arena_allocator.allocator(); |
| 172 | 172 | |
| 173 | const target = comp.getTarget(); | |
| 173 | const target = comp.root_mod.resolved_target.result; | |
| 174 | 174 | const target_ver = target.os.version_range.linux.glibc; |
| 175 | 175 | const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt; |
| 176 | 176 | |
| ... | ... | @@ -196,12 +196,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 196 | 196 | "-DASSEMBLER", |
| 197 | 197 | "-Wa,--noexecstack", |
| 198 | 198 | }); |
| 199 | return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &.{ | |
| 199 | var files = [_]Compilation.CSourceFile{ | |
| 200 | 200 | .{ |
| 201 | 201 | .src_path = try start_asm_path(comp, arena, "crti.S"), |
| 202 | 202 | .cache_exempt_flags = args.items, |
| 203 | .owner = comp.root_mod, | |
| 203 | 204 | }, |
| 204 | }); | |
| 205 | }; | |
| 206 | return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &files); | |
| 205 | 207 | }, |
| 206 | 208 | .crtn_o => { |
| 207 | 209 | var args = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -215,12 +217,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 215 | 217 | "-DASSEMBLER", |
| 216 | 218 | "-Wa,--noexecstack", |
| 217 | 219 | }); |
| 218 | return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &.{ | |
| 220 | var files = [_]Compilation.CSourceFile{ | |
| 219 | 221 | .{ |
| 220 | 222 | .src_path = try start_asm_path(comp, arena, "crtn.S"), |
| 221 | 223 | .cache_exempt_flags = args.items, |
| 224 | .owner = undefined, | |
| 222 | 225 | }, |
| 223 | }); | |
| 226 | }; | |
| 227 | return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &files); | |
| 224 | 228 | }, |
| 225 | 229 | .scrt1_o => { |
| 226 | 230 | const start_o: Compilation.CSourceFile = blk: { |
| ... | ... | @@ -244,6 +248,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 244 | 248 | break :blk .{ |
| 245 | 249 | .src_path = try start_asm_path(comp, arena, src_path), |
| 246 | 250 | .cache_exempt_flags = args.items, |
| 251 | .owner = undefined, | |
| 247 | 252 | }; |
| 248 | 253 | }; |
| 249 | 254 | const abi_note_o: Compilation.CSourceFile = blk: { |
| ... | ... | @@ -263,11 +268,11 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 263 | 268 | break :blk .{ |
| 264 | 269 | .src_path = try lib_path(comp, arena, lib_libc_glibc ++ "csu" ++ path.sep_str ++ "abi-note.S"), |
| 265 | 270 | .cache_exempt_flags = args.items, |
| 271 | .owner = undefined, | |
| 266 | 272 | }; |
| 267 | 273 | }; |
| 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); | |
| 271 | 276 | }, |
| 272 | 277 | .libc_nonshared_a => { |
| 273 | 278 | const s = path.sep_str; |
| ... | ... | @@ -364,6 +369,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 364 | 369 | files_buf[files_index] = .{ |
| 365 | 370 | .src_path = try lib_path(comp, arena, dep.path), |
| 366 | 371 | .cache_exempt_flags = args.items, |
| 372 | .owner = undefined, | |
| 367 | 373 | }; |
| 368 | 374 | files_index += 1; |
| 369 | 375 | } |
| ... | ... | @@ -1061,40 +1067,70 @@ fn buildSharedLib( |
| 1061 | 1067 | const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 }; |
| 1062 | 1068 | const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?); |
| 1063 | 1069 | 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 | ||
| 1065 | 1112 | const c_source_files = [1]Compilation.CSourceFile{ |
| 1066 | 1113 | .{ |
| 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, | |
| 1068 | 1116 | }, |
| 1069 | 1117 | }; |
| 1070 | const sub_compilation = try Compilation.create(comp.gpa, .{ | |
| 1118 | ||
| 1119 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | |
| 1071 | 1120 | .local_cache_directory = zig_cache_directory, |
| 1072 | 1121 | .global_cache_directory = comp.global_cache_directory, |
| 1073 | 1122 | .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, | |
| 1080 | 1123 | .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, | |
| 1082 | 1130 | .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, | |
| 1091 | 1131 | .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, | |
| 1096 | 1132 | .verbose_cc = comp.verbose_cc, |
| 1097 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 1133 | .verbose_link = comp.verbose_link, | |
| 1098 | 1134 | .verbose_air = comp.verbose_air, |
| 1099 | 1135 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 1100 | 1136 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
src/libc_installation.zig+6-7| ... | ... | @@ -41,7 +41,7 @@ pub const LibCInstallation = struct { |
| 41 | 41 | pub fn parse( |
| 42 | 42 | allocator: Allocator, |
| 43 | 43 | libc_file: []const u8, |
| 44 | target: std.zig.CrossTarget, | |
| 44 | target: std.Target, | |
| 45 | 45 | ) !LibCInstallation { |
| 46 | 46 | var self: LibCInstallation = .{}; |
| 47 | 47 | |
| ... | ... | @@ -95,24 +95,23 @@ pub const LibCInstallation = struct { |
| 95 | 95 | return error.ParseError; |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | const os_tag = target.getOsTag(); | |
| 98 | const os_tag = target.os.tag; | |
| 99 | 99 | if (self.crt_dir == null and !target.isDarwin()) { |
| 100 | 100 | log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)}); |
| 101 | 101 | return error.ParseError; |
| 102 | 102 | } |
| 103 | 103 | |
| 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) { | |
| 106 | 105 | log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{ |
| 107 | 106 | @tagName(os_tag), |
| 108 | @tagName(abi), | |
| 107 | @tagName(target.abi), | |
| 109 | 108 | }); |
| 110 | 109 | return error.ParseError; |
| 111 | 110 | } |
| 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) { | |
| 113 | 112 | log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{ |
| 114 | 113 | @tagName(os_tag), |
| 115 | @tagName(abi), | |
| 114 | @tagName(target.abi), | |
| 116 | 115 | }); |
| 117 | 116 | return error.ParseError; |
| 118 | 117 | } |
src/libcxx.zig+112-65| ... | ... | @@ -6,6 +6,7 @@ const target_util = @import("target.zig"); |
| 6 | 6 | const Compilation = @import("Compilation.zig"); |
| 7 | 7 | const build_options = @import("build_options"); |
| 8 | 8 | const trace = @import("tracy.zig").trace; |
| 9 | const Module = @import("Package/Module.zig"); | |
| 9 | 10 | |
| 10 | 11 | pub const AbiVersion = enum(u2) { |
| 11 | 12 | @"1" = 1, |
| ... | ... | @@ -115,7 +116,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 115 | 116 | const root_name = "c++"; |
| 116 | 117 | const output_mode = .Lib; |
| 117 | 118 | const link_mode = .Static; |
| 118 | const target = comp.getTarget(); | |
| 119 | const target = comp.root_mod.resolved_target.result; | |
| 119 | 120 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 120 | 121 | .root_name = root_name, |
| 121 | 122 | .target = target, |
| ... | ... | @@ -137,6 +138,50 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 137 | 138 | const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ |
| 138 | 139 | @intFromEnum(comp.libcxx_abi_version), |
| 139 | 140 | }); |
| 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 | ||
| 140 | 185 | var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxx_files.len); |
| 141 | 186 | |
| 142 | 187 | for (libcxx_files) |cxx_src| { |
| ... | ... | @@ -154,7 +199,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 154 | 199 | continue; |
| 155 | 200 | if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos) |
| 156 | 201 | continue; |
| 157 | if (comp.bin_file.options.single_threaded) { | |
| 202 | if (!comp.config.any_non_single_threaded) { | |
| 158 | 203 | if (std.mem.startsWith(u8, cxx_src, "src/support/win32/thread_win32.cpp")) { |
| 159 | 204 | continue; |
| 160 | 205 | } |
| ... | ... | @@ -223,49 +268,32 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 223 | 268 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }), |
| 224 | 269 | .extra_flags = cflags.items, |
| 225 | 270 | .cache_exempt_flags = cache_exempt_flags.items, |
| 271 | .owner = root_mod, | |
| 226 | 272 | }); |
| 227 | 273 | } |
| 228 | 274 | |
| 229 | const sub_compilation = try Compilation.create(comp.gpa, .{ | |
| 275 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | |
| 230 | 276 | .local_cache_directory = comp.global_cache_directory, |
| 231 | 277 | .global_cache_directory = comp.global_cache_directory, |
| 232 | 278 | .zig_lib_directory = comp.zig_lib_directory, |
| 279 | .self_exe_path = comp.self_exe_path, | |
| 233 | 280 | .cache_mode = .whole, |
| 234 | .target = target, | |
| 281 | .config = config, | |
| 282 | .root_mod = root_mod, | |
| 235 | 283 | .root_name = root_name, |
| 236 | .main_mod = null, | |
| 237 | .output_mode = output_mode, | |
| 238 | 284 | .thread_pool = comp.thread_pool, |
| 239 | .libc_installation = comp.bin_file.options.libc_installation, | |
| 285 | .libc_installation = comp.libc_installation, | |
| 240 | 286 | .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, | |
| 254 | 287 | .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, | |
| 259 | 288 | .c_source_files = c_source_files.items, |
| 260 | 289 | .verbose_cc = comp.verbose_cc, |
| 261 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 290 | .verbose_link = comp.verbose_link, | |
| 262 | 291 | .verbose_air = comp.verbose_air, |
| 263 | 292 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 264 | 293 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
| 265 | 294 | .verbose_cimport = comp.verbose_cimport, |
| 266 | 295 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 267 | 296 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 268 | .link_libc = true, | |
| 269 | 297 | .skip_linker_dependencies = true, |
| 270 | 298 | }); |
| 271 | 299 | defer sub_compilation.destroy(); |
| ... | ... | @@ -273,12 +301,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 273 | 301 | try comp.updateSubCompilation(sub_compilation, .libcxx, prog_node); |
| 274 | 302 | |
| 275 | 303 | 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(); | |
| 282 | 305 | } |
| 283 | 306 | |
| 284 | 307 | pub 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 { |
| 296 | 319 | const root_name = "c++abi"; |
| 297 | 320 | const output_mode = .Lib; |
| 298 | 321 | const link_mode = .Static; |
| 299 | const target = comp.getTarget(); | |
| 322 | const target = comp.root_mod.resolved_target.result; | |
| 300 | 323 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 301 | 324 | .root_name = root_name, |
| 302 | 325 | .target = target, |
| ... | ... | @@ -318,6 +341,53 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 318 | 341 | const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ |
| 319 | 342 | @intFromEnum(comp.libcxx_abi_version), |
| 320 | 343 | }); |
| 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 | ||
| 321 | 391 | var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len); |
| 322 | 392 | |
| 323 | 393 | for (libcxxabi_files) |cxxabi_src| { |
| ... | ... | @@ -332,7 +402,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 332 | 402 | } |
| 333 | 403 | |
| 334 | 404 | // WASM targets are single threaded. |
| 335 | if (comp.bin_file.options.single_threaded) { | |
| 405 | if (!comp.config.any_non_single_threaded) { | |
| 336 | 406 | if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_thread_atexit.cpp")) { |
| 337 | 407 | continue; |
| 338 | 408 | } |
| ... | ... | @@ -365,7 +435,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 365 | 435 | } |
| 366 | 436 | try cflags.append("-nostdinc++"); |
| 367 | 437 | try cflags.append("-fstrict-aliasing"); |
| 368 | try cflags.append("-funwind-tables"); | |
| 369 | 438 | try cflags.append("-std=c++20"); |
| 370 | 439 | |
| 371 | 440 | // 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 { |
| 386 | 455 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }), |
| 387 | 456 | .extra_flags = cflags.items, |
| 388 | 457 | .cache_exempt_flags = cache_exempt_flags.items, |
| 458 | .owner = root_mod, | |
| 389 | 459 | }); |
| 390 | 460 | } |
| 391 | 461 | |
| 392 | const sub_compilation = try Compilation.create(comp.gpa, .{ | |
| 462 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | |
| 393 | 463 | .local_cache_directory = comp.global_cache_directory, |
| 394 | 464 | .global_cache_directory = comp.global_cache_directory, |
| 395 | 465 | .zig_lib_directory = comp.zig_lib_directory, |
| 466 | .self_exe_path = comp.self_exe_path, | |
| 396 | 467 | .cache_mode = .whole, |
| 397 | .target = target, | |
| 468 | .config = config, | |
| 469 | .root_mod = root_mod, | |
| 398 | 470 | .root_name = root_name, |
| 399 | .main_mod = null, | |
| 400 | .output_mode = output_mode, | |
| 401 | 471 | .thread_pool = comp.thread_pool, |
| 402 | .libc_installation = comp.bin_file.options.libc_installation, | |
| 472 | .libc_installation = comp.libc_installation, | |
| 403 | 473 | .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, | |
| 417 | 474 | .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, | |
| 422 | 475 | .c_source_files = c_source_files.items, |
| 423 | 476 | .verbose_cc = comp.verbose_cc, |
| 424 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 477 | .verbose_link = comp.verbose_link, | |
| 425 | 478 | .verbose_air = comp.verbose_air, |
| 426 | 479 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 427 | 480 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
| 428 | 481 | .verbose_cimport = comp.verbose_cimport, |
| 429 | 482 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 430 | 483 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 431 | .link_libc = true, | |
| 432 | 484 | .skip_linker_dependencies = true, |
| 433 | 485 | }); |
| 434 | 486 | defer sub_compilation.destroy(); |
| ... | ... | @@ -436,10 +488,5 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 436 | 488 | try comp.updateSubCompilation(sub_compilation, .libcxxabi, prog_node); |
| 437 | 489 | |
| 438 | 490 | 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(); | |
| 445 | 492 | } |
src/libtsan.zig+64-34| ... | ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; |
| 4 | 4 | const Compilation = @import("Compilation.zig"); |
| 5 | 5 | const build_options = @import("build_options"); |
| 6 | 6 | const trace = @import("tracy.zig").trace; |
| 7 | const Module = @import("Package/Module.zig"); | |
| 7 | 8 | |
| 8 | 9 | pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 9 | 10 | if (!build_options.have_llvm) { |
| ... | ... | @@ -33,6 +34,52 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 33 | 34 | .basename = basename, |
| 34 | 35 | }; |
| 35 | 36 | |
| 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 | ||
| 36 | 83 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 37 | 84 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); |
| 38 | 85 | |
| ... | ... | @@ -49,8 +96,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 49 | 96 | try cflags.append("-fno-rtti"); |
| 50 | 97 | |
| 51 | 98 | 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 }), | |
| 53 | 100 | .extra_flags = cflags.items, |
| 101 | .owner = root_mod, | |
| 54 | 102 | }); |
| 55 | 103 | } |
| 56 | 104 | |
| ... | ... | @@ -73,6 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 73 | 121 | c_source_files.appendAssumeCapacity(.{ |
| 74 | 122 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "tsan", tsan_src }), |
| 75 | 123 | .extra_flags = cflags.items, |
| 124 | .owner = root_mod, | |
| 76 | 125 | }); |
| 77 | 126 | } |
| 78 | 127 | { |
| ... | ... | @@ -93,6 +142,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 93 | 142 | c_source_files.appendAssumeCapacity(.{ |
| 94 | 143 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "tsan", asm_source }), |
| 95 | 144 | .extra_flags = cflags.items, |
| 145 | .owner = root_mod, | |
| 96 | 146 | }); |
| 97 | 147 | } |
| 98 | 148 | |
| ... | ... | @@ -116,10 +166,11 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 116 | 166 | "tsan", "sanitizer_common", common_src, |
| 117 | 167 | }), |
| 118 | 168 | .extra_flags = cflags.items, |
| 169 | .owner = root_mod, | |
| 119 | 170 | }); |
| 120 | 171 | } |
| 121 | 172 | |
| 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) | |
| 123 | 174 | &sanitizer_libcdep_sources |
| 124 | 175 | else |
| 125 | 176 | &sanitizer_nolibc_sources; |
| ... | ... | @@ -140,6 +191,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 140 | 191 | "tsan", "sanitizer_common", c_src, |
| 141 | 192 | }), |
| 142 | 193 | .extra_flags = cflags.items, |
| 194 | .owner = root_mod, | |
| 143 | 195 | }); |
| 144 | 196 | } |
| 145 | 197 | |
| ... | ... | @@ -160,6 +212,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 160 | 212 | "tsan", "sanitizer_common", c_src, |
| 161 | 213 | }), |
| 162 | 214 | .extra_flags = cflags.items, |
| 215 | .owner = root_mod, | |
| 163 | 216 | }); |
| 164 | 217 | } |
| 165 | 218 | |
| ... | ... | @@ -188,63 +241,40 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 188 | 241 | "tsan", "interception", c_src, |
| 189 | 242 | }), |
| 190 | 243 | .extra_flags = cflags.items, |
| 244 | .owner = root_mod, | |
| 191 | 245 | }); |
| 192 | 246 | } |
| 193 | 247 | |
| 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, .{ | |
| 199 | 249 | .local_cache_directory = comp.global_cache_directory, |
| 200 | 250 | .global_cache_directory = comp.global_cache_directory, |
| 201 | 251 | .zig_lib_directory = comp.zig_lib_directory, |
| 252 | .thread_pool = comp.thread_pool, | |
| 253 | .self_exe_path = comp.self_exe_path, | |
| 202 | 254 | .cache_mode = .whole, |
| 203 | .target = target, | |
| 255 | .config = config, | |
| 256 | .root_mod = root_mod, | |
| 204 | 257 | .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, | |
| 209 | 259 | .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, | |
| 219 | 260 | .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, | |
| 224 | 261 | .c_source_files = c_source_files.items, |
| 225 | 262 | .verbose_cc = comp.verbose_cc, |
| 226 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 263 | .verbose_link = comp.verbose_link, | |
| 227 | 264 | .verbose_air = comp.verbose_air, |
| 228 | 265 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 229 | 266 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
| 230 | 267 | .verbose_cimport = comp.verbose_cimport, |
| 231 | 268 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 232 | 269 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 233 | .link_libc = true, | |
| 234 | 270 | .skip_linker_dependencies = true, |
| 235 | .clang_argv = &common_flags, | |
| 236 | 271 | }); |
| 237 | 272 | defer sub_compilation.destroy(); |
| 238 | 273 | |
| 239 | 274 | try comp.updateSubCompilation(sub_compilation, .libtsan, prog_node); |
| 240 | 275 | |
| 241 | 276 | 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(); | |
| 248 | 278 | } |
| 249 | 279 | |
| 250 | 280 | const tsan_sources = [_][]const u8{ |
src/libunwind.zig+53-36| ... | ... | @@ -4,6 +4,7 @@ const assert = std.debug.assert; |
| 4 | 4 | |
| 5 | 5 | const target_util = @import("target.zig"); |
| 6 | 6 | const Compilation = @import("Compilation.zig"); |
| 7 | const Module = @import("Package/Module.zig"); | |
| 7 | 8 | const build_options = @import("build_options"); |
| 8 | 9 | const trace = @import("tracy.zig").trace; |
| 9 | 10 | |
| ... | ... | @@ -19,10 +20,49 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 19 | 20 | defer arena_allocator.deinit(); |
| 20 | 21 | const arena = arena_allocator.allocator(); |
| 21 | 22 | |
| 22 | const root_name = "unwind"; | |
| 23 | 23 | 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"; | |
| 24 | 64 | const link_mode = .Static; |
| 25 | const target = comp.getTarget(); | |
| 65 | const target = comp.root_mod.resolved_target.result; | |
| 26 | 66 | const basename = try std.zig.binNameAlloc(arena, .{ |
| 27 | 67 | .root_name = root_name, |
| 28 | 68 | .target = target, |
| ... | ... | @@ -64,10 +104,10 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 64 | 104 | // defines will be correct. |
| 65 | 105 | try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); |
| 66 | 106 | |
| 67 | if (comp.bin_file.options.optimize_mode == .Debug) { | |
| 107 | if (comp.root_mod.optimize_mode == .Debug) { | |
| 68 | 108 | try cflags.append("-D_DEBUG"); |
| 69 | 109 | } |
| 70 | if (comp.bin_file.options.single_threaded) { | |
| 110 | if (!comp.config.any_non_single_threaded) { | |
| 71 | 111 | try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS"); |
| 72 | 112 | } |
| 73 | 113 | 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 { |
| 80 | 120 | c_source_files[i] = .{ |
| 81 | 121 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}), |
| 82 | 122 | .extra_flags = cflags.items, |
| 123 | .owner = root_mod, | |
| 83 | 124 | }; |
| 84 | 125 | } |
| 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, | |
| 86 | 128 | .local_cache_directory = comp.global_cache_directory, |
| 87 | 129 | .global_cache_directory = comp.global_cache_directory, |
| 88 | 130 | .zig_lib_directory = comp.zig_lib_directory, |
| 131 | .config = config, | |
| 132 | .root_mod = root_mod, | |
| 89 | 133 | .cache_mode = .whole, |
| 90 | .target = target, | |
| 91 | 134 | .root_name = root_name, |
| 92 | 135 | .main_mod = null, |
| 93 | .output_mode = output_mode, | |
| 94 | 136 | .thread_pool = comp.thread_pool, |
| 95 | .libc_installation = comp.bin_file.options.libc_installation, | |
| 137 | .libc_installation = comp.libc_installation, | |
| 96 | 138 | .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, | |
| 116 | 140 | .c_source_files = &c_source_files, |
| 117 | 141 | .verbose_cc = comp.verbose_cc, |
| 118 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 142 | .verbose_link = comp.verbose_link, | |
| 119 | 143 | .verbose_air = comp.verbose_air, |
| 120 | 144 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 121 | 145 | .verbose_llvm_bc = comp.verbose_llvm_bc, |
| 122 | 146 | .verbose_cimport = comp.verbose_cimport, |
| 123 | 147 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 124 | 148 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 125 | .link_libc = true, | |
| 126 | 149 | .skip_linker_dependencies = true, |
| 127 | 150 | }); |
| 128 | 151 | defer sub_compilation.destroy(); |
| ... | ... | @@ -130,13 +153,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 130 | 153 | try comp.updateSubCompilation(sub_compilation, .libunwind, prog_node); |
| 131 | 154 | |
| 132 | 155 | 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(); | |
| 140 | 157 | } |
| 141 | 158 | |
| 142 | 159 | const unwind_src_list = [_][]const u8{ |
src/link.zig+397-653| ... | ... | @@ -10,7 +10,6 @@ const wasi_libc = @import("wasi_libc.zig"); |
| 10 | 10 | |
| 11 | 11 | const Air = @import("Air.zig"); |
| 12 | 12 | const Allocator = std.mem.Allocator; |
| 13 | const BuildId = std.Build.CompileStep.BuildId; | |
| 14 | 13 | const Cache = std.Build.Cache; |
| 15 | 14 | const Compilation = @import("Compilation.zig"); |
| 16 | 15 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| ... | ... | @@ -19,6 +18,7 @@ const Module = @import("Module.zig"); |
| 19 | 18 | const InternPool = @import("InternPool.zig"); |
| 20 | 19 | const Type = @import("type.zig").Type; |
| 21 | 20 | const TypedValue = @import("TypedValue.zig"); |
| 21 | const LlvmObject = @import("codegen/llvm.zig").Object; | |
| 22 | 22 | |
| 23 | 23 | /// When adding a new field, remember to update `hashAddSystemLibs`. |
| 24 | 24 | /// These are *always* dynamically linked. Static libraries will be |
| ... | ... | @@ -33,17 +33,6 @@ pub const SystemLib = struct { |
| 33 | 33 | path: ?[]const u8, |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | /// When adding a new field, remember to update `hashAddFrameworks`. | |
| 37 | pub const Framework = struct { | |
| 38 | needed: bool = false, | |
| 39 | weak: bool = false, | |
| 40 | path: []const u8, | |
| 41 | }; | |
| 42 | ||
| 43 | pub const SortSection = enum { name, alignment }; | |
| 44 | ||
| 45 | pub const CacheMode = enum { incremental, whole }; | |
| 46 | ||
| 47 | 36 | pub fn hashAddSystemLibs( |
| 48 | 37 | man: *Cache.Manifest, |
| 49 | 38 | hm: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | ... | @@ -57,355 +46,172 @@ pub fn hashAddSystemLibs( |
| 57 | 46 | } |
| 58 | 47 | } |
| 59 | 48 | |
| 60 | pub 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 | ||
| 68 | 49 | pub const producer_string = if (builtin.is_test) "zig test" else "zig " ++ build_options.version; |
| 69 | 50 | |
| 70 | pub 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 | ||
| 92 | pub 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 | ||
| 285 | pub const HashStyle = enum { sysv, gnu, both }; | |
| 286 | ||
| 287 | pub const CompressDebugSections = enum { none, zlib, zstd }; | |
| 288 | ||
| 289 | /// The filesystem layout of darwin SDK elements. | |
| 290 | pub 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 | ||
| 297 | 51 | pub const File = struct { |
| 298 | 52 | tag: Tag, |
| 299 | options: Options, | |
| 53 | ||
| 54 | /// The owner of this output File. | |
| 55 | comp: *Compilation, | |
| 56 | emit: Compilation.Emit, | |
| 57 | ||
| 300 | 58 | file: ?fs.File, |
| 301 | allocator: Allocator, | |
| 302 | 59 | /// When linking with LLD, this linker code will output an object file only at |
| 303 | 60 | /// 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, | |
| 305 | 69 | |
| 306 | 70 | /// Prevents other processes from clobbering files in the output directory |
| 307 | 71 | /// of this linking operation. |
| 308 | 72 | lock: ?Cache.Lock = null, |
| 309 | ||
| 310 | 73 | child_pid: ?std.ChildProcess.Id = null, |
| 311 | 74 | |
| 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 | ||
| 312 | 172 | /// Attempts incremental linking, if the file already exists. If |
| 313 | 173 | /// incremental linking fails, falls back to truncating the file and |
| 314 | 174 | /// rewriting it. A malicious file is detected as incremental link failure |
| 315 | 175 | /// 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 | }, | |
| 336 | 194 | } |
| 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 | } | |
| 400 | 196 | |
| 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 | }, | |
| 406 | 214 | } |
| 407 | ||
| 408 | return file; | |
| 409 | 215 | } |
| 410 | 216 | |
| 411 | 217 | pub fn cast(base: *File, comptime T: type) ?*T { |
| ... | ... | @@ -416,11 +222,13 @@ pub const File = struct { |
| 416 | 222 | } |
| 417 | 223 | |
| 418 | 224 | pub fn makeWritable(base: *File) !void { |
| 225 | const comp = base.comp; | |
| 226 | const gpa = comp.gpa; | |
| 419 | 227 | switch (base.tag) { |
| 420 | 228 | .coff, .elf, .macho, .plan9, .wasm => { |
| 421 | 229 | if (build_options.only_c) unreachable; |
| 422 | 230 | if (base.file != null) return; |
| 423 | const emit = base.options.emit orelse return; | |
| 231 | const emit = base.emit; | |
| 424 | 232 | if (base.child_pid) |pid| { |
| 425 | 233 | if (builtin.os.tag == .windows) { |
| 426 | 234 | base.cast(Coff).?.ptraceAttach(pid) catch |err| { |
| ... | ... | @@ -431,9 +239,10 @@ pub const File = struct { |
| 431 | 239 | // it will return ETXTBSY. So instead, we copy the file, atomically rename it |
| 432 | 240 | // over top of the exe path, and then proceed normally. This changes the inode, |
| 433 | 241 | // 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}", .{ | |
| 435 | 243 | emit.sub_path, std.crypto.random.int(u32), |
| 436 | 244 | }); |
| 245 | defer gpa.free(tmp_sub_path); | |
| 437 | 246 | try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{}); |
| 438 | 247 | try emit.directory.handle.rename(tmp_sub_path, emit.sub_path); |
| 439 | 248 | switch (builtin.os.tag) { |
| ... | ... | @@ -448,10 +257,13 @@ pub const File = struct { |
| 448 | 257 | } |
| 449 | 258 | } |
| 450 | 259 | } |
| 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; | |
| 451 | 263 | base.file = try emit.directory.handle.createFile(emit.sub_path, .{ |
| 452 | 264 | .truncate = false, |
| 453 | 265 | .read = true, |
| 454 | .mode = determineMode(base.options), | |
| 266 | .mode = determineMode(use_lld, output_mode, link_mode), | |
| 455 | 267 | }); |
| 456 | 268 | }, |
| 457 | 269 | .c, .spirv, .nvptx => {}, |
| ... | ... | @@ -459,9 +271,14 @@ pub const File = struct { |
| 459 | 271 | } |
| 460 | 272 | |
| 461 | 273 | 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) { | |
| 463 | 280 | .Obj => return, |
| 464 | .Lib => switch (base.options.link_mode) { | |
| 281 | .Lib => switch (link_mode) { | |
| 465 | 282 | .Static => return, |
| 466 | 283 | .Dynamic => {}, |
| 467 | 284 | }, |
| ... | ... | @@ -470,8 +287,7 @@ pub const File = struct { |
| 470 | 287 | switch (base.tag) { |
| 471 | 288 | .elf => if (base.file) |f| { |
| 472 | 289 | 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) { | |
| 475 | 291 | // The file we have open is not the final file that we want to |
| 476 | 292 | // make executable, so we don't have to close it. |
| 477 | 293 | return; |
| ... | ... | @@ -490,7 +306,7 @@ pub const File = struct { |
| 490 | 306 | }, |
| 491 | 307 | .coff, .macho, .plan9, .wasm => if (base.file) |f| { |
| 492 | 308 | if (build_options.only_c) unreachable; |
| 493 | if (base.intermediary_basename != null) { | |
| 309 | if (base.zcu_object_sub_path != null) { | |
| 494 | 310 | // The file we have open is not the final file that we want to |
| 495 | 311 | // make executable, so we don't have to close it. |
| 496 | 312 | return; |
| ... | ... | @@ -555,16 +371,12 @@ pub const File = struct { |
| 555 | 371 | pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { |
| 556 | 372 | if (build_options.only_c) @compileError("unreachable"); |
| 557 | 373 | 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), | |
| 563 | 374 | .spirv => unreachable, |
| 564 | .c => unreachable, | |
| 565 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 375 | .c => unreachable, | |
| 566 | 376 | .nvptx => unreachable, |
| 567 | // zig fmt: on | |
| 377 | inline else => |t| { | |
| 378 | return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(tv, decl_index); | |
| 379 | }, | |
| 568 | 380 | } |
| 569 | 381 | } |
| 570 | 382 | |
| ... | ... | @@ -577,16 +389,13 @@ pub const File = struct { |
| 577 | 389 | if (build_options.only_c) @compileError("unreachable"); |
| 578 | 390 | log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); |
| 579 | 391 | 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), | |
| 584 | 392 | .plan9 => unreachable, |
| 585 | 393 | .spirv => unreachable, |
| 586 | .c => unreachable, | |
| 587 | .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name, lib_name), | |
| 394 | .c => unreachable, | |
| 588 | 395 | .nvptx => unreachable, |
| 589 | // zig fmt: on | |
| 396 | inline else => |t| { | |
| 397 | return @fieldParentPtr(t.Type(), "base", base).getGlobalSymbol(name, lib_name); | |
| 398 | }, | |
| 590 | 399 | } |
| 591 | 400 | } |
| 592 | 401 | |
| ... | ... | @@ -594,59 +403,48 @@ pub const File = struct { |
| 594 | 403 | pub fn updateDecl(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 595 | 404 | const decl = module.declPtr(decl_index); |
| 596 | 405 | 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 | } | |
| 601 | 406 | 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 | }, | |
| 612 | 414 | } |
| 613 | 415 | } |
| 614 | 416 | |
| 615 | 417 | /// 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 { | |
| 621 | 425 | 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 | }, | |
| 632 | 433 | } |
| 633 | 434 | } |
| 634 | 435 | |
| 635 | 436 | pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 636 | 437 | const decl = module.declPtr(decl_index); |
| 637 | 438 | 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 | } | |
| 642 | 439 | 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), | |
| 649 | 440 | .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 | }, | |
| 650 | 448 | } |
| 651 | 449 | } |
| 652 | 450 | |
| ... | ... | @@ -666,56 +464,12 @@ pub const File = struct { |
| 666 | 464 | pub fn destroy(base: *File) void { |
| 667 | 465 | base.releaseLock(); |
| 668 | 466 | 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); | |
| 672 | 467 | 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| { | |
| 715 | 471 | 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(); | |
| 719 | 473 | }, |
| 720 | 474 | } |
| 721 | 475 | } |
| ... | ... | @@ -793,19 +547,22 @@ pub const File = struct { |
| 793 | 547 | |
| 794 | 548 | /// Commit pending changes and write headers. Takes into account final output mode |
| 795 | 549 | /// 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 { | |
| 797 | 552 | if (build_options.only_c) { |
| 798 | 553 | assert(base.tag == .c); |
| 799 | return @fieldParentPtr(C, "base", base).flush(comp, prog_node); | |
| 554 | return @fieldParentPtr(C, "base", base).flush(arena, prog_node); | |
| 800 | 555 | } |
| 556 | const comp = base.comp; | |
| 801 | 557 | 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; | |
| 803 | 560 | // TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case) |
| 804 | 561 | // Until then, we do `lld -r -o output.o input.o` even though the output is the same |
| 805 | 562 | // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file |
| 806 | 563 | // 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); | |
| 809 | 566 | assert(comp.c_object_table.count() == 1); |
| 810 | 567 | const the_key = comp.c_object_table.keys()[0]; |
| 811 | 568 | const cached_pp_file_path = the_key.status.success.object_path; |
| ... | ... | @@ -813,75 +570,43 @@ pub const File = struct { |
| 813 | 570 | return; |
| 814 | 571 | } |
| 815 | 572 | |
| 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); | |
| 819 | 578 | } |
| 820 | 579 | 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 | }, | |
| 829 | 583 | } |
| 830 | 584 | } |
| 831 | 585 | |
| 832 | 586 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 833 | 587 | /// 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 { | |
| 839 | 589 | 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 | }, | |
| 848 | 597 | } |
| 849 | 598 | } |
| 850 | 599 | |
| 851 | 600 | /// Called when a Decl is deleted from the Module. |
| 852 | 601 | 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 { | |
| 881 | 602 | 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 | }, | |
| 885 | 610 | } |
| 886 | 611 | } |
| 887 | 612 | |
| ... | ... | @@ -900,19 +625,14 @@ pub const File = struct { |
| 900 | 625 | exported: Module.Exported, |
| 901 | 626 | exports: []const *Module.Export, |
| 902 | 627 | ) UpdateExportsError!void { |
| 903 | if (build_options.only_c) { | |
| 904 | assert(base.tag == .c); | |
| 905 | return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports); | |
| 906 | } | |
| 907 | 628 | 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 | }, | |
| 916 | 636 | } |
| 917 | 637 | } |
| 918 | 638 | |
| ... | ... | @@ -929,150 +649,91 @@ pub const File = struct { |
| 929 | 649 | /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate |
| 930 | 650 | /// the block/atom. |
| 931 | 651 | 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"); | |
| 933 | 653 | 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), | |
| 938 | 654 | .c => unreachable, |
| 939 | .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 940 | 655 | .spirv => unreachable, |
| 941 | 656 | .nvptx => unreachable, |
| 657 | inline else => |tag| { | |
| 658 | return @fieldParentPtr(tag.Type(), "base", base).getDeclVAddr(decl_index, reloc_info); | |
| 659 | }, | |
| 942 | 660 | } |
| 943 | 661 | } |
| 944 | 662 | |
| 945 | 663 | pub const LowerResult = @import("codegen.zig").Result; |
| 946 | 664 | |
| 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"); | |
| 949 | 672 | 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), | |
| 954 | 673 | .c => unreachable, |
| 955 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 956 | 674 | .spirv => unreachable, |
| 957 | 675 | .nvptx => unreachable, |
| 676 | inline else => |tag| { | |
| 677 | return @fieldParentPtr(tag.Type(), "base", base).lowerAnonDecl(decl_val, decl_align, src_loc); | |
| 678 | }, | |
| 958 | 679 | } |
| 959 | 680 | } |
| 960 | 681 | |
| 961 | 682 | 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"); | |
| 963 | 684 | 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), | |
| 968 | 685 | .c => unreachable, |
| 969 | .wasm => return @fieldParentPtr(Wasm, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 970 | 686 | .spirv => unreachable, |
| 971 | 687 | .nvptx => unreachable, |
| 688 | inline else => |tag| { | |
| 689 | return @fieldParentPtr(tag.Type(), "base", base).getAnonDeclVAddr(decl_val, reloc_info); | |
| 690 | }, | |
| 972 | 691 | } |
| 973 | 692 | } |
| 974 | 693 | |
| 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( | |
| 1000 | 695 | 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, | |
| 1004 | 698 | ) !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 | }, | |
| 1047 | 710 | } |
| 1048 | 711 | } |
| 1049 | 712 | |
| 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 { | |
| 1053 | 714 | const tracy = trace(@src()); |
| 1054 | 715 | defer tracy.end(); |
| 1055 | 716 | |
| 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; | |
| 1059 | 719 | |
| 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}); | |
| 1062 | 722 | const full_out_path_z = try arena.dupeZ(u8, full_out_path); |
| 723 | const opt_zcu = comp.module; | |
| 1063 | 724 | |
| 1064 | 725 | // If there is no Zig code to compile, then we should skip flushing the output file |
| 1065 | 726 | // 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); | |
| 1068 | 729 | |
| 1069 | 730 | 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.? }); | |
| 1071 | 732 | } else null; |
| 1072 | 733 | |
| 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)"}); | |
| 1074 | 735 | |
| 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) | |
| 1076 | 737 | comp.compiler_rt_obj.?.full_object_path |
| 1077 | 738 | else |
| 1078 | 739 | null; |
| ... | ... | @@ -1084,17 +745,19 @@ pub const File = struct { |
| 1084 | 745 | const id_symlink_basename = "llvm-ar.id"; |
| 1085 | 746 | |
| 1086 | 747 | 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; | |
| 1088 | 751 | |
| 1089 | 752 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 1090 | 753 | |
| 1091 | if (!base.options.disable_lld_caching) { | |
| 754 | if (!base.disable_lld_caching) { | |
| 1092 | 755 | man = comp.cache_parent.obtain(); |
| 1093 | 756 | |
| 1094 | 757 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 1095 | 758 | base.releaseLock(); |
| 1096 | 759 | |
| 1097 | for (base.options.objects) |obj| { | |
| 760 | for (objects) |obj| { | |
| 1098 | 761 | _ = try man.addFile(obj.path, null); |
| 1099 | 762 | man.hash.add(obj.must_link); |
| 1100 | 763 | man.hash.add(obj.loption); |
| ... | ... | @@ -1107,7 +770,7 @@ pub const File = struct { |
| 1107 | 770 | _ = try man.addFile(key.status.success.res_path, null); |
| 1108 | 771 | } |
| 1109 | 772 | } |
| 1110 | try man.addOptionalFile(module_obj_path); | |
| 773 | try man.addOptionalFile(zcu_obj_path); | |
| 1111 | 774 | try man.addOptionalFile(compiler_rt_path); |
| 1112 | 775 | |
| 1113 | 776 | // 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 { |
| 1137 | 800 | } |
| 1138 | 801 | |
| 1139 | 802 | 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); | |
| 1142 | 805 | defer object_files.deinit(); |
| 1143 | 806 | |
| 1144 | for (base.options.objects) |obj| { | |
| 807 | for (objects) |obj| { | |
| 1145 | 808 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path)); |
| 1146 | 809 | } |
| 1147 | 810 | for (comp.c_object_table.keys()) |key| { |
| ... | ... | @@ -1152,14 +815,14 @@ pub const File = struct { |
| 1152 | 815 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path)); |
| 1153 | 816 | } |
| 1154 | 817 | } |
| 1155 | if (module_obj_path) |p| { | |
| 818 | if (zcu_obj_path) |p| { | |
| 1156 | 819 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, p)); |
| 1157 | 820 | } |
| 1158 | 821 | if (compiler_rt_path) |p| { |
| 1159 | 822 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, p)); |
| 1160 | 823 | } |
| 1161 | 824 | |
| 1162 | if (base.options.verbose_link) { | |
| 825 | if (comp.verbose_link) { | |
| 1163 | 826 | std.debug.print("ar rcs {s}", .{full_out_path_z}); |
| 1164 | 827 | for (object_files.items) |arg| { |
| 1165 | 828 | std.debug.print(" {s}", .{arg}); |
| ... | ... | @@ -1170,12 +833,13 @@ pub const File = struct { |
| 1170 | 833 | const llvm_bindings = @import("codegen/llvm/bindings.zig"); |
| 1171 | 834 | const Builder = @import("codegen/llvm/Builder.zig"); |
| 1172 | 835 | 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); | |
| 1175 | 839 | const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag); |
| 1176 | 840 | if (bad) return error.UnableToWriteArchive; |
| 1177 | 841 | |
| 1178 | if (!base.options.disable_lld_caching) { | |
| 842 | if (!base.disable_lld_caching) { | |
| 1179 | 843 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| 1180 | 844 | log.warn("failed to save archive hash digest file: {s}", .{@errorName(err)}); |
| 1181 | 845 | }; |
| ... | ... | @@ -1199,6 +863,35 @@ pub const File = struct { |
| 1199 | 863 | spirv, |
| 1200 | 864 | plan9, |
| 1201 | 865 | 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 | } | |
| 1202 | 895 | }; |
| 1203 | 896 | |
| 1204 | 897 | pub const ErrorFlags = struct { |
| ... | ... | @@ -1237,6 +930,73 @@ pub const File = struct { |
| 1237 | 930 | } |
| 1238 | 931 | }; |
| 1239 | 932 | |
| 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 | ||
| 1240 | 1000 | pub const C = @import("link/C.zig"); |
| 1241 | 1001 | pub const Coff = @import("link/Coff.zig"); |
| 1242 | 1002 | pub const Plan9 = @import("link/Plan9.zig"); |
| ... | ... | @@ -1247,19 +1007,3 @@ pub const File = struct { |
| 1247 | 1007 | pub const NvPtx = @import("link/NvPtx.zig"); |
| 1248 | 1008 | pub const Dwarf = @import("link/Dwarf.zig"); |
| 1249 | 1009 | }; |
| 1250 | ||
| 1251 | pub 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; |
| 5 | 5 | const fs = std.fs; |
| 6 | 6 | |
| 7 | 7 | const C = @This(); |
| 8 | const build_options = @import("build_options"); | |
| 8 | 9 | const Module = @import("../Module.zig"); |
| 9 | 10 | const InternPool = @import("../InternPool.zig"); |
| 10 | 11 | const Alignment = InternPool.Alignment; |
| ... | ... | @@ -83,7 +84,8 @@ pub fn getString(this: C, s: String) []const u8 { |
| 83 | 84 | } |
| 84 | 85 | |
| 85 | 86 | pub 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; | |
| 87 | 89 | try this.string_bytes.appendSlice(gpa, s); |
| 88 | 90 | return .{ |
| 89 | 91 | .start = @intCast(this.string_bytes.items.len - s.len), |
| ... | ... | @@ -91,28 +93,55 @@ pub fn addString(this: *C, s: []const u8) Allocator.Error!String { |
| 91 | 93 | }; |
| 92 | 94 | } |
| 93 | 95 | |
| 94 | pub 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; | |
| 96 | pub 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 | } | |
| 99 | 104 | |
| 100 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ | |
| 105 | pub 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, .{ | |
| 101 | 124 | // Truncation is done on `flush`. |
| 102 | 125 | .truncate = false, |
| 103 | .mode = link.determineMode(options), | |
| 126 | .mode = link.File.determineMode(use_lld, output_mode, link_mode), | |
| 104 | 127 | }); |
| 105 | 128 | errdefer file.close(); |
| 106 | 129 | |
| 107 | const c_file = try gpa.create(C); | |
| 108 | errdefer gpa.destroy(c_file); | |
| 130 | const c_file = try arena.create(C); | |
| 109 | 131 | |
| 110 | 132 | c_file.* = .{ |
| 111 | 133 | .base = .{ |
| 112 | 134 | .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, | |
| 114 | 141 | .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, | |
| 116 | 145 | }, |
| 117 | 146 | }; |
| 118 | 147 | |
| ... | ... | @@ -120,7 +149,7 @@ pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C |
| 120 | 149 | } |
| 121 | 150 | |
| 122 | 151 | pub fn deinit(self: *C) void { |
| 123 | const gpa = self.base.allocator; | |
| 152 | const gpa = self.base.comp.gpa; | |
| 124 | 153 | |
| 125 | 154 | for (self.decl_table.values()) |*db| { |
| 126 | 155 | db.deinit(gpa); |
| ... | ... | @@ -141,7 +170,7 @@ pub fn deinit(self: *C) void { |
| 141 | 170 | } |
| 142 | 171 | |
| 143 | 172 | pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void { |
| 144 | const gpa = self.base.allocator; | |
| 173 | const gpa = self.base.comp.gpa; | |
| 145 | 174 | if (self.decl_table.fetchSwapRemove(decl_index)) |kv| { |
| 146 | 175 | var decl_block = kv.value; |
| 147 | 176 | decl_block.deinit(gpa); |
| ... | ... | @@ -155,7 +184,7 @@ pub fn updateFunc( |
| 155 | 184 | air: Air, |
| 156 | 185 | liveness: Liveness, |
| 157 | 186 | ) !void { |
| 158 | const gpa = self.base.allocator; | |
| 187 | const gpa = self.base.comp.gpa; | |
| 159 | 188 | |
| 160 | 189 | const func = module.funcInfo(func_index); |
| 161 | 190 | const decl_index = func.owner_decl; |
| ... | ... | @@ -223,7 +252,7 @@ pub fn updateFunc( |
| 223 | 252 | } |
| 224 | 253 | |
| 225 | 254 | fn updateAnonDecl(self: *C, module: *Module, i: usize) !void { |
| 226 | const gpa = self.base.allocator; | |
| 255 | const gpa = self.base.comp.gpa; | |
| 227 | 256 | const anon_decl = self.anon_decls.keys()[i]; |
| 228 | 257 | |
| 229 | 258 | const fwd_decl = &self.fwd_decl_buf; |
| ... | ... | @@ -285,7 +314,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) ! |
| 285 | 314 | const tracy = trace(@src()); |
| 286 | 315 | defer tracy.end(); |
| 287 | 316 | |
| 288 | const gpa = self.base.allocator; | |
| 317 | const gpa = self.base.comp.gpa; | |
| 289 | 318 | |
| 290 | 319 | const gop = try self.decl_table.getOrPut(gpa, decl_index); |
| 291 | 320 | if (!gop.found_existing) { |
| ... | ... | @@ -347,12 +376,13 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: InternPool.De |
| 347 | 376 | _ = decl_index; |
| 348 | 377 | } |
| 349 | 378 | |
| 350 | pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 351 | return self.flushModule(comp, prog_node); | |
| 379 | pub fn flush(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void { | |
| 380 | return self.flushModule(arena, prog_node); | |
| 352 | 381 | } |
| 353 | 382 | |
| 354 | 383 | fn 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); | |
| 356 | 386 | errdefer defines.deinit(); |
| 357 | 387 | const writer = defines.writer(); |
| 358 | 388 | switch (target.abi) { |
| ... | ... | @@ -363,7 +393,9 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { |
| 363 | 393 | return defines; |
| 364 | 394 | } |
| 365 | 395 | |
| 366 | pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 396 | pub 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 | ||
| 367 | 399 | const tracy = trace(@src()); |
| 368 | 400 | defer tracy.end(); |
| 369 | 401 | |
| ... | ... | @@ -371,8 +403,9 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo |
| 371 | 403 | sub_prog_node.activate(); |
| 372 | 404 | defer sub_prog_node.end(); |
| 373 | 405 | |
| 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.?; | |
| 376 | 409 | |
| 377 | 410 | { |
| 378 | 411 | var i: usize = 0; |
| ... | ... | @@ -520,8 +553,8 @@ fn flushCTypes( |
| 520 | 553 | pass: codegen.DeclGen.Pass, |
| 521 | 554 | decl_ctypes: codegen.CType.Store, |
| 522 | 555 | ) 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.?; | |
| 525 | 558 | |
| 526 | 559 | const decl_ctypes_len = decl_ctypes.count(); |
| 527 | 560 | f.ctypes_map.clearRetainingCapacity(); |
| ... | ... | @@ -601,7 +634,7 @@ fn flushCTypes( |
| 601 | 634 | } |
| 602 | 635 | |
| 603 | 636 | fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void { |
| 604 | const gpa = self.base.allocator; | |
| 637 | const gpa = self.base.comp.gpa; | |
| 605 | 638 | |
| 606 | 639 | const fwd_decl = &self.lazy_fwd_decl_buf; |
| 607 | 640 | const code = &self.lazy_code_buf; |
| ... | ... | @@ -609,7 +642,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void { |
| 609 | 642 | var object = codegen.Object{ |
| 610 | 643 | .dg = .{ |
| 611 | 644 | .gpa = gpa, |
| 612 | .module = self.base.options.module.?, | |
| 645 | .module = self.base.comp.module.?, | |
| 613 | 646 | .error_msg = null, |
| 614 | 647 | .pass = .flush, |
| 615 | 648 | .is_naked_fn = false, |
| ... | ... | @@ -643,7 +676,7 @@ fn flushLazyFn( |
| 643 | 676 | ctypes: *codegen.CType.Store, |
| 644 | 677 | lazy_fn: codegen.LazyFnMap.Entry, |
| 645 | 678 | ) FlushDeclError!void { |
| 646 | const gpa = self.base.allocator; | |
| 679 | const gpa = self.base.comp.gpa; | |
| 647 | 680 | |
| 648 | 681 | const fwd_decl = &self.lazy_fwd_decl_buf; |
| 649 | 682 | const code = &self.lazy_code_buf; |
| ... | ... | @@ -651,7 +684,7 @@ fn flushLazyFn( |
| 651 | 684 | var object = codegen.Object{ |
| 652 | 685 | .dg = .{ |
| 653 | 686 | .gpa = gpa, |
| 654 | .module = self.base.options.module.?, | |
| 687 | .module = self.base.comp.module.?, | |
| 655 | 688 | .error_msg = null, |
| 656 | 689 | .pass = .flush, |
| 657 | 690 | .is_naked_fn = false, |
| ... | ... | @@ -683,7 +716,7 @@ fn flushLazyFn( |
| 683 | 716 | } |
| 684 | 717 | |
| 685 | 718 | fn flushLazyFns(self: *C, f: *Flush, lazy_fns: codegen.LazyFnMap) FlushDeclError!void { |
| 686 | const gpa = self.base.allocator; | |
| 719 | const gpa = self.base.comp.gpa; | |
| 687 | 720 | try f.lazy_fns.ensureUnusedCapacity(gpa, @intCast(lazy_fns.count())); |
| 688 | 721 | |
| 689 | 722 | var it = lazy_fns.iterator(); |
| ... | ... | @@ -702,7 +735,7 @@ fn flushDeclBlock( |
| 702 | 735 | export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void), |
| 703 | 736 | extern_symbol_name: InternPool.OptionalNullTerminatedString, |
| 704 | 737 | ) FlushDeclError!void { |
| 705 | const gpa = self.base.allocator; | |
| 738 | const gpa = self.base.comp.gpa; | |
| 706 | 739 | try self.flushLazyFns(f, decl_block.lazy_fns); |
| 707 | 740 | try f.all_buffers.ensureUnusedCapacity(gpa, 1); |
| 708 | 741 | fwd_decl: { |
src/link/Coff.zig+289-207| ... | ... | @@ -3,11 +3,24 @@ |
| 3 | 3 | //! LLD for traditional linking (linking relocatable object files). |
| 4 | 4 | //! LLD is also the default linker for LLVM. |
| 5 | 5 | |
| 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. | |
| 7 | 7 | llvm_object: ?*LlvmObject = null, |
| 8 | 8 | |
| 9 | 9 | base: link.File, |
| 10 | error_flags: link.File.ErrorFlags = .{}, | |
| 10 | image_base: u64, | |
| 11 | subsystem: ?std.Target.SubSystem, | |
| 12 | tsaware: bool, | |
| 13 | nxcompat: bool, | |
| 14 | dynamicbase: 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. | |
| 17 | major_subsystem_version: u16, | |
| 18 | minor_subsystem_version: u16, | |
| 19 | lib_dirs: []const []const u8, | |
| 20 | entry: link.File.OpenOptions.Entry, | |
| 21 | entry_addr: ?u32, | |
| 22 | module_definition_file: ?[]const u8, | |
| 23 | pdb_out_path: ?[]const u8, | |
| 11 | 24 | |
| 12 | 25 | ptr_width: PtrWidth, |
| 13 | 26 | page_size: u32, |
| ... | ... | @@ -48,9 +61,6 @@ got_table_count_dirty: bool = true, |
| 48 | 61 | got_table_contents_dirty: bool = true, |
| 49 | 62 | imports_count_dirty: bool = true, |
| 50 | 63 | |
| 51 | /// Virtual address of the entry point procedure relative to image base. | |
| 52 | entry_addr: ?u32 = null, | |
| 53 | ||
| 54 | 64 | /// Table of tracked LazySymbols. |
| 55 | 65 | lazy_syms: LazySymbolTable = .{}, |
| 56 | 66 | |
| ... | ... | @@ -226,132 +236,112 @@ const ideal_factor = 3; |
| 226 | 236 | const minimum_text_block_size = 64; |
| 227 | 237 | pub const min_text_capacity = padToIdeal(minimum_text_block_size); |
| 228 | 238 | |
| 229 | pub 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 | ||
| 251 | pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff { | |
| 252 | const ptr_width: PtrWidth = switch (options.target.ptrBitWidth()) { | |
| 239 | pub 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()) { | |
| 253 | 254 | 0...32 => .p32, |
| 254 | 255 | 33...64 => .p64, |
| 255 | 256 | else => return error.UnsupportedCOFFArchitecture, |
| 256 | 257 | }; |
| 257 | const page_size: u32 = switch (options.target.cpu.arch) { | |
| 258 | const page_size: u32 = switch (target.cpu.arch) { | |
| 258 | 259 | else => 0x1000, |
| 259 | 260 | }; |
| 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); | |
| 262 | 273 | self.* = .{ |
| 263 | 274 | .base = .{ |
| 264 | 275 | .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, | |
| 267 | 283 | .file = null, |
| 284 | .disable_lld_caching = options.disable_lld_caching, | |
| 285 | .build_id = options.build_id, | |
| 286 | .rpath_list = options.rpath_list, | |
| 268 | 287 | }, |
| 269 | 288 | .ptr_width = ptr_width, |
| 270 | 289 | .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 | ||
| 280 | pub fn deinit(self: *Coff) void { | |
| 281 | const gpa = self.base.allocator; | |
| 282 | 290 | |
| 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, | |
| 284 | 295 | |
| 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 | }, | |
| 332 | 305 | |
| 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); | |
| 339 | 325 | } |
| 326 | errdefer self.base.destroy(); | |
| 340 | 327 | |
| 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; | |
| 343 | 331 | } |
| 344 | self.relocs.deinit(gpa); | |
| 345 | 332 | |
| 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 | }); | |
| 351 | 342 | |
| 352 | fn populateMissingMetadata(self: *Coff) !void { | |
| 353 | 343 | assert(self.llvm_object == null); |
| 354 | const gpa = self.base.allocator; | |
| 344 | const gpa = comp.gpa; | |
| 355 | 345 | |
| 356 | 346 | try self.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32)); |
| 357 | 347 | self.strtab.buffer.appendNTimesAssumeCapacity(0, @sizeOf(u32)); |
| ... | ... | @@ -369,7 +359,7 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 369 | 359 | }); |
| 370 | 360 | |
| 371 | 361 | 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); | |
| 373 | 363 | self.text_section_index = try self.allocateSection(".text", file_size, .{ |
| 374 | 364 | .CNT_CODE = 1, |
| 375 | 365 | .MEM_EXECUTE = 1, |
| ... | ... | @@ -378,7 +368,7 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 378 | 368 | } |
| 379 | 369 | |
| 380 | 370 | 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(); | |
| 382 | 372 | self.got_section_index = try self.allocateSection(".got", file_size, .{ |
| 383 | 373 | .CNT_INITIALIZED_DATA = 1, |
| 384 | 374 | .MEM_READ = 1, |
| ... | ... | @@ -403,7 +393,7 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 403 | 393 | } |
| 404 | 394 | |
| 405 | 395 | 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(); | |
| 407 | 397 | self.idata_section_index = try self.allocateSection(".idata", file_size, .{ |
| 408 | 398 | .CNT_INITIALIZED_DATA = 1, |
| 409 | 399 | .MEM_READ = 1, |
| ... | ... | @@ -411,7 +401,7 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 411 | 401 | } |
| 412 | 402 | |
| 413 | 403 | 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); | |
| 415 | 405 | self.reloc_section_index = try self.allocateSection(".reloc", file_size, .{ |
| 416 | 406 | .CNT_INITIALIZED_DATA = 1, |
| 417 | 407 | .MEM_DISCARDABLE = 1, |
| ... | ... | @@ -438,6 +428,91 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 438 | 428 | } |
| 439 | 429 | try self.base.file.?.pwriteAll(&[_]u8{0}, max_file_offset); |
| 440 | 430 | } |
| 431 | ||
| 432 | return self; | |
| 433 | } | |
| 434 | ||
| 435 | pub 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 | ||
| 446 | pub 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); | |
| 441 | 516 | } |
| 442 | 517 | |
| 443 | 518 | fn 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 |
| 471 | 546 | .number_of_linenumbers = 0, |
| 472 | 547 | .flags = flags, |
| 473 | 548 | }; |
| 549 | const gpa = self.base.comp.gpa; | |
| 474 | 550 | try self.setSectionName(&header, name); |
| 475 | try self.sections.append(self.base.allocator, .{ .header = header }); | |
| 551 | try self.sections.append(gpa, .{ .header = header }); | |
| 476 | 552 | return index; |
| 477 | 553 | } |
| 478 | 554 | |
| ... | ... | @@ -654,7 +730,7 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme |
| 654 | 730 | } |
| 655 | 731 | |
| 656 | 732 | pub fn allocateSymbol(self: *Coff) !u32 { |
| 657 | const gpa = self.base.allocator; | |
| 733 | const gpa = self.base.comp.gpa; | |
| 658 | 734 | try self.locals.ensureUnusedCapacity(gpa, 1); |
| 659 | 735 | |
| 660 | 736 | const index = blk: { |
| ... | ... | @@ -682,7 +758,7 @@ pub fn allocateSymbol(self: *Coff) !u32 { |
| 682 | 758 | } |
| 683 | 759 | |
| 684 | 760 | fn allocateGlobal(self: *Coff) !u32 { |
| 685 | const gpa = self.base.allocator; | |
| 761 | const gpa = self.base.comp.gpa; | |
| 686 | 762 | try self.globals.ensureUnusedCapacity(gpa, 1); |
| 687 | 763 | |
| 688 | 764 | const index = blk: { |
| ... | ... | @@ -706,15 +782,16 @@ fn allocateGlobal(self: *Coff) !u32 { |
| 706 | 782 | } |
| 707 | 783 | |
| 708 | 784 | fn addGotEntry(self: *Coff, target: SymbolWithLoc) !void { |
| 785 | const gpa = self.base.comp.gpa; | |
| 709 | 786 | 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); | |
| 711 | 788 | try self.writeOffsetTableEntry(got_index); |
| 712 | 789 | self.got_table_count_dirty = true; |
| 713 | 790 | self.markRelocsDirtyByTarget(target); |
| 714 | 791 | } |
| 715 | 792 | |
| 716 | 793 | pub fn createAtom(self: *Coff) !Atom.Index { |
| 717 | const gpa = self.base.allocator; | |
| 794 | const gpa = self.base.comp.gpa; | |
| 718 | 795 | const atom_index = @as(Atom.Index, @intCast(self.atoms.items.len)); |
| 719 | 796 | const atom = try self.atoms.addOne(gpa); |
| 720 | 797 | const sym_index = try self.allocateSymbol(); |
| ... | ... | @@ -759,7 +836,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { |
| 759 | 836 | file_offset + code.len, |
| 760 | 837 | }); |
| 761 | 838 | |
| 762 | const gpa = self.base.allocator; | |
| 839 | const gpa = self.base.comp.gpa; | |
| 763 | 840 | |
| 764 | 841 | // Gather relocs which can be resolved. |
| 765 | 842 | // 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 { |
| 807 | 884 | } |
| 808 | 885 | } |
| 809 | 886 | |
| 810 | self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase()); | |
| 887 | self.resolveRelocs(atom_index, relocs.items, code, self.image_base); | |
| 811 | 888 | try self.base.file.?.pwriteAll(code, file_offset); |
| 812 | 889 | |
| 813 | 890 | // Now we can mark the relocs as resolved. |
| ... | ... | @@ -853,24 +930,24 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 853 | 930 | const file_offset = header.pointer_to_raw_data + entry_offset; |
| 854 | 931 | const vmaddr = header.virtual_address + entry_offset; |
| 855 | 932 | |
| 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 }); | |
| 857 | 934 | |
| 858 | 935 | switch (self.ptr_width) { |
| 859 | 936 | .p32 => { |
| 860 | 937 | 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); | |
| 862 | 939 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 863 | 940 | }, |
| 864 | 941 | .p64 => { |
| 865 | 942 | 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); | |
| 867 | 944 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 868 | 945 | }, |
| 869 | 946 | } |
| 870 | 947 | |
| 871 | 948 | if (is_hot_update_compatible) { |
| 872 | 949 | if (self.base.child_pid) |handle| { |
| 873 | const gpa = self.base.allocator; | |
| 950 | const gpa = self.base.comp.gpa; | |
| 874 | 951 | const slide = @intFromPtr(self.hot_state.loaded_base_address.?); |
| 875 | 952 | const actual_vmaddr = vmaddr + slide; |
| 876 | 953 | const pvaddr = @as(*anyopaque, @ptrFromInt(actual_vmaddr)); |
| ... | ... | @@ -974,7 +1051,7 @@ pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void { |
| 974 | 1051 | fn freeAtom(self: *Coff, atom_index: Atom.Index) void { |
| 975 | 1052 | log.debug("freeAtom {d}", .{atom_index}); |
| 976 | 1053 | |
| 977 | const gpa = self.base.allocator; | |
| 1054 | const gpa = self.base.comp.gpa; | |
| 978 | 1055 | |
| 979 | 1056 | // Remove any relocs and base relocs associated with this Atom |
| 980 | 1057 | Atom.freeRelocations(self, atom_index); |
| ... | ... | @@ -1061,7 +1138,8 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: |
| 1061 | 1138 | self.freeUnnamedConsts(decl_index); |
| 1062 | 1139 | Atom.freeRelocations(self, atom_index); |
| 1063 | 1140 | |
| 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); | |
| 1065 | 1143 | defer code_buffer.deinit(); |
| 1066 | 1144 | |
| 1067 | 1145 | const res = try codegen.generateFunction( |
| ... | ... | @@ -1090,8 +1168,8 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air: |
| 1090 | 1168 | } |
| 1091 | 1169 | |
| 1092 | 1170 | pub 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.?; | |
| 1095 | 1173 | const decl = mod.declPtr(decl_index); |
| 1096 | 1174 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); |
| 1097 | 1175 | if (!gop.found_existing) { |
| ... | ... | @@ -1121,7 +1199,7 @@ const LowerConstResult = union(enum) { |
| 1121 | 1199 | }; |
| 1122 | 1200 | |
| 1123 | 1201 | fn 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; | |
| 1125 | 1203 | |
| 1126 | 1204 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1127 | 1205 | defer code_buffer.deinit(); |
| ... | ... | @@ -1174,13 +1252,14 @@ pub fn updateDecl( |
| 1174 | 1252 | return; |
| 1175 | 1253 | } |
| 1176 | 1254 | |
| 1255 | const gpa = self.base.comp.gpa; | |
| 1177 | 1256 | if (decl.isExtern(mod)) { |
| 1178 | 1257 | // TODO make this part of getGlobalSymbol |
| 1179 | 1258 | const variable = decl.getOwnedVariable(mod).?; |
| 1180 | 1259 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 1181 | 1260 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); |
| 1182 | 1261 | 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, {}); | |
| 1184 | 1263 | return; |
| 1185 | 1264 | } |
| 1186 | 1265 | |
| ... | ... | @@ -1188,7 +1267,7 @@ pub fn updateDecl( |
| 1188 | 1267 | Atom.freeRelocations(self, atom_index); |
| 1189 | 1268 | const atom = self.getAtom(atom_index); |
| 1190 | 1269 | |
| 1191 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | |
| 1270 | var code_buffer = std.ArrayList(u8).init(gpa); | |
| 1192 | 1271 | defer code_buffer.deinit(); |
| 1193 | 1272 | |
| 1194 | 1273 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| ... | ... | @@ -1220,8 +1299,8 @@ fn updateLazySymbolAtom( |
| 1220 | 1299 | atom_index: Atom.Index, |
| 1221 | 1300 | section_index: u16, |
| 1222 | 1301 | ) !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.?; | |
| 1225 | 1304 | |
| 1226 | 1305 | var required_alignment: InternPool.Alignment = .none; |
| 1227 | 1306 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -1281,8 +1360,9 @@ fn updateLazySymbolAtom( |
| 1281 | 1360 | } |
| 1282 | 1361 | |
| 1283 | 1362 | pub 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)); | |
| 1286 | 1366 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 1287 | 1367 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 1288 | 1368 | 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 |
| 1305 | 1385 | } |
| 1306 | 1386 | |
| 1307 | 1387 | pub 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); | |
| 1309 | 1390 | if (!gop.found_existing) { |
| 1310 | 1391 | gop.value_ptr.* = .{ |
| 1311 | 1392 | .atom = try self.createAtom(), |
| ... | ... | @@ -1317,9 +1398,9 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !At |
| 1317 | 1398 | } |
| 1318 | 1399 | |
| 1319 | 1400 | fn 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); | |
| 1321 | 1402 | const ty = decl.ty; |
| 1322 | const mod = self.base.options.module.?; | |
| 1403 | const mod = self.base.comp.module.?; | |
| 1323 | 1404 | const zig_ty = ty.zigTypeTag(mod); |
| 1324 | 1405 | const val = decl.val; |
| 1325 | 1406 | const index: u16 = blk: { |
| ... | ... | @@ -1343,7 +1424,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 { |
| 1343 | 1424 | } |
| 1344 | 1425 | |
| 1345 | 1426 | fn 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.?; | |
| 1347 | 1428 | const decl = mod.declPtr(decl_index); |
| 1348 | 1429 | |
| 1349 | 1430 | 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 |
| 1401 | 1482 | } |
| 1402 | 1483 | |
| 1403 | 1484 | fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void { |
| 1404 | const gpa = self.base.allocator; | |
| 1485 | const gpa = self.base.comp.gpa; | |
| 1405 | 1486 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 1406 | 1487 | for (unnamed_consts.items) |atom_index| { |
| 1407 | 1488 | self.freeAtom(atom_index); |
| ... | ... | @@ -1412,7 +1493,8 @@ fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void { |
| 1412 | 1493 | pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void { |
| 1413 | 1494 | if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index); |
| 1414 | 1495 | |
| 1415 | const mod = self.base.options.module.?; | |
| 1496 | const gpa = self.base.comp.gpa; | |
| 1497 | const mod = self.base.comp.module.?; | |
| 1416 | 1498 | const decl = mod.declPtr(decl_index); |
| 1417 | 1499 | |
| 1418 | 1500 | log.debug("freeDecl {*}", .{decl}); |
| ... | ... | @@ -1421,7 +1503,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void { |
| 1421 | 1503 | var kv = const_kv; |
| 1422 | 1504 | self.freeAtom(kv.value.atom); |
| 1423 | 1505 | self.freeUnnamedConsts(decl_index); |
| 1424 | kv.value.exports.deinit(self.base.allocator); | |
| 1506 | kv.value.exports.deinit(gpa); | |
| 1425 | 1507 | } |
| 1426 | 1508 | } |
| 1427 | 1509 | |
| ... | ... | @@ -1436,8 +1518,10 @@ pub fn updateExports( |
| 1436 | 1518 | } |
| 1437 | 1519 | |
| 1438 | 1520 | const ip = &mod.intern_pool; |
| 1521 | const comp = self.base.comp; | |
| 1522 | const target = comp.root_mod.resolved_target.result; | |
| 1439 | 1523 | |
| 1440 | if (self.base.options.use_llvm) { | |
| 1524 | if (comp.config.use_llvm) { | |
| 1441 | 1525 | // Even in the case of LLVM, we need to notice certain exported symbols in order to |
| 1442 | 1526 | // detect the default subsystem. |
| 1443 | 1527 | for (exports) |exp| { |
| ... | ... | @@ -1447,16 +1531,16 @@ pub fn updateExports( |
| 1447 | 1531 | }; |
| 1448 | 1532 | const exported_decl = mod.declPtr(exported_decl_index); |
| 1449 | 1533 | 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) { | |
| 1451 | 1535 | .x86 => std.builtin.CallingConvention.Stdcall, |
| 1452 | 1536 | else => std.builtin.CallingConvention.C, |
| 1453 | 1537 | }; |
| 1454 | 1538 | const decl_cc = exported_decl.ty.fnCallingConvention(mod); |
| 1455 | 1539 | if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and |
| 1456 | self.base.options.link_libc) | |
| 1540 | comp.config.link_libc) | |
| 1457 | 1541 | { |
| 1458 | 1542 | 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) { | |
| 1460 | 1544 | if (ip.stringEqlSlice(exp.opts.name, "WinMain")) { |
| 1461 | 1545 | mod.stage1_flags.have_winmain = true; |
| 1462 | 1546 | } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) { |
| ... | ... | @@ -1474,9 +1558,7 @@ pub fn updateExports( |
| 1474 | 1558 | |
| 1475 | 1559 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports); |
| 1476 | 1560 | |
| 1477 | if (self.base.options.emit == null) return; | |
| 1478 | ||
| 1479 | const gpa = self.base.allocator; | |
| 1561 | const gpa = comp.gpa; | |
| 1480 | 1562 | |
| 1481 | 1563 | const metadata = switch (exported) { |
| 1482 | 1564 | .decl_index => |decl_index| blk: { |
| ... | ... | @@ -1570,11 +1652,11 @@ pub fn deleteDeclExport( |
| 1570 | 1652 | ) void { |
| 1571 | 1653 | if (self.llvm_object) |_| return; |
| 1572 | 1654 | const metadata = self.decls.getPtr(decl_index) orelse return; |
| 1573 | const mod = self.base.options.module.?; | |
| 1655 | const mod = self.base.comp.module.?; | |
| 1574 | 1656 | const name = mod.intern_pool.stringToSlice(name_ip); |
| 1575 | 1657 | const sym_index = metadata.getExportPtr(self, name) orelse return; |
| 1576 | 1658 | |
| 1577 | const gpa = self.base.allocator; | |
| 1659 | const gpa = self.base.comp.gpa; | |
| 1578 | 1660 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null }; |
| 1579 | 1661 | const sym = self.getSymbolPtr(sym_loc); |
| 1580 | 1662 | log.debug("deleting export '{s}'", .{name}); |
| ... | ... | @@ -1602,7 +1684,7 @@ pub fn deleteDeclExport( |
| 1602 | 1684 | } |
| 1603 | 1685 | |
| 1604 | 1686 | fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| 1605 | const gpa = self.base.allocator; | |
| 1687 | const gpa = self.base.comp.gpa; | |
| 1606 | 1688 | const sym = self.getSymbol(current); |
| 1607 | 1689 | const sym_name = self.getSymbolName(current); |
| 1608 | 1690 | |
| ... | ... | @@ -1624,38 +1706,35 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| 1624 | 1706 | gop.value_ptr.* = current; |
| 1625 | 1707 | } |
| 1626 | 1708 | |
| 1627 | pub 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; | |
| 1709 | pub 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; | |
| 1635 | 1712 | if (use_lld) { |
| 1636 | return lld.linkWithLLD(self, comp, prog_node); | |
| 1713 | return lld.linkWithLLD(self, arena, prog_node); | |
| 1637 | 1714 | } |
| 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), | |
| 1640 | 1717 | .Lib => return error.TODOImplementWritingLibFiles, |
| 1641 | 1718 | } |
| 1642 | 1719 | } |
| 1643 | 1720 | |
| 1644 | pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 1721 | pub fn flushModule(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 1645 | 1722 | const tracy = trace(@src()); |
| 1646 | 1723 | defer tracy.end(); |
| 1647 | 1724 | |
| 1725 | const comp = self.base.comp; | |
| 1726 | const gpa = comp.gpa; | |
| 1727 | ||
| 1648 | 1728 | 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; | |
| 1650 | 1731 | } |
| 1651 | 1732 | |
| 1652 | 1733 | var sub_prog_node = prog_node.start("COFF Flush", 0); |
| 1653 | 1734 | sub_prog_node.activate(); |
| 1654 | 1735 | defer sub_prog_node.end(); |
| 1655 | 1736 | |
| 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; | |
| 1659 | 1738 | |
| 1660 | 1739 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 1661 | 1740 | // 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 |
| 1756 | 1835 | try self.writeDataDirectoriesHeaders(); |
| 1757 | 1836 | try self.writeSectionHeaders(); |
| 1758 | 1837 | |
| 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) { | |
| 1760 | 1839 | 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; | |
| 1762 | 1841 | } else { |
| 1763 | 1842 | 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; | |
| 1765 | 1844 | try self.writeHeader(); |
| 1766 | 1845 | } |
| 1767 | 1846 | |
| ... | ... | @@ -1794,8 +1873,8 @@ pub fn lowerAnonDecl( |
| 1794 | 1873 | explicit_alignment: InternPool.Alignment, |
| 1795 | 1874 | src_loc: Module.SrcLoc, |
| 1796 | 1875 | ) !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.?; | |
| 1799 | 1878 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1800 | 1879 | const decl_alignment = switch (explicit_alignment) { |
| 1801 | 1880 | .none => ty.abiAlignment(mod), |
| ... | ... | @@ -1868,7 +1947,7 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8 |
| 1868 | 1947 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1869 | 1948 | gop.value_ptr.* = sym_loc; |
| 1870 | 1949 | |
| 1871 | const gpa = self.base.allocator; | |
| 1950 | const gpa = self.base.comp.gpa; | |
| 1872 | 1951 | const sym = self.getSymbolPtr(sym_loc); |
| 1873 | 1952 | try self.setSymbolName(sym, name); |
| 1874 | 1953 | sym.storage_class = .EXTERNAL; |
| ... | ... | @@ -1895,7 +1974,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: InternPool |
| 1895 | 1974 | /// TODO: note that .ABSOLUTE is used as padding within each block; we could use this fact to do |
| 1896 | 1975 | /// incremental updates and writes into the table instead of doing it all at once |
| 1897 | 1976 | fn writeBaseRelocations(self: *Coff) !void { |
| 1898 | const gpa = self.base.allocator; | |
| 1977 | const gpa = self.base.comp.gpa; | |
| 1899 | 1978 | |
| 1900 | 1979 | var page_table = std.AutoHashMap(u32, std.ArrayList(coff.BaseRelocation)).init(gpa); |
| 1901 | 1980 | defer { |
| ... | ... | @@ -2006,7 +2085,7 @@ fn writeImportTables(self: *Coff) !void { |
| 2006 | 2085 | if (self.idata_section_index == null) return; |
| 2007 | 2086 | if (!self.imports_count_dirty) return; |
| 2008 | 2087 | |
| 2009 | const gpa = self.base.allocator; | |
| 2088 | const gpa = self.base.comp.gpa; | |
| 2010 | 2089 | |
| 2011 | 2090 | const ext = ".dll"; |
| 2012 | 2091 | const header = &self.sections.items(.header)[self.idata_section_index.?]; |
| ... | ... | @@ -2154,7 +2233,8 @@ fn writeStrtab(self: *Coff) !void { |
| 2154 | 2233 | |
| 2155 | 2234 | log.debug("writing strtab from 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + needed_size }); |
| 2156 | 2235 | |
| 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); | |
| 2158 | 2238 | defer buffer.deinit(); |
| 2159 | 2239 | try buffer.ensureTotalCapacityPrecise(needed_size); |
| 2160 | 2240 | buffer.appendSliceAssumeCapacity(self.strtab.buffer.items); |
| ... | ... | @@ -2176,7 +2256,8 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void { |
| 2176 | 2256 | } |
| 2177 | 2257 | |
| 2178 | 2258 | fn 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; | |
| 2180 | 2261 | var buffer = std.ArrayList(u8).init(gpa); |
| 2181 | 2262 | defer buffer.deinit(); |
| 2182 | 2263 | const writer = buffer.writer(); |
| ... | ... | @@ -2194,14 +2275,14 @@ fn writeHeader(self: *Coff) !void { |
| 2194 | 2275 | .p32 => flags.@"32BIT_MACHINE" = 1, |
| 2195 | 2276 | .p64 => flags.LARGE_ADDRESS_AWARE = 1, |
| 2196 | 2277 | } |
| 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) { | |
| 2198 | 2279 | flags.DLL = 1; |
| 2199 | 2280 | } |
| 2200 | 2281 | |
| 2201 | 2282 | const timestamp = std.time.timestamp(); |
| 2202 | 2283 | const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize())); |
| 2203 | 2284 | var coff_header = coff.CoffHeader{ |
| 2204 | .machine = coff.MachineType.fromTargetCpuArch(self.base.options.target.cpu.arch), | |
| 2285 | .machine = coff.MachineType.fromTargetCpuArch(target.cpu.arch), | |
| 2205 | 2286 | .number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section |
| 2206 | 2287 | .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))), |
| 2207 | 2288 | .pointer_to_symbol_table = self.strtab_offset orelse 0, |
| ... | ... | @@ -2221,8 +2302,6 @@ fn writeHeader(self: *Coff) !void { |
| 2221 | 2302 | const subsystem: coff.Subsystem = .WINDOWS_CUI; |
| 2222 | 2303 | const size_of_image: u32 = self.getSizeOfImage(); |
| 2223 | 2304 | const size_of_headers: u32 = mem.alignForward(u32, self.getSizeOfHeaders(), default_file_alignment); |
| 2224 | const image_base = self.getImageBase(); | |
| 2225 | ||
| 2226 | 2305 | const base_of_code = self.sections.get(self.text_section_index.?).header.virtual_address; |
| 2227 | 2306 | const base_of_data = self.sections.get(self.data_section_index.?).header.virtual_address; |
| 2228 | 2307 | |
| ... | ... | @@ -2253,15 +2332,15 @@ fn writeHeader(self: *Coff) !void { |
| 2253 | 2332 | .address_of_entry_point = self.entry_addr orelse 0, |
| 2254 | 2333 | .base_of_code = base_of_code, |
| 2255 | 2334 | .base_of_data = base_of_data, |
| 2256 | .image_base = @as(u32, @intCast(image_base)), | |
| 2335 | .image_base = @intCast(self.image_base), | |
| 2257 | 2336 | .section_alignment = self.page_size, |
| 2258 | 2337 | .file_alignment = default_file_alignment, |
| 2259 | 2338 | .major_operating_system_version = 6, |
| 2260 | 2339 | .minor_operating_system_version = 0, |
| 2261 | 2340 | .major_image_version = 0, |
| 2262 | 2341 | .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), | |
| 2265 | 2344 | .win32_version_value = 0, |
| 2266 | 2345 | .size_of_image = size_of_image, |
| 2267 | 2346 | .size_of_headers = size_of_headers, |
| ... | ... | @@ -2273,7 +2352,7 @@ fn writeHeader(self: *Coff) !void { |
| 2273 | 2352 | .size_of_heap_reserve = default_size_of_heap_reserve, |
| 2274 | 2353 | .size_of_heap_commit = default_size_of_heap_commit, |
| 2275 | 2354 | .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), | |
| 2277 | 2356 | }; |
| 2278 | 2357 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; |
| 2279 | 2358 | }, |
| ... | ... | @@ -2287,15 +2366,15 @@ fn writeHeader(self: *Coff) !void { |
| 2287 | 2366 | .size_of_uninitialized_data = size_of_uninitialized_data, |
| 2288 | 2367 | .address_of_entry_point = self.entry_addr orelse 0, |
| 2289 | 2368 | .base_of_code = base_of_code, |
| 2290 | .image_base = image_base, | |
| 2369 | .image_base = self.image_base, | |
| 2291 | 2370 | .section_alignment = self.page_size, |
| 2292 | 2371 | .file_alignment = default_file_alignment, |
| 2293 | 2372 | .major_operating_system_version = 6, |
| 2294 | 2373 | .minor_operating_system_version = 0, |
| 2295 | 2374 | .major_image_version = 0, |
| 2296 | 2375 | .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, | |
| 2299 | 2378 | .win32_version_value = 0, |
| 2300 | 2379 | .size_of_image = size_of_image, |
| 2301 | 2380 | .size_of_headers = size_of_headers, |
| ... | ... | @@ -2307,7 +2386,7 @@ fn writeHeader(self: *Coff) !void { |
| 2307 | 2386 | .size_of_heap_reserve = default_size_of_heap_reserve, |
| 2308 | 2387 | .size_of_heap_commit = default_size_of_heap_commit, |
| 2309 | 2388 | .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), | |
| 2311 | 2390 | }; |
| 2312 | 2391 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; |
| 2313 | 2392 | }, |
| ... | ... | @@ -2421,22 +2500,23 @@ inline fn getSizeOfImage(self: Coff) u32 { |
| 2421 | 2500 | |
| 2422 | 2501 | /// Returns symbol location corresponding to the set entrypoint (if any). |
| 2423 | 2502 | pub 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 | ||
| 2429 | pub 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, | |
| 2435 | 2514 | }, |
| 2436 | .Lib => 0x10000000, | |
| 2437 | .Obj => 0, | |
| 2515 | .enabled => "wWinMainCRTStartup", | |
| 2516 | .named => |name| name, | |
| 2438 | 2517 | }; |
| 2439 | return image_base; | |
| 2518 | const global_index = self.resolver.get(entry_name) orelse return null; | |
| 2519 | return self.globals.items[global_index]; | |
| 2440 | 2520 | } |
| 2441 | 2521 | |
| 2442 | 2522 | /// Returns pointer-to-symbol described by `sym_loc` descriptor. |
| ... | ... | @@ -2499,7 +2579,7 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult |
| 2499 | 2579 | if (self.getGlobalPtr(name)) |ptr| { |
| 2500 | 2580 | return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr }; |
| 2501 | 2581 | } |
| 2502 | const gpa = self.base.allocator; | |
| 2582 | const gpa = self.base.comp.gpa; | |
| 2503 | 2583 | const global_index = try self.allocateGlobal(); |
| 2504 | 2584 | const global_name = try gpa.dupe(u8, name); |
| 2505 | 2585 | _ = try self.resolver.put(gpa, global_name, global_index); |
| ... | ... | @@ -2530,7 +2610,8 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v |
| 2530 | 2610 | @memset(header.name[name.len..], 0); |
| 2531 | 2611 | return; |
| 2532 | 2612 | } |
| 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); | |
| 2534 | 2615 | const name_offset = fmt.bufPrint(&header.name, "/{d}", .{offset}) catch unreachable; |
| 2535 | 2616 | @memset(header.name[name_offset.len..], 0); |
| 2536 | 2617 | } |
| ... | ... | @@ -2549,7 +2630,8 @@ fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void { |
| 2549 | 2630 | @memset(symbol.name[name.len..], 0); |
| 2550 | 2631 | return; |
| 2551 | 2632 | } |
| 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); | |
| 2553 | 2635 | @memset(symbol.name[0..4], 0); |
| 2554 | 2636 | mem.writeInt(u32, symbol.name[4..8], offset, .little); |
| 2555 | 2637 | } |
src/link/Coff/Atom.zig+6-3| ... | ... | @@ -94,7 +94,8 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool { |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | pub 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; | |
| 98 | 99 | log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index }); |
| 99 | 100 | const gop = try coff_file.relocs.getOrPut(gpa, atom_index); |
| 100 | 101 | if (!gop.found_existing) { |
| ... | ... | @@ -104,7 +105,8 @@ pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !vo |
| 104 | 105 | } |
| 105 | 106 | |
| 106 | 107 | pub 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; | |
| 108 | 110 | log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{ |
| 109 | 111 | offset, |
| 110 | 112 | coff_file.getAtom(atom_index).getSymbolIndex().?, |
| ... | ... | @@ -117,7 +119,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void |
| 117 | 119 | } |
| 118 | 120 | |
| 119 | 121 | pub 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; | |
| 121 | 124 | var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index); |
| 122 | 125 | if (removed_relocs) |*relocs| relocs.value.deinit(gpa); |
| 123 | 126 | 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: |
| 107 | 107 | .ptr_width = coff_file.ptr_width, |
| 108 | 108 | }; |
| 109 | 109 | |
| 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) { | |
| 111 | 112 | .aarch64 => self.resolveAarch64(ctx), |
| 112 | 113 | .x86, .x86_64 => self.resolveX86(ctx), |
| 113 | 114 | else => unreachable, // unhandled target architecture |
src/link/Coff/lld.zig+94-99| ... | ... | @@ -17,26 +17,25 @@ const Allocator = mem.Allocator; |
| 17 | 17 | const Coff = @import("../Coff.zig"); |
| 18 | 18 | const Compilation = @import("../../Compilation.zig"); |
| 19 | 19 | |
| 20 | pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 20 | pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) !void { | |
| 21 | 21 | const tracy = trace(@src()); |
| 22 | 22 | defer tracy.end(); |
| 23 | 23 | |
| 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; | |
| 27 | 26 | |
| 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}); | |
| 30 | 29 | |
| 31 | 30 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 32 | 31 | // 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); | |
| 35 | 34 | |
| 36 | 35 | 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.? }); | |
| 38 | 37 | } else { |
| 39 | break :blk self.base.intermediary_basename.?; | |
| 38 | break :blk self.base.zcu_object_sub_path.?; | |
| 40 | 39 | } |
| 41 | 40 | } else null; |
| 42 | 41 | |
| ... | ... | @@ -45,27 +44,35 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 45 | 44 | sub_prog_node.context.refresh(); |
| 46 | 45 | defer sub_prog_node.end(); |
| 47 | 46 | |
| 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 | }; | |
| 53 | 60 | |
| 54 | 61 | // See link/Elf.zig for comments on how this mechanism works. |
| 55 | 62 | const id_symlink_basename = "lld.id"; |
| 56 | 63 | |
| 57 | 64 | 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(); | |
| 59 | 66 | |
| 60 | 67 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 61 | 68 | |
| 62 | if (!self.base.options.disable_lld_caching) { | |
| 69 | if (!self.base.disable_lld_caching) { | |
| 63 | 70 | man = comp.cache_parent.obtain(); |
| 64 | 71 | self.base.releaseLock(); |
| 65 | 72 | |
| 66 | 73 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 67 | 74 | |
| 68 | for (self.base.options.objects) |obj| { | |
| 75 | for (comp.objects) |obj| { | |
| 69 | 76 | _ = try man.addFile(obj.path, null); |
| 70 | 77 | man.hash.add(obj.must_link); |
| 71 | 78 | } |
| ... | ... | @@ -78,14 +85,14 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 78 | 85 | } |
| 79 | 86 | } |
| 80 | 87 | 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| { | |
| 89 | 96 | man.hash.addBytes(libc_installation.crt_dir.?); |
| 90 | 97 | if (target.abi == .msvc) { |
| 91 | 98 | man.hash.addBytes(libc_installation.msvc_lib_dir.?); |
| ... | ... | @@ -93,19 +100,19 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 93 | 100 | } |
| 94 | 101 | } |
| 95 | 102 | } |
| 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); | |
| 104 | 111 | // 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); | |
| 109 | 116 | |
| 110 | 117 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 111 | 118 | _ = try man.hit(); |
| ... | ... | @@ -135,13 +142,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 135 | 142 | }; |
| 136 | 143 | } |
| 137 | 144 | |
| 138 | if (self.base.options.output_mode == .Obj) { | |
| 145 | if (comp.config.output_mode == .Obj) { | |
| 139 | 146 | // LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy |
| 140 | 147 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 141 | 148 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 142 | 149 | 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; | |
| 145 | 152 | |
| 146 | 153 | if (comp.c_object_table.count() != 0) |
| 147 | 154 | 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 |
| 160 | 167 | } |
| 161 | 168 | } else { |
| 162 | 169 | // 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); | |
| 164 | 171 | defer argv.deinit(); |
| 165 | 172 | // We will invoke ourselves as a child process to gain access to LLD. |
| 166 | 173 | // 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 |
| 170 | 177 | |
| 171 | 178 | try argv.append("-ERRORLIMIT:0"); |
| 172 | 179 | try argv.append("-NOLOGO"); |
| 173 | if (!self.base.options.strip) { | |
| 180 | if (comp.config.debug_format != .strip) { | |
| 174 | 181 | try argv.append("-DEBUG"); |
| 175 | 182 | |
| 176 | 183 | 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", .{ | |
| 178 | 185 | full_out_path[0 .. full_out_path.len - out_ext.len], |
| 179 | 186 | }); |
| 180 | 187 | |
| 181 | 188 | try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb})); |
| 182 | 189 | try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb})); |
| 183 | 190 | } |
| 184 | if (self.base.options.version) |version| { | |
| 191 | if (comp.version) |version| { | |
| 185 | 192 | try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor })); |
| 186 | 193 | } |
| 187 | if (self.base.options.lto) { | |
| 188 | switch (self.base.options.optimize_mode) { | |
| 194 | if (comp.config.lto) { | |
| 195 | switch (optimize_mode) { | |
| 189 | 196 | .Debug => {}, |
| 190 | 197 | .ReleaseSmall => try argv.append("-OPT:lldlto=2"), |
| 191 | 198 | .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"), |
| 192 | 199 | } |
| 193 | 200 | } |
| 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})); | |
| 200 | 203 | } |
| 204 | try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{self.image_base})); | |
| 201 | 205 | |
| 202 | 206 | if (target.cpu.arch == .x86) { |
| 203 | 207 | try argv.append("-MACHINE:X86"); |
| ... | ... | @@ -211,7 +215,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 211 | 215 | } |
| 212 | 216 | } |
| 213 | 217 | |
| 214 | for (self.base.options.force_undefined_symbols.keys()) |symbol| { | |
| 218 | for (comp.force_undefined_symbols.keys()) |symbol| { | |
| 215 | 219 | try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol})); |
| 216 | 220 | } |
| 217 | 221 | |
| ... | ... | @@ -219,34 +223,32 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 219 | 223 | try argv.append("-DLL"); |
| 220 | 224 | } |
| 221 | 225 | |
| 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})); | |
| 224 | 228 | } |
| 225 | 229 | |
| 226 | if (self.base.options.tsaware) { | |
| 230 | if (self.tsaware) { | |
| 227 | 231 | try argv.append("-tsaware"); |
| 228 | 232 | } |
| 229 | if (self.base.options.nxcompat) { | |
| 233 | if (self.nxcompat) { | |
| 230 | 234 | try argv.append("-nxcompat"); |
| 231 | 235 | } |
| 232 | if (!self.base.options.dynamicbase) { | |
| 236 | if (!self.dynamicbase) { | |
| 233 | 237 | try argv.append("-dynamicbase:NO"); |
| 234 | 238 | } |
| 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"); | |
| 239 | 241 | } |
| 240 | 242 | |
| 241 | 243 | try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path})); |
| 242 | 244 | |
| 243 | if (self.base.options.implib_emit) |emit| { | |
| 245 | if (comp.implib_emit) |emit| { | |
| 244 | 246 | const implib_out_path = try emit.directory.join(arena, &[_][]const u8{emit.sub_path}); |
| 245 | 247 | try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path})); |
| 246 | 248 | } |
| 247 | 249 | |
| 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| { | |
| 250 | 252 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); |
| 251 | 253 | |
| 252 | 254 | if (target.abi == .msvc) { |
| ... | ... | @@ -256,12 +258,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 256 | 258 | } |
| 257 | 259 | } |
| 258 | 260 | |
| 259 | for (self.base.options.lib_dirs) |lib_dir| { | |
| 261 | for (self.lib_dirs) |lib_dir| { | |
| 260 | 262 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 261 | 263 | } |
| 262 | 264 | |
| 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| { | |
| 265 | 267 | if (obj.must_link) { |
| 266 | 268 | argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{s}", .{obj.path})); |
| 267 | 269 | } else { |
| ... | ... | @@ -283,18 +285,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 283 | 285 | try argv.append(p); |
| 284 | 286 | } |
| 285 | 287 | |
| 286 | if (self.base.options.module_definition_file) |def| { | |
| 288 | if (self.module_definition_file) |def| { | |
| 287 | 289 | try argv.append(try allocPrint(arena, "-DEF:{s}", .{def})); |
| 288 | 290 | } |
| 289 | 291 | |
| 290 | 292 | 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; | |
| 292 | 294 | switch (target.os.tag) { |
| 293 | 295 | .windows => { |
| 294 | if (self.base.options.module) |module| { | |
| 296 | if (comp.module) |module| { | |
| 295 | 297 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) |
| 296 | 298 | 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 | |
| 298 | 300 | module.stage1_flags.have_winmain_crt_startup or |
| 299 | 301 | module.stage1_flags.have_wwinmain_crt_startup) |
| 300 | 302 | { |
| ... | ... | @@ -313,16 +315,9 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 313 | 315 | const Mode = enum { uefi, win32 }; |
| 314 | 316 | const mode: Mode = mode: { |
| 315 | 317 | 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 | }); | |
| 326 | 321 | |
| 327 | 322 | switch (subsystem) { |
| 328 | 323 | .Console => { |
| ... | ... | @@ -419,21 +414,21 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 419 | 414 | try argv.append(try comp.get_libc_crt_file(arena, "uuid.lib")); |
| 420 | 415 | |
| 421 | 416 | for (mingw.always_link_libs) |name| { |
| 422 | if (!self.base.options.system_libs.contains(name)) { | |
| 417 | if (!comp.system_libs.contains(name)) { | |
| 423 | 418 | const lib_basename = try allocPrint(arena, "{s}.lib", .{name}); |
| 424 | 419 | try argv.append(try comp.get_libc_crt_file(arena, lib_basename)); |
| 425 | 420 | } |
| 426 | 421 | } |
| 427 | 422 | } else { |
| 428 | const lib_str = switch (self.base.options.link_mode) { | |
| 423 | const lib_str = switch (comp.config.link_mode) { | |
| 429 | 424 | .Dynamic => "", |
| 430 | 425 | .Static => "lib", |
| 431 | 426 | }; |
| 432 | const d_str = switch (self.base.options.optimize_mode) { | |
| 427 | const d_str = switch (optimize_mode) { | |
| 433 | 428 | .Debug => "d", |
| 434 | 429 | else => "", |
| 435 | 430 | }; |
| 436 | switch (self.base.options.link_mode) { | |
| 431 | switch (comp.config.link_mode) { | |
| 437 | 432 | .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})), |
| 438 | 433 | .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})), |
| 439 | 434 | } |
| ... | ... | @@ -451,8 +446,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 451 | 446 | } |
| 452 | 447 | } else { |
| 453 | 448 | 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| { | |
| 456 | 451 | if (module.stage1_flags.have_winmain_crt_startup) { |
| 457 | 452 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 458 | 453 | } else { |
| ... | ... | @@ -467,18 +462,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 467 | 462 | } |
| 468 | 463 | |
| 469 | 464 | // libc++ dep |
| 470 | if (self.base.options.link_libcpp) { | |
| 465 | if (comp.config.link_libcpp) { | |
| 471 | 466 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 472 | 467 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 473 | 468 | } |
| 474 | 469 | |
| 475 | 470 | // libunwind dep |
| 476 | if (self.base.options.link_libunwind) { | |
| 471 | if (comp.config.link_libunwind) { | |
| 477 | 472 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 478 | 473 | } |
| 479 | 474 | |
| 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) { | |
| 482 | 477 | if (comp.libc_static_lib) |lib| { |
| 483 | 478 | try argv.append(lib.full_object_path); |
| 484 | 479 | } |
| ... | ... | @@ -489,20 +484,20 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 489 | 484 | if (comp.compiler_rt_lib) |lib| try argv.append(lib.full_object_path); |
| 490 | 485 | } |
| 491 | 486 | |
| 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| { | |
| 494 | 489 | const lib_basename = try allocPrint(arena, "{s}.lib", .{key}); |
| 495 | 490 | if (comp.crt_files.get(lib_basename)) |crt_file| { |
| 496 | 491 | argv.appendAssumeCapacity(crt_file.full_object_path); |
| 497 | 492 | continue; |
| 498 | 493 | } |
| 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| { | |
| 500 | 495 | argv.appendAssumeCapacity(full_path); |
| 501 | 496 | continue; |
| 502 | 497 | } |
| 503 | 498 | if (target.abi.isGnu()) { |
| 504 | 499 | 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| { | |
| 506 | 501 | argv.appendAssumeCapacity(full_path); |
| 507 | 502 | continue; |
| 508 | 503 | } |
| ... | ... | @@ -516,7 +511,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 516 | 511 | return error.DllImportLibraryNotFound; |
| 517 | 512 | } |
| 518 | 513 | |
| 519 | if (self.base.options.verbose_link) { | |
| 514 | if (comp.verbose_link) { | |
| 520 | 515 | // Skip over our own name so that the LLD linker name is the first argv item. |
| 521 | 516 | Compilation.dump_argv(argv.items[1..]); |
| 522 | 517 | } |
| ... | ... | @@ -586,7 +581,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 586 | 581 | } |
| 587 | 582 | } |
| 588 | 583 | |
| 589 | if (!self.base.options.disable_lld_caching) { | |
| 584 | if (!self.base.disable_lld_caching) { | |
| 590 | 585 | // Update the file with the digest. If it fails we can continue; it only |
| 591 | 586 | // means that the next invocation will have an unnecessary cache miss. |
| 592 | 587 | 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; |
| 1022 | 1022 | /// actual_capacity + (actual_capacity / ideal_factor) |
| 1023 | 1023 | const ideal_factor = 3; |
| 1024 | 1024 | |
| 1025 | pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf { | |
| 1026 | const target = &bin_file.options.target; | |
| 1025 | pub 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; | |
| 1027 | 1029 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { |
| 1028 | 1030 | 0...32 => .p32, |
| 1029 | 1031 | 33...64 => .p64, |
| 1030 | 1032 | else => unreachable, |
| 1031 | 1033 | }; |
| 1032 | 1034 | return .{ |
| 1033 | .allocator = allocator, | |
| 1034 | .bin_file = bin_file, | |
| 1035 | .allocator = gpa, | |
| 1036 | .bin_file = lf, | |
| 1035 | 1037 | .format = format, |
| 1036 | 1038 | .ptr_width = ptr_width, |
| 1037 | 1039 | .dbg_line_header = switch (target.cpu.arch) { |
| ... | ... | @@ -1190,7 +1192,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde |
| 1190 | 1192 | |
| 1191 | 1193 | pub fn commitDeclState( |
| 1192 | 1194 | self: *Dwarf, |
| 1193 | mod: *Module, | |
| 1195 | zcu: *Module, | |
| 1194 | 1196 | decl_index: InternPool.DeclIndex, |
| 1195 | 1197 | sym_addr: u64, |
| 1196 | 1198 | sym_size: u64, |
| ... | ... | @@ -1200,15 +1202,17 @@ pub fn commitDeclState( |
| 1200 | 1202 | defer tracy.end(); |
| 1201 | 1203 | |
| 1202 | 1204 | 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 | ||
| 1203 | 1211 | var dbg_line_buffer = &decl_state.dbg_line; |
| 1204 | 1212 | 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(); | |
| 1209 | 1213 | |
| 1210 | 1214 | assert(decl.has_tv); |
| 1211 | switch (decl.ty.zigTypeTag(mod)) { | |
| 1215 | switch (decl.ty.zigTypeTag(zcu)) { | |
| 1212 | 1216 | .Fn => { |
| 1213 | 1217 | try decl_state.setInlineFunc(decl.val.toIntern()); |
| 1214 | 1218 | |
| ... | ... | @@ -1407,18 +1411,18 @@ pub fn commitDeclState( |
| 1407 | 1411 | if (ip.isErrorSetType(ty.toIntern())) continue; |
| 1408 | 1412 | |
| 1409 | 1413 | 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); | |
| 1411 | 1415 | } |
| 1412 | 1416 | } |
| 1413 | 1417 | |
| 1414 | 1418 | try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len)); |
| 1415 | 1419 | |
| 1416 | 1420 | 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]; | |
| 1419 | 1423 | const ty = symbol.type; |
| 1420 | 1424 | if (ip.isErrorSetType(ty.toIntern())) { |
| 1421 | log.debug("resolving %{d} deferred until flush", .{target}); | |
| 1425 | log.debug("resolving %{d} deferred until flush", .{reloc_target}); | |
| 1422 | 1426 | try self.global_abbrev_relocs.append(gpa, .{ |
| 1423 | 1427 | .target = null, |
| 1424 | 1428 | .offset = reloc.offset, |
| ... | ... | @@ -1431,8 +1435,8 @@ pub fn commitDeclState( |
| 1431 | 1435 | log.debug("{x}: [() => {x}] (%{d}, '{}')", .{ |
| 1432 | 1436 | reloc.offset, |
| 1433 | 1437 | value, |
| 1434 | target, | |
| 1435 | ty.fmt(mod), | |
| 1438 | reloc_target, | |
| 1439 | ty.fmt(zcu), | |
| 1436 | 1440 | }); |
| 1437 | 1441 | mem.writeInt( |
| 1438 | 1442 | u32, |
| ... | ... | @@ -1741,6 +1745,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void { |
| 1741 | 1745 | } |
| 1742 | 1746 | |
| 1743 | 1747 | pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1748 | const gpa = self.allocator; | |
| 1744 | 1749 | // These are LEB encoded but since the values are all less than 127 |
| 1745 | 1750 | // we can simply append these bytes. |
| 1746 | 1751 | // zig fmt: off |
| ... | ... | @@ -1883,7 +1888,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1883 | 1888 | .wasm => { |
| 1884 | 1889 | const wasm_file = self.bin_file.cast(File.Wasm).?; |
| 1885 | 1890 | 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); | |
| 1887 | 1892 | debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf; |
| 1888 | 1893 | }, |
| 1889 | 1894 | else => unreachable, |
| ... | ... | @@ -1895,7 +1900,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize { |
| 1895 | 1900 | return 120; |
| 1896 | 1901 | } |
| 1897 | 1902 | |
| 1898 | pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u64) !void { | |
| 1903 | pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) !void { | |
| 1899 | 1904 | // If this value is null it means there is an error in the module; |
| 1900 | 1905 | // leave debug_info_header_dirty=true. |
| 1901 | 1906 | 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 |
| 1906 | 1911 | var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes); |
| 1907 | 1912 | defer di_buf.deinit(); |
| 1908 | 1913 | |
| 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(); | |
| 1910 | 1917 | const init_len_size: usize = switch (self.format) { |
| 1911 | 1918 | .dwarf32 => 4, |
| 1912 | 1919 | .dwarf64 => 12, |
| ... | ... | @@ -1929,9 +1936,9 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u |
| 1929 | 1936 | di_buf.appendAssumeCapacity(self.ptrWidthBytes()); // address size |
| 1930 | 1937 | |
| 1931 | 1938 | // 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); | |
| 1933 | 1940 | 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); | |
| 1935 | 1942 | const comp_dir_strp = try self.strtab.insert(self.allocator, compile_unit_dir); |
| 1936 | 1943 | const producer_strp = try self.strtab.insert(self.allocator, link.producer_string); |
| 1937 | 1944 | |
| ... | ... | @@ -1995,7 +2002,9 @@ fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) [] |
| 1995 | 2002 | } |
| 1996 | 2003 | |
| 1997 | 2004 | fn 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(); | |
| 1999 | 2008 | switch (self.ptr_width) { |
| 2000 | 2009 | .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(addr), target_endian), |
| 2001 | 2010 | .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 |
| 2003 | 2012 | } |
| 2004 | 2013 | |
| 2005 | 2014 | fn 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(); | |
| 2007 | 2018 | switch (self.format) { |
| 2008 | 2019 | .dwarf32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(off), target_endian), |
| 2009 | 2020 | .dwarf64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), off, target_endian), |
| ... | ... | @@ -2225,7 +2236,10 @@ fn writeDbgInfoNopsToArrayList( |
| 2225 | 2236 | } |
| 2226 | 2237 | |
| 2227 | 2238 | pub 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(); | |
| 2229 | 2243 | const ptr_width_bytes = self.ptrWidthBytes(); |
| 2230 | 2244 | |
| 2231 | 2245 | // 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 { |
| 2289 | 2303 | .wasm => { |
| 2290 | 2304 | const wasm_file = self.bin_file.cast(File.Wasm).?; |
| 2291 | 2305 | 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); | |
| 2293 | 2307 | @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items); |
| 2294 | 2308 | }, |
| 2295 | 2309 | else => unreachable, |
| ... | ... | @@ -2297,9 +2311,10 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { |
| 2297 | 2311 | } |
| 2298 | 2312 | |
| 2299 | 2313 | pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2314 | const comp = self.bin_file.comp; | |
| 2300 | 2315 | 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(); | |
| 2303 | 2318 | const init_len_size: usize = switch (self.format) { |
| 2304 | 2319 | .dwarf32 => 4, |
| 2305 | 2320 | .dwarf64 => 12, |
| ... | ... | @@ -2563,7 +2578,8 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 2563 | 2578 | } |
| 2564 | 2579 | |
| 2565 | 2580 | pub 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; | |
| 2567 | 2583 | |
| 2568 | 2584 | if (self.global_abbrev_relocs.items.len > 0) { |
| 2569 | 2585 | const gpa = self.allocator; |
src/link/Elf.zig+602-506| ... | ... | @@ -1,8 +1,34 @@ |
| 1 | 1 | base: link.File, |
| 2 | image_base: u64, | |
| 3 | emit_relocs: bool, | |
| 4 | z_nodelete: bool, | |
| 5 | z_notext: bool, | |
| 6 | z_defs: bool, | |
| 7 | z_origin: bool, | |
| 8 | z_nocopyreloc: bool, | |
| 9 | z_now: bool, | |
| 10 | z_relro: bool, | |
| 11 | /// TODO make this non optional and resolve the default in open() | |
| 12 | z_common_page_size: ?u64, | |
| 13 | /// TODO make this non optional and resolve the default in open() | |
| 14 | z_max_page_size: ?u64, | |
| 15 | lib_dirs: []const []const u8, | |
| 16 | hash_style: HashStyle, | |
| 17 | compress_debug_sections: CompressDebugSections, | |
| 18 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void), | |
| 19 | each_lib_rpath: bool, | |
| 20 | sort_section: ?SortSection, | |
| 21 | soname: ?[]const u8, | |
| 22 | bind_global_refs_locally: bool, | |
| 23 | linker_script: ?[]const u8, | |
| 24 | version_script: ?[]const u8, | |
| 25 | print_icf_sections: bool, | |
| 26 | print_map: bool, | |
| 27 | entry_name: ?[]const u8, | |
| 2 | 28 | |
| 3 | 29 | ptr_width: PtrWidth, |
| 4 | 30 | |
| 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. | |
| 6 | 32 | llvm_object: ?*LlvmObject = null, |
| 7 | 33 | |
| 8 | 34 | /// A list of all input files. |
| ... | ... | @@ -171,9 +197,6 @@ resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| 171 | 197 | has_text_reloc: bool = false, |
| 172 | 198 | num_ifunc_dynrelocs: usize = 0, |
| 173 | 199 | |
| 174 | error_flags: link.File.ErrorFlags = link.File.ErrorFlags{}, | |
| 175 | misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, | |
| 176 | ||
| 177 | 200 | /// List of atoms that are owned directly by the linker. |
| 178 | 201 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 179 | 202 | |
| ... | ... | @@ -199,59 +222,161 @@ const minimum_atom_size = 64; |
| 199 | 222 | pub const min_text_capacity = padToIdeal(minimum_atom_size); |
| 200 | 223 | |
| 201 | 224 | pub const PtrWidth = enum { p32, p64 }; |
| 225 | pub const HashStyle = enum { sysv, gnu, both }; | |
| 226 | pub const CompressDebugSections = enum { none, zlib, zstd }; | |
| 227 | pub const SortSection = enum { name, alignment }; | |
| 228 | ||
| 229 | pub 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 | }; | |
| 202 | 250 | |
| 203 | pub 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; | |
| 205 | 261 | |
| 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}); | |
| 208 | 271 | |
| 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, | |
| 211 | 291 | |
| 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 | }, | |
| 215 | 298 | |
| 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; | |
| 221 | 339 | } |
| 222 | errdefer if (self.base.intermediary_basename) |path| allocator.free(path); | |
| 223 | 340 | |
| 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, | |
| 226 | 350 | .read = true, |
| 227 | .mode = link.determineMode(options), | |
| 351 | .mode = link.File.determineMode(use_lld, output_mode, link_mode), | |
| 228 | 352 | }); |
| 229 | 353 | |
| 354 | const gpa = comp.gpa; | |
| 355 | ||
| 230 | 356 | // Index 0 is always a null symbol. |
| 231 | try self.symbols.append(allocator, .{}); | |
| 357 | try self.symbols.append(gpa, .{}); | |
| 232 | 358 | // Index 0 is always a null symbol. |
| 233 | try self.symbols_extra.append(allocator, 0); | |
| 359 | try self.symbols_extra.append(gpa, 0); | |
| 234 | 360 | // Allocate atom index 0 to null atom |
| 235 | try self.atoms.append(allocator, .{}); | |
| 361 | try self.atoms.append(gpa, .{}); | |
| 236 | 362 | // Append null file at index 0 |
| 237 | try self.files.append(allocator, .null); | |
| 363 | try self.files.append(gpa, .null); | |
| 238 | 364 | // 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); | |
| 241 | 367 | // There must always be a null shdr in index 0 |
| 242 | 368 | _ = try self.addSection(.{ .name = "" }); |
| 243 | 369 | // Append null symbol in output symtab |
| 244 | try self.symtab.append(allocator, null_sym); | |
| 370 | try self.symtab.append(gpa, null_sym); | |
| 245 | 371 | |
| 246 | 372 | if (!is_obj_or_ar) { |
| 247 | try self.dynstrtab.append(allocator, 0); | |
| 373 | try self.dynstrtab.append(gpa, 0); | |
| 248 | 374 | |
| 249 | 375 | // Initialize PT_PHDR program header |
| 250 | 376 | const p_align: u16 = switch (self.ptr_width) { |
| 251 | 377 | .p32 => @alignOf(elf.Elf32_Phdr), |
| 252 | 378 | .p64 => @alignOf(elf.Elf64_Phdr), |
| 253 | 379 | }; |
| 254 | const image_base = self.calcImageBase(); | |
| 255 | 380 | const ehsize: u64 = switch (self.ptr_width) { |
| 256 | 381 | .p32 => @sizeOf(elf.Elf32_Ehdr), |
| 257 | 382 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| ... | ... | @@ -266,7 +391,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 266 | 391 | .type = elf.PT_PHDR, |
| 267 | 392 | .flags = elf.PF_R, |
| 268 | 393 | .@"align" = p_align, |
| 269 | .addr = image_base + ehsize, | |
| 394 | .addr = self.image_base + ehsize, | |
| 270 | 395 | .offset = ehsize, |
| 271 | 396 | .filesz = reserved, |
| 272 | 397 | .memsz = reserved, |
| ... | ... | @@ -275,71 +400,49 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 275 | 400 | .type = elf.PT_LOAD, |
| 276 | 401 | .flags = elf.PF_R, |
| 277 | 402 | .@"align" = self.page_size, |
| 278 | .addr = image_base, | |
| 403 | .addr = self.image_base, | |
| 279 | 404 | .offset = 0, |
| 280 | 405 | .filesz = reserved + ehsize, |
| 281 | 406 | .memsz = reserved + ehsize, |
| 282 | 407 | }); |
| 283 | 408 | } |
| 284 | 409 | |
| 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 | } | |
| 296 | 426 | } |
| 297 | 427 | |
| 298 | 428 | return self; |
| 299 | 429 | } |
| 300 | 430 | |
| 301 | pub 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; | |
| 431 | pub 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); | |
| 337 | 440 | } |
| 338 | 441 | |
| 339 | 442 | pub fn deinit(self: *Elf) void { |
| 340 | const gpa = self.base.allocator; | |
| 443 | const gpa = self.base.comp.gpa; | |
| 341 | 444 | |
| 342 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); | |
| 445 | if (self.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 343 | 446 | |
| 344 | 447 | for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) { |
| 345 | 448 | .null => {}, |
| ... | ... | @@ -378,7 +481,6 @@ pub fn deinit(self: *Elf) void { |
| 378 | 481 | } |
| 379 | 482 | self.last_atom_and_free_list_table.deinit(gpa); |
| 380 | 483 | |
| 381 | self.misc_errors.deinit(gpa); | |
| 382 | 484 | self.comdat_groups.deinit(gpa); |
| 383 | 485 | self.comdat_groups_owners.deinit(gpa); |
| 384 | 486 | self.comdat_groups_table.deinit(gpa); |
| ... | ... | @@ -494,17 +596,23 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 { |
| 494 | 596 | return start; |
| 495 | 597 | } |
| 496 | 598 | |
| 599 | pub const InitMetadataOptions = struct { | |
| 600 | symbol_count_hint: u64, | |
| 601 | program_code_size_hint: u64, | |
| 602 | }; | |
| 603 | ||
| 497 | 604 | /// TODO move to ZigObject |
| 498 | pub fn initMetadata(self: *Elf) !void { | |
| 499 | const gpa = self.base.allocator; | |
| 605 | pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | |
| 606 | const gpa = self.base.comp.gpa; | |
| 500 | 607 | 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; | |
| 503 | 611 | const zig_object = self.zigObjectPtr().?; |
| 504 | 612 | |
| 505 | 613 | const fillSection = struct { |
| 506 | 614 | 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()) { | |
| 508 | 616 | const off = elf_file.findFreeSpace(size, shdr.sh_addralign); |
| 509 | 617 | shdr.sh_offset = off; |
| 510 | 618 | shdr.sh_size = size; |
| ... | ... | @@ -519,9 +627,9 @@ pub fn initMetadata(self: *Elf) !void { |
| 519 | 627 | |
| 520 | 628 | comptime assert(number_of_zig_segments == 5); |
| 521 | 629 | |
| 522 | if (!self.isRelocatable()) { | |
| 630 | if (!self.base.isRelocatable()) { | |
| 523 | 631 | 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; | |
| 525 | 633 | const off = self.findFreeSpace(filesz, self.page_size); |
| 526 | 634 | self.phdr_zig_load_re_index = try self.addPhdr(.{ |
| 527 | 635 | .type = elf.PT_LOAD, |
| ... | ... | @@ -538,7 +646,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 538 | 646 | // We really only need ptr alignment but since we are using PROGBITS, linux requires |
| 539 | 647 | // page align. |
| 540 | 648 | 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; | |
| 542 | 650 | const off = self.findFreeSpace(filesz, alignment); |
| 543 | 651 | self.phdr_zig_got_index = try self.addPhdr(.{ |
| 544 | 652 | .type = elf.PT_LOAD, |
| ... | ... | @@ -602,8 +710,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 602 | 710 | .offset = std.math.maxInt(u64), |
| 603 | 711 | }); |
| 604 | 712 | 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()) { | |
| 607 | 715 | const rela_shndx = try self.addRelaShdr(".rela.text.zig", self.zig_text_section_index.?); |
| 608 | 716 | try self.output_rela_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{ |
| 609 | 717 | .shndx = rela_shndx, |
| ... | ... | @@ -619,7 +727,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 619 | 727 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); |
| 620 | 728 | } |
| 621 | 729 | |
| 622 | if (self.zig_got_section_index == null and !self.isRelocatable()) { | |
| 730 | if (self.zig_got_section_index == null and !self.base.isRelocatable()) { | |
| 623 | 731 | self.zig_got_section_index = try self.addSection(.{ |
| 624 | 732 | .name = ".got.zig", |
| 625 | 733 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -650,7 +758,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 650 | 758 | }); |
| 651 | 759 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; |
| 652 | 760 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); |
| 653 | if (self.isRelocatable()) { | |
| 761 | if (self.base.isRelocatable()) { | |
| 654 | 762 | const rela_shndx = try self.addRelaShdr( |
| 655 | 763 | ".rela.data.rel.ro.zig", |
| 656 | 764 | self.zig_data_rel_ro_section_index.?, |
| ... | ... | @@ -679,7 +787,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 679 | 787 | }); |
| 680 | 788 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; |
| 681 | 789 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); |
| 682 | if (self.isRelocatable()) { | |
| 790 | if (self.base.isRelocatable()) { | |
| 683 | 791 | const rela_shndx = try self.addRelaShdr( |
| 684 | 792 | ".rela.data.zig", |
| 685 | 793 | self.zig_data_section_index.?, |
| ... | ... | @@ -918,56 +1026,47 @@ pub fn markDirty(self: *Elf, shdr_index: u16) void { |
| 918 | 1026 | } |
| 919 | 1027 | } |
| 920 | 1028 | |
| 921 | pub 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; | |
| 1029 | pub 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; | |
| 929 | 1031 | if (use_lld) { |
| 930 | return self.linkWithLLD(comp, prog_node); | |
| 1032 | return self.linkWithLLD(arena, prog_node); | |
| 931 | 1033 | } |
| 932 | try self.flushModule(comp, prog_node); | |
| 1034 | try self.flushModule(arena, prog_node); | |
| 933 | 1035 | } |
| 934 | 1036 | |
| 935 | pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 1037 | pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 936 | 1038 | const tracy = trace(@src()); |
| 937 | 1039 | defer tracy.end(); |
| 938 | 1040 | |
| 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; | |
| 941 | 1043 | |
| 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; | |
| 943 | 1047 | if (use_lld) return; |
| 944 | 1048 | } |
| 945 | 1049 | |
| 946 | const gpa = self.base.allocator; | |
| 947 | 1050 | var sub_prog_node = prog_node.start("ELF Flush", 0); |
| 948 | 1051 | sub_prog_node.activate(); |
| 949 | 1052 | defer sub_prog_node.end(); |
| 950 | 1053 | |
| 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: { | |
| 959 | 1059 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 960 | 1060 | break :blk try fs.path.join(arena, &.{ dirname, path }); |
| 961 | 1061 | } else { |
| 962 | 1062 | break :blk path; |
| 963 | 1063 | } |
| 964 | 1064 | } else null; |
| 965 | const gc_sections = self.base.options.gc_sections orelse false; | |
| 966 | 1065 | |
| 967 | 1066 | // --verbose-link |
| 968 | if (self.base.options.verbose_link) try self.dumpArgv(comp); | |
| 1067 | if (comp.verbose_link) try self.dumpArgv(comp); | |
| 969 | 1068 | |
| 970 | const csu = try CsuObjects.init(arena, self.base.options, comp); | |
| 1069 | const csu = try CsuObjects.init(arena, comp); | |
| 971 | 1070 | const compiler_rt_path: ?[]const u8 = blk: { |
| 972 | 1071 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 973 | 1072 | 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 |
| 975 | 1074 | }; |
| 976 | 1075 | |
| 977 | 1076 | 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); | |
| 980 | 1079 | |
| 981 | 1080 | // Here we will parse input positional and library files (if referenced). |
| 982 | 1081 | // 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 |
| 987 | 1086 | if (csu.crti) |v| try positionals.append(.{ .path = v }); |
| 988 | 1087 | if (csu.crtbegin) |v| try positionals.append(.{ .path = v }); |
| 989 | 1088 | |
| 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); | |
| 992 | 1091 | |
| 993 | 1092 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 994 | 1093 | // 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 |
| 1000 | 1099 | if (module_obj_path) |path| try positionals.append(.{ .path = path }); |
| 1001 | 1100 | |
| 1002 | 1101 | // rpaths |
| 1003 | var rpath_table = std.StringArrayHashMap(void).init(self.base.allocator); | |
| 1102 | var rpath_table = std.StringArrayHashMap(void).init(gpa); | |
| 1004 | 1103 | defer rpath_table.deinit(); |
| 1005 | 1104 | |
| 1006 | for (self.base.options.rpath_list) |rpath| { | |
| 1105 | for (self.base.rpath_list) |rpath| { | |
| 1007 | 1106 | _ = try rpath_table.put(rpath, {}); |
| 1008 | 1107 | } |
| 1009 | 1108 | |
| 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); | |
| 1012 | 1111 | 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| { | |
| 1015 | 1114 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) |
| 1016 | 1115 | continue; |
| 1017 | 1116 | _ = try rpath_table.put(lib_dir_path, {}); |
| 1018 | 1117 | } |
| 1019 | 1118 | } |
| 1020 | for (self.base.options.objects) |obj| { | |
| 1119 | for (comp.objects) |obj| { | |
| 1021 | 1120 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 1022 | 1121 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 1023 | 1122 | if (obj.loption) continue; |
| ... | ... | @@ -1027,14 +1126,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1027 | 1126 | } |
| 1028 | 1127 | |
| 1029 | 1128 | // TSAN |
| 1030 | if (self.base.options.tsan) { | |
| 1129 | if (comp.config.any_sanitize_thread) { | |
| 1031 | 1130 | try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path }); |
| 1032 | 1131 | } |
| 1033 | 1132 | |
| 1034 | 1133 | // 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) { | |
| 1038 | 1135 | if (comp.libc_static_lib) |lib| { |
| 1039 | 1136 | try positionals.append(.{ .path = lib.full_object_path }); |
| 1040 | 1137 | } |
| ... | ... | @@ -1053,27 +1150,27 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1053 | 1150 | |
| 1054 | 1151 | var system_libs = std.ArrayList(SystemLib).init(arena); |
| 1055 | 1152 | |
| 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| { | |
| 1058 | 1155 | system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? }); |
| 1059 | 1156 | } |
| 1060 | 1157 | |
| 1061 | 1158 | // libc++ dep |
| 1062 | if (self.base.options.link_libcpp) { | |
| 1159 | if (comp.config.link_libcpp) { | |
| 1063 | 1160 | try system_libs.ensureUnusedCapacity(2); |
| 1064 | 1161 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path }); |
| 1065 | 1162 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path }); |
| 1066 | 1163 | } |
| 1067 | 1164 | |
| 1068 | 1165 | // libunwind dep |
| 1069 | if (self.base.options.link_libunwind) { | |
| 1166 | if (comp.config.link_libunwind) { | |
| 1070 | 1167 | try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path }); |
| 1071 | 1168 | } |
| 1072 | 1169 | |
| 1073 | 1170 | // 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| { | |
| 1077 | 1174 | const flags = target_util.libcFullLinkFlags(target); |
| 1078 | 1175 | try system_libs.ensureUnusedCapacity(flags.len); |
| 1079 | 1176 | |
| ... | ... | @@ -1085,7 +1182,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1085 | 1182 | const lib_name = flag["-l".len..]; |
| 1086 | 1183 | |
| 1087 | 1184 | success: { |
| 1088 | if (!self.isStatic()) { | |
| 1185 | if (!self.base.isStatic()) { | |
| 1089 | 1186 | if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Dynamic)) |
| 1090 | 1187 | break :success; |
| 1091 | 1188 | } |
| ... | ... | @@ -1116,13 +1213,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1116 | 1213 | .path = try comp.get_libc_crt_file(arena, "libc_nonshared.a"), |
| 1117 | 1214 | }); |
| 1118 | 1215 | } 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) { | |
| 1120 | 1217 | .Static => "libc.a", |
| 1121 | 1218 | .Dynamic => "libc.so", |
| 1122 | 1219 | }); |
| 1123 | 1220 | try system_libs.append(.{ .path = path }); |
| 1124 | 1221 | } else { |
| 1125 | self.error_flags.missing_libc = true; | |
| 1222 | comp.link_error_flags.missing_libc = true; | |
| 1126 | 1223 | } |
| 1127 | 1224 | } |
| 1128 | 1225 | |
| ... | ... | @@ -1160,7 +1257,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1160 | 1257 | }; |
| 1161 | 1258 | } |
| 1162 | 1259 | |
| 1163 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1260 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1164 | 1261 | |
| 1165 | 1262 | // Init all objects |
| 1166 | 1263 | for (self.objects.items) |index| { |
| ... | ... | @@ -1170,7 +1267,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1170 | 1267 | try self.file(index).?.shared_object.init(self); |
| 1171 | 1268 | } |
| 1172 | 1269 | |
| 1173 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1270 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1174 | 1271 | |
| 1175 | 1272 | // Dedup shared objects |
| 1176 | 1273 | { |
| ... | ... | @@ -1211,18 +1308,15 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1211 | 1308 | |
| 1212 | 1309 | // Look for entry address in objects if not set by the incremental compiler. |
| 1213 | 1310 | 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 | } | |
| 1220 | 1314 | } |
| 1221 | 1315 | |
| 1222 | if (gc_sections) { | |
| 1316 | if (self.base.gc_sections) { | |
| 1223 | 1317 | try gc.gcAtoms(self); |
| 1224 | 1318 | |
| 1225 | if (self.base.options.print_gc_sections) { | |
| 1319 | if (self.base.print_gc_sections) { | |
| 1226 | 1320 | try gc.dumpPrunedAtoms(self); |
| 1227 | 1321 | } |
| 1228 | 1322 | } |
| ... | ... | @@ -1290,26 +1384,26 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1290 | 1384 | try self.writeAtoms(); |
| 1291 | 1385 | try self.writeSyntheticSections(); |
| 1292 | 1386 | |
| 1293 | if (self.entry_index == null and self.isExe()) { | |
| 1387 | if (self.entry_index == null and self.base.isExe()) { | |
| 1294 | 1388 | 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; | |
| 1296 | 1390 | } else { |
| 1297 | 1391 | 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; | |
| 1299 | 1393 | try self.writeElfHeader(); |
| 1300 | 1394 | } |
| 1301 | 1395 | |
| 1302 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1396 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1303 | 1397 | } |
| 1304 | 1398 | |
| 1305 | 1399 | pub 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; | |
| 1307 | 1401 | |
| 1308 | 1402 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 1309 | 1403 | defer positionals.deinit(); |
| 1310 | 1404 | |
| 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); | |
| 1313 | 1407 | |
| 1314 | 1408 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 1315 | 1409 | // 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 |
| 1331 | 1425 | }; |
| 1332 | 1426 | } |
| 1333 | 1427 | |
| 1334 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1428 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1335 | 1429 | |
| 1336 | 1430 | // First, we flush relocatable object file generated with our backends. |
| 1337 | 1431 | if (self.zigObjectPtr()) |zig_object| { |
| ... | ... | @@ -1443,16 +1537,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 1443 | 1537 | try self.base.file.?.setEndPos(total_size); |
| 1444 | 1538 | try self.base.file.?.pwriteAll(buffer.items, 0); |
| 1445 | 1539 | |
| 1446 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1540 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1447 | 1541 | } |
| 1448 | 1542 | |
| 1449 | 1543 | pub 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; | |
| 1451 | 1545 | |
| 1452 | 1546 | var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 1453 | 1547 | 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); | |
| 1456 | 1550 | |
| 1457 | 1551 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 1458 | 1552 | // 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) |
| 1474 | 1568 | }; |
| 1475 | 1569 | } |
| 1476 | 1570 | |
| 1477 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1571 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1478 | 1572 | |
| 1479 | 1573 | // Init all objects |
| 1480 | 1574 | for (self.objects.items) |index| { |
| 1481 | 1575 | try self.file(index).?.object.init(self); |
| 1482 | 1576 | } |
| 1483 | 1577 | |
| 1484 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1578 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1485 | 1579 | |
| 1486 | 1580 | // Now, we are ready to resolve the symbols across all input files. |
| 1487 | 1581 | // 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) |
| 1515 | 1609 | try self.writeShdrTable(); |
| 1516 | 1610 | try self.writeElfHeader(); |
| 1517 | 1611 | |
| 1518 | if (self.misc_errors.items.len > 0) return error.FlushFailure; | |
| 1612 | if (comp.link_errors.items.len > 0) return error.FlushFailure; | |
| 1519 | 1613 | } |
| 1520 | 1614 | |
| 1521 | 1615 | /// --verbose-link output |
| 1522 | 1616 | fn 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); | |
| 1524 | 1619 | defer arena_allocator.deinit(); |
| 1525 | 1620 | const arena = arena_allocator.allocator(); |
| 1526 | 1621 | |
| 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: { | |
| 1531 | 1627 | if (fs.path.dirname(full_out_path)) |dirname| { |
| 1532 | 1628 | break :blk try fs.path.join(arena, &.{ dirname, path }); |
| 1533 | 1629 | } else { |
| 1534 | 1630 | break :blk path; |
| 1535 | 1631 | } |
| 1536 | 1632 | } else null; |
| 1537 | const gc_sections = self.base.options.gc_sections orelse false; | |
| 1538 | 1633 | |
| 1539 | const csu = try CsuObjects.init(arena, self.base.options, comp); | |
| 1634 | const csu = try CsuObjects.init(arena, comp); | |
| 1540 | 1635 | const compiler_rt_path: ?[]const u8 = blk: { |
| 1541 | 1636 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 1542 | 1637 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| ... | ... | @@ -1547,21 +1642,21 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1547 | 1642 | |
| 1548 | 1643 | try argv.append("zig"); |
| 1549 | 1644 | |
| 1550 | if (self.isStaticLib()) { | |
| 1645 | if (self.base.isStaticLib()) { | |
| 1551 | 1646 | try argv.append("ar"); |
| 1552 | 1647 | } else { |
| 1553 | 1648 | try argv.append("ld"); |
| 1554 | 1649 | } |
| 1555 | 1650 | |
| 1556 | if (self.isObject()) { | |
| 1651 | if (self.base.isObject()) { | |
| 1557 | 1652 | try argv.append("-r"); |
| 1558 | 1653 | } |
| 1559 | 1654 | |
| 1560 | 1655 | try argv.append("-o"); |
| 1561 | 1656 | try argv.append(full_out_path); |
| 1562 | 1657 | |
| 1563 | if (self.isRelocatable()) { | |
| 1564 | for (self.base.options.objects) |obj| { | |
| 1658 | if (self.base.isRelocatable()) { | |
| 1659 | for (comp.objects) |obj| { | |
| 1565 | 1660 | try argv.append(obj.path); |
| 1566 | 1661 | } |
| 1567 | 1662 | |
| ... | ... | @@ -1573,36 +1668,35 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1573 | 1668 | try argv.append(p); |
| 1574 | 1669 | } |
| 1575 | 1670 | } 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| { | |
| 1578 | 1673 | try argv.append("-dynamic-linker"); |
| 1579 | 1674 | try argv.append(path); |
| 1580 | 1675 | } |
| 1581 | 1676 | } |
| 1582 | 1677 | |
| 1583 | if (self.isDynLib()) { | |
| 1584 | if (self.base.options.soname) |name| { | |
| 1678 | if (self.base.isDynLib()) { | |
| 1679 | if (self.soname) |name| { | |
| 1585 | 1680 | try argv.append("-soname"); |
| 1586 | 1681 | try argv.append(name); |
| 1587 | 1682 | } |
| 1588 | 1683 | } |
| 1589 | 1684 | |
| 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 }); | |
| 1593 | 1687 | } |
| 1594 | 1688 | |
| 1595 | for (self.base.options.rpath_list) |rpath| { | |
| 1689 | for (self.base.rpath_list) |rpath| { | |
| 1596 | 1690 | try argv.append("-rpath"); |
| 1597 | 1691 | try argv.append(rpath); |
| 1598 | 1692 | } |
| 1599 | 1693 | |
| 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| { | |
| 1602 | 1696 | try argv.append("-rpath"); |
| 1603 | 1697 | try argv.append(lib_dir_path); |
| 1604 | 1698 | } |
| 1605 | for (self.base.options.objects) |obj| { | |
| 1699 | for (comp.objects) |obj| { | |
| 1606 | 1700 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 1607 | 1701 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 1608 | 1702 | if (obj.loption) continue; |
| ... | ... | @@ -1613,57 +1707,55 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1613 | 1707 | } |
| 1614 | 1708 | } |
| 1615 | 1709 | |
| 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 | }); | |
| 1620 | 1714 | |
| 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})); | |
| 1624 | 1716 | |
| 1625 | if (gc_sections) { | |
| 1717 | if (self.base.gc_sections) { | |
| 1626 | 1718 | try argv.append("--gc-sections"); |
| 1627 | 1719 | } |
| 1628 | 1720 | |
| 1629 | if (self.base.options.print_gc_sections) { | |
| 1721 | if (self.base.print_gc_sections) { | |
| 1630 | 1722 | try argv.append("--print-gc-sections"); |
| 1631 | 1723 | } |
| 1632 | 1724 | |
| 1633 | if (self.base.options.eh_frame_hdr) { | |
| 1725 | if (comp.link_eh_frame_hdr) { | |
| 1634 | 1726 | try argv.append("--eh-frame-hdr"); |
| 1635 | 1727 | } |
| 1636 | 1728 | |
| 1637 | if (self.base.options.rdynamic) { | |
| 1729 | if (comp.config.rdynamic) { | |
| 1638 | 1730 | try argv.append("--export-dynamic"); |
| 1639 | 1731 | } |
| 1640 | 1732 | |
| 1641 | if (self.base.options.z_notext) { | |
| 1733 | if (self.z_notext) { | |
| 1642 | 1734 | try argv.append("-z"); |
| 1643 | 1735 | try argv.append("notext"); |
| 1644 | 1736 | } |
| 1645 | 1737 | |
| 1646 | if (self.base.options.z_nocopyreloc) { | |
| 1738 | if (self.z_nocopyreloc) { | |
| 1647 | 1739 | try argv.append("-z"); |
| 1648 | 1740 | try argv.append("nocopyreloc"); |
| 1649 | 1741 | } |
| 1650 | 1742 | |
| 1651 | if (self.base.options.z_now) { | |
| 1743 | if (self.z_now) { | |
| 1652 | 1744 | try argv.append("-z"); |
| 1653 | 1745 | try argv.append("now"); |
| 1654 | 1746 | } |
| 1655 | 1747 | |
| 1656 | if (self.isStatic()) { | |
| 1748 | if (self.base.isStatic()) { | |
| 1657 | 1749 | try argv.append("-static"); |
| 1658 | } else if (self.isDynLib()) { | |
| 1750 | } else if (self.base.isDynLib()) { | |
| 1659 | 1751 | try argv.append("-shared"); |
| 1660 | 1752 | } |
| 1661 | 1753 | |
| 1662 | if (self.base.options.pie and self.isExe()) { | |
| 1754 | if (comp.config.pie and self.base.isExe()) { | |
| 1663 | 1755 | try argv.append("-pie"); |
| 1664 | 1756 | } |
| 1665 | 1757 | |
| 1666 | if (self.base.options.strip) { | |
| 1758 | if (comp.config.debug_format == .strip) { | |
| 1667 | 1759 | try argv.append("-s"); |
| 1668 | 1760 | } |
| 1669 | 1761 | |
| ... | ... | @@ -1672,20 +1764,20 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1672 | 1764 | if (csu.crti) |v| try argv.append(v); |
| 1673 | 1765 | if (csu.crtbegin) |v| try argv.append(v); |
| 1674 | 1766 | |
| 1675 | for (self.base.options.lib_dirs) |lib_dir| { | |
| 1767 | for (self.lib_dirs) |lib_dir| { | |
| 1676 | 1768 | try argv.append("-L"); |
| 1677 | 1769 | try argv.append(lib_dir); |
| 1678 | 1770 | } |
| 1679 | 1771 | |
| 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| { | |
| 1682 | 1774 | try argv.append("-L"); |
| 1683 | 1775 | try argv.append(libc_installation.crt_dir.?); |
| 1684 | 1776 | } |
| 1685 | 1777 | } |
| 1686 | 1778 | |
| 1687 | 1779 | var whole_archive = false; |
| 1688 | for (self.base.options.objects) |obj| { | |
| 1780 | for (comp.objects) |obj| { | |
| 1689 | 1781 | if (obj.must_link and !whole_archive) { |
| 1690 | 1782 | try argv.append("-whole-archive"); |
| 1691 | 1783 | whole_archive = true; |
| ... | ... | @@ -1713,15 +1805,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1713 | 1805 | try argv.append(p); |
| 1714 | 1806 | } |
| 1715 | 1807 | |
| 1716 | // TSAN | |
| 1717 | if (self.base.options.tsan) { | |
| 1808 | if (comp.config.any_sanitize_thread) { | |
| 1718 | 1809 | try argv.append(comp.tsan_static_lib.?.full_object_path); |
| 1719 | 1810 | } |
| 1720 | 1811 | |
| 1721 | 1812 | // 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) { | |
| 1725 | 1814 | if (comp.libc_static_lib) |lib| { |
| 1726 | 1815 | try argv.append(lib.full_object_path); |
| 1727 | 1816 | } |
| ... | ... | @@ -1730,11 +1819,11 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1730 | 1819 | // Shared libraries. |
| 1731 | 1820 | // Worst-case, we need an --as-needed argument for every lib, as well |
| 1732 | 1821 | // 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); | |
| 1734 | 1823 | argv.appendAssumeCapacity("--as-needed"); |
| 1735 | 1824 | var as_needed = true; |
| 1736 | 1825 | |
| 1737 | for (self.base.options.system_libs.values()) |lib_info| { | |
| 1826 | for (self.base.comp.system_libs.values()) |lib_info| { | |
| 1738 | 1827 | const lib_as_needed = !lib_info.needed; |
| 1739 | 1828 | switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) { |
| 1740 | 1829 | 0b00, 0b11 => {}, |
| ... | ... | @@ -1756,20 +1845,20 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1756 | 1845 | } |
| 1757 | 1846 | |
| 1758 | 1847 | // libc++ dep |
| 1759 | if (self.base.options.link_libcpp) { | |
| 1848 | if (comp.config.link_libcpp) { | |
| 1760 | 1849 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 1761 | 1850 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 1762 | 1851 | } |
| 1763 | 1852 | |
| 1764 | 1853 | // libunwind dep |
| 1765 | if (self.base.options.link_libunwind) { | |
| 1854 | if (comp.config.link_libunwind) { | |
| 1766 | 1855 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 1767 | 1856 | } |
| 1768 | 1857 | |
| 1769 | 1858 | // 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; | |
| 1773 | 1862 | if (needs_grouping) try argv.append("--start-group"); |
| 1774 | 1863 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); |
| 1775 | 1864 | if (needs_grouping) try argv.append("--end-group"); |
| ... | ... | @@ -1782,7 +1871,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1782 | 1871 | } |
| 1783 | 1872 | try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a")); |
| 1784 | 1873 | } 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) { | |
| 1786 | 1875 | .Static => "libc.a", |
| 1787 | 1876 | .Dynamic => "libc.so", |
| 1788 | 1877 | })); |
| ... | ... | @@ -1842,7 +1931,7 @@ fn parseObject(self: *Elf, path: []const u8) ParseError!void { |
| 1842 | 1931 | const tracy = trace(@src()); |
| 1843 | 1932 | defer tracy.end(); |
| 1844 | 1933 | |
| 1845 | const gpa = self.base.allocator; | |
| 1934 | const gpa = self.base.comp.gpa; | |
| 1846 | 1935 | const in_file = try std.fs.cwd().openFile(path, .{}); |
| 1847 | 1936 | defer in_file.close(); |
| 1848 | 1937 | 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 { |
| 1862 | 1951 | const tracy = trace(@src()); |
| 1863 | 1952 | defer tracy.end(); |
| 1864 | 1953 | |
| 1865 | const gpa = self.base.allocator; | |
| 1954 | const gpa = self.base.comp.gpa; | |
| 1866 | 1955 | const in_file = try std.fs.cwd().openFile(path, .{}); |
| 1867 | 1956 | defer in_file.close(); |
| 1868 | 1957 | const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32)); |
| ... | ... | @@ -1888,7 +1977,7 @@ fn parseSharedObject(self: *Elf, lib: SystemLib) ParseError!void { |
| 1888 | 1977 | const tracy = trace(@src()); |
| 1889 | 1978 | defer tracy.end(); |
| 1890 | 1979 | |
| 1891 | const gpa = self.base.allocator; | |
| 1980 | const gpa = self.base.comp.gpa; | |
| 1892 | 1981 | const in_file = try std.fs.cwd().openFile(lib.path, .{}); |
| 1893 | 1982 | defer in_file.close(); |
| 1894 | 1983 | const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32)); |
| ... | ... | @@ -1910,7 +1999,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1910 | 1999 | const tracy = trace(@src()); |
| 1911 | 2000 | defer tracy.end(); |
| 1912 | 2001 | |
| 1913 | const gpa = self.base.allocator; | |
| 2002 | const gpa = self.base.comp.gpa; | |
| 1914 | 2003 | const in_file = try std.fs.cwd().openFile(lib.path, .{}); |
| 1915 | 2004 | defer in_file.close(); |
| 1916 | 2005 | const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32)); |
| ... | ... | @@ -1920,8 +2009,6 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1920 | 2009 | defer script.deinit(gpa); |
| 1921 | 2010 | try script.parse(data, self); |
| 1922 | 2011 | |
| 1923 | const lib_dirs = self.base.options.lib_dirs; | |
| 1924 | ||
| 1925 | 2012 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 1926 | 2013 | defer arena_allocator.deinit(); |
| 1927 | 2014 | const arena = arena_allocator.allocator(); |
| ... | ... | @@ -1938,8 +2025,8 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1938 | 2025 | |
| 1939 | 2026 | // TODO I think technically we should re-use the mechanism used by the frontend here. |
| 1940 | 2027 | // 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()) { | |
| 1943 | 2030 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Dynamic)) |
| 1944 | 2031 | break :success; |
| 1945 | 2032 | } |
| ... | ... | @@ -1955,7 +2042,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 1955 | 2042 | } else |_| {} |
| 1956 | 2043 | |
| 1957 | 2044 | try checked_paths.append(try gpa.dupe(u8, scr_obj.path)); |
| 1958 | for (lib_dirs) |lib_dir| { | |
| 2045 | for (self.lib_dirs) |lib_dir| { | |
| 1959 | 2046 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null)) |
| 1960 | 2047 | break :success; |
| 1961 | 2048 | } |
| ... | ... | @@ -1995,8 +2082,9 @@ fn accessLibPath( |
| 1995 | 2082 | lib_name: []const u8, |
| 1996 | 2083 | link_mode: ?std.builtin.LinkMode, |
| 1997 | 2084 | ) !bool { |
| 2085 | const gpa = self.base.comp.gpa; | |
| 1998 | 2086 | const sep = fs.path.sep_str; |
| 1999 | const target = self.base.options.target; | |
| 2087 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 2000 | 2088 | test_path.clearRetainingCapacity(); |
| 2001 | 2089 | const prefix = if (link_mode != null) "lib" else ""; |
| 2002 | 2090 | const suffix = if (link_mode) |mode| switch (mode) { |
| ... | ... | @@ -2010,7 +2098,7 @@ fn accessLibPath( |
| 2010 | 2098 | suffix, |
| 2011 | 2099 | }); |
| 2012 | 2100 | 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)); | |
| 2014 | 2102 | } |
| 2015 | 2103 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| 2016 | 2104 | error.FileNotFound => return false, |
| ... | ... | @@ -2139,7 +2227,7 @@ fn markImportsExports(self: *Elf) void { |
| 2139 | 2227 | } |
| 2140 | 2228 | if (file_ptr.index() == file_index) { |
| 2141 | 2229 | global.flags.@"export" = true; |
| 2142 | if (elf_file.isDynLib() and vis != .PROTECTED) { | |
| 2230 | if (elf_file.base.isDynLib() and vis != .PROTECTED) { | |
| 2143 | 2231 | global.flags.import = true; |
| 2144 | 2232 | } |
| 2145 | 2233 | } |
| ... | ... | @@ -2147,7 +2235,7 @@ fn markImportsExports(self: *Elf) void { |
| 2147 | 2235 | } |
| 2148 | 2236 | }.mark; |
| 2149 | 2237 | |
| 2150 | if (!self.isDynLib()) { | |
| 2238 | if (!self.base.isDynLib()) { | |
| 2151 | 2239 | for (self.shared_objects.items) |index| { |
| 2152 | 2240 | for (self.file(index).?.globals()) |global_index| { |
| 2153 | 2241 | const global = self.symbol(global_index); |
| ... | ... | @@ -2190,7 +2278,7 @@ fn claimUnresolvedObject(self: *Elf) void { |
| 2190 | 2278 | /// This is also the point where we will report undefined symbols for any |
| 2191 | 2279 | /// alloc sections. |
| 2192 | 2280 | fn scanRelocs(self: *Elf) !void { |
| 2193 | const gpa = self.base.allocator; | |
| 2281 | const gpa = self.base.comp.gpa; | |
| 2194 | 2282 | |
| 2195 | 2283 | var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Atom.Index)).init(gpa); |
| 2196 | 2284 | defer { |
| ... | ... | @@ -2259,26 +2347,25 @@ fn scanRelocs(self: *Elf) !void { |
| 2259 | 2347 | } |
| 2260 | 2348 | } |
| 2261 | 2349 | |
| 2262 | fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 2350 | fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !void { | |
| 2263 | 2351 | const tracy = trace(@src()); |
| 2264 | 2352 | defer tracy.end(); |
| 2265 | 2353 | |
| 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; | |
| 2269 | 2356 | |
| 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}); | |
| 2272 | 2359 | |
| 2273 | 2360 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 2274 | 2361 | // 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); | |
| 2277 | 2364 | |
| 2278 | 2365 | 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.? }); | |
| 2280 | 2367 | } else { |
| 2281 | break :blk self.base.intermediary_basename.?; | |
| 2368 | break :blk self.base.zcu_object_sub_path.?; | |
| 2282 | 2369 | } |
| 2283 | 2370 | } else null; |
| 2284 | 2371 | |
| ... | ... | @@ -2287,16 +2374,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2287 | 2374 | sub_prog_node.context.refresh(); |
| 2288 | 2375 | defer sub_prog_node.end(); |
| 2289 | 2376 | |
| 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; | |
| 2300 | 2386 | const compiler_rt_path: ?[]const u8 = blk: { |
| 2301 | 2387 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 2302 | 2388 | 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 |
| 2314 | 2400 | const id_symlink_basename = "lld.id"; |
| 2315 | 2401 | |
| 2316 | 2402 | 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(); | |
| 2318 | 2404 | |
| 2319 | 2405 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 2320 | 2406 | |
| 2321 | if (!self.base.options.disable_lld_caching) { | |
| 2407 | if (!self.base.disable_lld_caching) { | |
| 2322 | 2408 | man = comp.cache_parent.obtain(); |
| 2323 | 2409 | |
| 2324 | 2410 | // 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 |
| 2326 | 2412 | |
| 2327 | 2413 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 2328 | 2414 | |
| 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| { | |
| 2332 | 2418 | _ = try man.addFile(obj.path, null); |
| 2333 | 2419 | man.hash.add(obj.must_link); |
| 2334 | 2420 | man.hash.add(obj.loption); |
| ... | ... | @@ -2341,52 +2427,51 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2341 | 2427 | |
| 2342 | 2428 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 2343 | 2429 | // 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); | |
| 2370 | 2456 | // 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| { | |
| 2374 | 2460 | man.hash.addBytes(libc_installation.crt_dir.?); |
| 2375 | 2461 | } |
| 2376 | 2462 | if (have_dynamic_linker) { |
| 2377 | man.hash.addOptionalBytes(self.base.options.dynamic_linker); | |
| 2463 | man.hash.addOptionalBytes(target.dynamic_linker.get()); | |
| 2378 | 2464 | } |
| 2379 | 2465 | } |
| 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); | |
| 2390 | 2475 | |
| 2391 | 2476 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. |
| 2392 | 2477 | _ = try man.hit(); |
| ... | ... | @@ -2421,15 +2506,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2421 | 2506 | // copy when generating relocatables. Normally, we would expect `lld -r` to work. |
| 2422 | 2507 | // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails |
| 2423 | 2508 | // 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())) | |
| 2426 | 2511 | { |
| 2427 | 2512 | // In this case we must do a simple file copy |
| 2428 | 2513 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 2429 | 2514 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 2430 | 2515 | 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; | |
| 2433 | 2518 | |
| 2434 | 2519 | if (comp.c_object_table.count() != 0) |
| 2435 | 2520 | 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 |
| 2448 | 2533 | } |
| 2449 | 2534 | } else { |
| 2450 | 2535 | // 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); | |
| 2452 | 2537 | defer argv.deinit(); |
| 2453 | 2538 | // We will invoke ourselves as a child process to gain access to LLD. |
| 2454 | 2539 | // 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 |
| 2461 | 2546 | |
| 2462 | 2547 | try argv.append("--error-limit=0"); |
| 2463 | 2548 | |
| 2464 | if (self.base.options.sysroot) |sysroot| { | |
| 2549 | if (comp.sysroot) |sysroot| { | |
| 2465 | 2550 | try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot})); |
| 2466 | 2551 | } |
| 2467 | 2552 | |
| 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) { | |
| 2470 | 2555 | .Debug => {}, |
| 2471 | 2556 | .ReleaseSmall => try argv.append("--lto-O2"), |
| 2472 | 2557 | .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"), |
| 2473 | 2558 | } |
| 2474 | 2559 | } |
| 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 | } | |
| 2478 | 2565 | |
| 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 }); | |
| 2482 | 2568 | } |
| 2483 | 2569 | |
| 2484 | for (self.base.options.force_undefined_symbols.keys()) |sym| { | |
| 2570 | for (comp.force_undefined_symbols.keys()) |sym| { | |
| 2485 | 2571 | try argv.append("-u"); |
| 2486 | 2572 | try argv.append(sym); |
| 2487 | 2573 | } |
| 2488 | 2574 | |
| 2489 | switch (self.base.options.hash_style) { | |
| 2575 | switch (self.hash_style) { | |
| 2490 | 2576 | .gnu => try argv.append("--hash-style=gnu"), |
| 2491 | 2577 | .sysv => try argv.append("--hash-style=sysv"), |
| 2492 | 2578 | .both => {}, // this is the default |
| 2493 | 2579 | } |
| 2494 | 2580 | |
| 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 | }); | |
| 2498 | 2586 | |
| 2499 | switch (self.base.options.build_id) { | |
| 2587 | switch (self.base.build_id) { | |
| 2500 | 2588 | .none => {}, |
| 2501 | 2589 | .fast, .uuid, .sha1, .md5 => { |
| 2502 | 2590 | try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{ |
| 2503 | @tagName(self.base.options.build_id), | |
| 2591 | @tagName(self.base.build_id), | |
| 2504 | 2592 | })); |
| 2505 | 2593 | }, |
| 2506 | 2594 | .hexstring => |hs| { |
| ... | ... | @@ -2511,85 +2599,83 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2511 | 2599 | } |
| 2512 | 2600 | } |
| 2513 | 2601 | |
| 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})); | |
| 2517 | 2603 | |
| 2518 | if (self.base.options.linker_script) |linker_script| { | |
| 2604 | if (self.linker_script) |linker_script| { | |
| 2519 | 2605 | try argv.append("-T"); |
| 2520 | 2606 | try argv.append(linker_script); |
| 2521 | 2607 | } |
| 2522 | 2608 | |
| 2523 | if (self.base.options.sort_section) |how| { | |
| 2609 | if (self.sort_section) |how| { | |
| 2524 | 2610 | const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)}); |
| 2525 | 2611 | try argv.append(arg); |
| 2526 | 2612 | } |
| 2527 | 2613 | |
| 2528 | if (gc_sections) { | |
| 2614 | if (self.base.gc_sections) { | |
| 2529 | 2615 | try argv.append("--gc-sections"); |
| 2530 | 2616 | } |
| 2531 | 2617 | |
| 2532 | if (self.base.options.print_gc_sections) { | |
| 2618 | if (self.base.print_gc_sections) { | |
| 2533 | 2619 | try argv.append("--print-gc-sections"); |
| 2534 | 2620 | } |
| 2535 | 2621 | |
| 2536 | if (self.base.options.print_icf_sections) { | |
| 2622 | if (self.print_icf_sections) { | |
| 2537 | 2623 | try argv.append("--print-icf-sections"); |
| 2538 | 2624 | } |
| 2539 | 2625 | |
| 2540 | if (self.base.options.print_map) { | |
| 2626 | if (self.print_map) { | |
| 2541 | 2627 | try argv.append("--print-map"); |
| 2542 | 2628 | } |
| 2543 | 2629 | |
| 2544 | if (self.base.options.eh_frame_hdr) { | |
| 2630 | if (comp.link_eh_frame_hdr) { | |
| 2545 | 2631 | try argv.append("--eh-frame-hdr"); |
| 2546 | 2632 | } |
| 2547 | 2633 | |
| 2548 | if (self.base.options.emit_relocs) { | |
| 2634 | if (self.emit_relocs) { | |
| 2549 | 2635 | try argv.append("--emit-relocs"); |
| 2550 | 2636 | } |
| 2551 | 2637 | |
| 2552 | if (self.base.options.rdynamic) { | |
| 2638 | if (comp.config.rdynamic) { | |
| 2553 | 2639 | try argv.append("--export-dynamic"); |
| 2554 | 2640 | } |
| 2555 | 2641 | |
| 2556 | if (self.base.options.strip) { | |
| 2642 | if (comp.config.debug_format == .strip) { | |
| 2557 | 2643 | try argv.append("-s"); |
| 2558 | 2644 | } |
| 2559 | 2645 | |
| 2560 | if (self.base.options.z_nodelete) { | |
| 2646 | if (self.z_nodelete) { | |
| 2561 | 2647 | try argv.append("-z"); |
| 2562 | 2648 | try argv.append("nodelete"); |
| 2563 | 2649 | } |
| 2564 | if (self.base.options.z_notext) { | |
| 2650 | if (self.z_notext) { | |
| 2565 | 2651 | try argv.append("-z"); |
| 2566 | 2652 | try argv.append("notext"); |
| 2567 | 2653 | } |
| 2568 | if (self.base.options.z_defs) { | |
| 2654 | if (self.z_defs) { | |
| 2569 | 2655 | try argv.append("-z"); |
| 2570 | 2656 | try argv.append("defs"); |
| 2571 | 2657 | } |
| 2572 | if (self.base.options.z_origin) { | |
| 2658 | if (self.z_origin) { | |
| 2573 | 2659 | try argv.append("-z"); |
| 2574 | 2660 | try argv.append("origin"); |
| 2575 | 2661 | } |
| 2576 | if (self.base.options.z_nocopyreloc) { | |
| 2662 | if (self.z_nocopyreloc) { | |
| 2577 | 2663 | try argv.append("-z"); |
| 2578 | 2664 | try argv.append("nocopyreloc"); |
| 2579 | 2665 | } |
| 2580 | if (self.base.options.z_now) { | |
| 2666 | if (self.z_now) { | |
| 2581 | 2667 | // LLD defaults to -zlazy |
| 2582 | 2668 | try argv.append("-znow"); |
| 2583 | 2669 | } |
| 2584 | if (!self.base.options.z_relro) { | |
| 2670 | if (!self.z_relro) { | |
| 2585 | 2671 | // LLD defaults to -zrelro |
| 2586 | 2672 | try argv.append("-znorelro"); |
| 2587 | 2673 | } |
| 2588 | if (self.base.options.z_common_page_size) |size| { | |
| 2674 | if (self.z_common_page_size) |size| { | |
| 2589 | 2675 | try argv.append("-z"); |
| 2590 | 2676 | try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size})); |
| 2591 | 2677 | } |
| 2592 | if (self.base.options.z_max_page_size) |size| { | |
| 2678 | if (self.z_max_page_size) |size| { | |
| 2593 | 2679 | try argv.append("-z"); |
| 2594 | 2680 | try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size})); |
| 2595 | 2681 | } |
| ... | ... | @@ -2604,7 +2690,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2604 | 2690 | try argv.append(arg); |
| 2605 | 2691 | } |
| 2606 | 2692 | |
| 2607 | if (self.base.options.link_mode == .Static) { | |
| 2693 | if (link_mode == .Static) { | |
| 2608 | 2694 | if (target.cpu.arch.isArmOrThumb()) { |
| 2609 | 2695 | try argv.append("-Bstatic"); |
| 2610 | 2696 | } else { |
| ... | ... | @@ -2614,7 +2700,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2614 | 2700 | try argv.append("-shared"); |
| 2615 | 2701 | } |
| 2616 | 2702 | |
| 2617 | if (self.base.options.pie and self.base.options.output_mode == .Exe) { | |
| 2703 | if (comp.config.pie and output_mode == .Exe) { | |
| 2618 | 2704 | try argv.append("-pie"); |
| 2619 | 2705 | } |
| 2620 | 2706 | |
| ... | ... | @@ -2631,29 +2717,29 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2631 | 2717 | try argv.append(full_out_path); |
| 2632 | 2718 | |
| 2633 | 2719 | // csu prelude |
| 2634 | const csu = try CsuObjects.init(arena, self.base.options, comp); | |
| 2720 | const csu = try CsuObjects.init(arena, comp); | |
| 2635 | 2721 | if (csu.crt0) |v| try argv.append(v); |
| 2636 | 2722 | if (csu.crti) |v| try argv.append(v); |
| 2637 | 2723 | if (csu.crtbegin) |v| try argv.append(v); |
| 2638 | 2724 | |
| 2639 | 2725 | // rpaths |
| 2640 | var rpath_table = std.StringHashMap(void).init(self.base.allocator); | |
| 2726 | var rpath_table = std.StringHashMap(void).init(gpa); | |
| 2641 | 2727 | defer rpath_table.deinit(); |
| 2642 | for (self.base.options.rpath_list) |rpath| { | |
| 2728 | for (self.base.rpath_list) |rpath| { | |
| 2643 | 2729 | if ((try rpath_table.fetchPut(rpath, {})) == null) { |
| 2644 | 2730 | try argv.append("-rpath"); |
| 2645 | 2731 | try argv.append(rpath); |
| 2646 | 2732 | } |
| 2647 | 2733 | } |
| 2648 | 2734 | |
| 2649 | for (self.base.options.symbol_wrap_set.keys()) |symbol_name| { | |
| 2735 | for (self.symbol_wrap_set.keys()) |symbol_name| { | |
| 2650 | 2736 | try argv.appendSlice(&.{ "-wrap", symbol_name }); |
| 2651 | 2737 | } |
| 2652 | 2738 | |
| 2653 | if (self.base.options.each_lib_rpath) { | |
| 2739 | if (self.each_lib_rpath) { | |
| 2654 | 2740 | 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| { | |
| 2657 | 2743 | if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic))) |
| 2658 | 2744 | continue; |
| 2659 | 2745 | 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 |
| 2662 | 2748 | } |
| 2663 | 2749 | } |
| 2664 | 2750 | } |
| 2665 | for (self.base.options.objects) |obj| { | |
| 2751 | for (comp.objects) |obj| { | |
| 2666 | 2752 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 2667 | 2753 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 2668 | 2754 | if (obj.loption) continue; |
| ... | ... | @@ -2675,19 +2761,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2675 | 2761 | } |
| 2676 | 2762 | } |
| 2677 | 2763 | |
| 2678 | for (self.base.options.lib_dirs) |lib_dir| { | |
| 2764 | for (self.lib_dirs) |lib_dir| { | |
| 2679 | 2765 | try argv.append("-L"); |
| 2680 | 2766 | try argv.append(lib_dir); |
| 2681 | 2767 | } |
| 2682 | 2768 | |
| 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| { | |
| 2685 | 2771 | try argv.append("-L"); |
| 2686 | 2772 | try argv.append(libc_installation.crt_dir.?); |
| 2687 | 2773 | } |
| 2688 | 2774 | |
| 2689 | 2775 | if (have_dynamic_linker) { |
| 2690 | if (self.base.options.dynamic_linker) |dynamic_linker| { | |
| 2776 | if (target.dynamic_linker.get()) |dynamic_linker| { | |
| 2691 | 2777 | try argv.append("-dynamic-linker"); |
| 2692 | 2778 | try argv.append(dynamic_linker); |
| 2693 | 2779 | } |
| ... | ... | @@ -2695,11 +2781,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2695 | 2781 | } |
| 2696 | 2782 | |
| 2697 | 2783 | if (is_dyn_lib) { |
| 2698 | if (self.base.options.soname) |soname| { | |
| 2784 | if (self.soname) |soname| { | |
| 2699 | 2785 | try argv.append("-soname"); |
| 2700 | 2786 | try argv.append(soname); |
| 2701 | 2787 | } |
| 2702 | if (self.base.options.version_script) |version_script| { | |
| 2788 | if (self.version_script) |version_script| { | |
| 2703 | 2789 | try argv.append("-version-script"); |
| 2704 | 2790 | try argv.append(version_script); |
| 2705 | 2791 | } |
| ... | ... | @@ -2707,7 +2793,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2707 | 2793 | |
| 2708 | 2794 | // Positional arguments to the linker such as object files. |
| 2709 | 2795 | var whole_archive = false; |
| 2710 | for (self.base.options.objects) |obj| { | |
| 2796 | for (comp.objects) |obj| { | |
| 2711 | 2797 | if (obj.must_link and !whole_archive) { |
| 2712 | 2798 | try argv.append("-whole-archive"); |
| 2713 | 2799 | whole_archive = true; |
| ... | ... | @@ -2735,15 +2821,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2735 | 2821 | try argv.append(p); |
| 2736 | 2822 | } |
| 2737 | 2823 | |
| 2738 | // TSAN | |
| 2739 | if (self.base.options.tsan) { | |
| 2824 | if (comp.config.any_sanitize_thread) { | |
| 2740 | 2825 | try argv.append(comp.tsan_static_lib.?.full_object_path); |
| 2741 | 2826 | } |
| 2742 | 2827 | |
| 2743 | 2828 | // libc |
| 2744 | 2829 | 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) | |
| 2747 | 2832 | { |
| 2748 | 2833 | if (comp.libc_static_lib) |lib| { |
| 2749 | 2834 | try argv.append(lib.full_object_path); |
| ... | ... | @@ -2752,8 +2837,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2752 | 2837 | |
| 2753 | 2838 | // Shared libraries. |
| 2754 | 2839 | 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(); | |
| 2757 | 2842 | |
| 2758 | 2843 | // Worst-case, we need an --as-needed argument for every lib, as well |
| 2759 | 2844 | // as one before and one after. |
| ... | ... | @@ -2788,21 +2873,21 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2788 | 2873 | } |
| 2789 | 2874 | |
| 2790 | 2875 | // libc++ dep |
| 2791 | if (self.base.options.link_libcpp) { | |
| 2876 | if (comp.config.link_libcpp) { | |
| 2792 | 2877 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 2793 | 2878 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 2794 | 2879 | } |
| 2795 | 2880 | |
| 2796 | 2881 | // libunwind dep |
| 2797 | if (self.base.options.link_libunwind) { | |
| 2882 | if (comp.config.link_libunwind) { | |
| 2798 | 2883 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 2799 | 2884 | } |
| 2800 | 2885 | |
| 2801 | 2886 | // 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; | |
| 2806 | 2891 | if (needs_grouping) try argv.append("--start-group"); |
| 2807 | 2892 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); |
| 2808 | 2893 | if (needs_grouping) try argv.append("--end-group"); |
| ... | ... | @@ -2815,12 +2900,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2815 | 2900 | } |
| 2816 | 2901 | try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a")); |
| 2817 | 2902 | } 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) { | |
| 2819 | 2904 | .Static => "libc.a", |
| 2820 | 2905 | .Dynamic => "libc.so", |
| 2821 | 2906 | })); |
| 2822 | 2907 | } else { |
| 2823 | self.error_flags.missing_libc = true; | |
| 2908 | comp.link_error_flags.missing_libc = true; | |
| 2824 | 2909 | } |
| 2825 | 2910 | } |
| 2826 | 2911 | } |
| ... | ... | @@ -2836,21 +2921,21 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2836 | 2921 | if (csu.crtend) |v| try argv.append(v); |
| 2837 | 2922 | if (csu.crtn) |v| try argv.append(v); |
| 2838 | 2923 | |
| 2839 | if (allow_shlib_undefined) { | |
| 2924 | if (self.base.allow_shlib_undefined) { | |
| 2840 | 2925 | try argv.append("--allow-shlib-undefined"); |
| 2841 | 2926 | } |
| 2842 | 2927 | |
| 2843 | switch (self.base.options.compress_debug_sections) { | |
| 2928 | switch (self.compress_debug_sections) { | |
| 2844 | 2929 | .none => {}, |
| 2845 | 2930 | .zlib => try argv.append("--compress-debug-sections=zlib"), |
| 2846 | 2931 | .zstd => try argv.append("--compress-debug-sections=zstd"), |
| 2847 | 2932 | } |
| 2848 | 2933 | |
| 2849 | if (self.base.options.bind_global_refs_locally) { | |
| 2934 | if (self.bind_global_refs_locally) { | |
| 2850 | 2935 | try argv.append("-Bsymbolic"); |
| 2851 | 2936 | } |
| 2852 | 2937 | |
| 2853 | if (self.base.options.verbose_link) { | |
| 2938 | if (comp.verbose_link) { | |
| 2854 | 2939 | // Skip over our own name so that the LLD linker name is the first argv item. |
| 2855 | 2940 | Compilation.dump_argv(argv.items[1..]); |
| 2856 | 2941 | } |
| ... | ... | @@ -2920,7 +3005,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2920 | 3005 | } |
| 2921 | 3006 | } |
| 2922 | 3007 | |
| 2923 | if (!self.base.options.disable_lld_caching) { | |
| 3008 | if (!self.base.disable_lld_caching) { | |
| 2924 | 3009 | // Update the file with the digest. If it fails we can continue; it only |
| 2925 | 3010 | // means that the next invocation will have an unnecessary cache miss. |
| 2926 | 3011 | 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 |
| 2937 | 3022 | } |
| 2938 | 3023 | |
| 2939 | 3024 | fn 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(); | |
| 2941 | 3027 | switch (self.ptr_width) { |
| 2942 | 3028 | .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(addr)), target_endian), |
| 2943 | 3029 | .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian), |
| ... | ... | @@ -2945,8 +3031,9 @@ fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) |
| 2945 | 3031 | } |
| 2946 | 3032 | |
| 2947 | 3033 | fn 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(); | |
| 2950 | 3037 | const foreign_endian = target_endian != builtin.cpu.arch.endian(); |
| 2951 | 3038 | const shsize: u64 = switch (self.ptr_width) { |
| 2952 | 3039 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| ... | ... | @@ -3001,8 +3088,9 @@ fn writeShdrTable(self: *Elf) !void { |
| 3001 | 3088 | } |
| 3002 | 3089 | |
| 3003 | 3090 | fn 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(); | |
| 3006 | 3094 | const foreign_endian = target_endian != builtin.cpu.arch.endian(); |
| 3007 | 3095 | const phdr_table = &self.phdrs.items[self.phdr_table_index.?]; |
| 3008 | 3096 | |
| ... | ... | @@ -3040,7 +3128,8 @@ fn writePhdrTable(self: *Elf) !void { |
| 3040 | 3128 | } |
| 3041 | 3129 | |
| 3042 | 3130 | fn 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 | |
| 3044 | 3133 | |
| 3045 | 3134 | var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined; |
| 3046 | 3135 | |
| ... | ... | @@ -3054,7 +3143,8 @@ fn writeElfHeader(self: *Elf) !void { |
| 3054 | 3143 | }; |
| 3055 | 3144 | index += 1; |
| 3056 | 3145 | |
| 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(); | |
| 3058 | 3148 | hdr_buf[index] = switch (endian) { |
| 3059 | 3149 | .little => elf.ELFDATA2LSB, |
| 3060 | 3150 | .big => elf.ELFDATA2MSB, |
| ... | ... | @@ -3072,10 +3162,12 @@ fn writeElfHeader(self: *Elf) !void { |
| 3072 | 3162 | |
| 3073 | 3163 | assert(index == 16); |
| 3074 | 3164 | |
| 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, | |
| 3077 | 3169 | .Obj => .REL, |
| 3078 | .Lib => switch (self.base.options.link_mode) { | |
| 3170 | .Lib => switch (link_mode) { | |
| 3079 | 3171 | .Static => @as(elf.ET, .REL), |
| 3080 | 3172 | .Dynamic => .DYN, |
| 3081 | 3173 | }, |
| ... | ... | @@ -3083,7 +3175,7 @@ fn writeElfHeader(self: *Elf) !void { |
| 3083 | 3175 | mem.writeInt(u16, hdr_buf[index..][0..2], @intFromEnum(elf_type), endian); |
| 3084 | 3176 | index += 2; |
| 3085 | 3177 | |
| 3086 | const machine = self.base.options.target.cpu.arch.toElfMachine(); | |
| 3178 | const machine = target.cpu.arch.toElfMachine(); | |
| 3087 | 3179 | mem.writeInt(u16, hdr_buf[index..][0..2], @intFromEnum(machine), endian); |
| 3088 | 3180 | index += 2; |
| 3089 | 3181 | |
| ... | ... | @@ -3201,7 +3293,6 @@ pub fn updateExports( |
| 3201 | 3293 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 3202 | 3294 | } |
| 3203 | 3295 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports); |
| 3204 | if (self.base.options.emit == null) return; | |
| 3205 | 3296 | return self.zigObjectPtr().?.updateExports(self, mod, exported, exports); |
| 3206 | 3297 | } |
| 3207 | 3298 | |
| ... | ... | @@ -3220,6 +3311,9 @@ pub fn deleteDeclExport( |
| 3220 | 3311 | } |
| 3221 | 3312 | |
| 3222 | 3313 | fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3314 | const comp = self.base.comp; | |
| 3315 | const gpa = comp.gpa; | |
| 3316 | ||
| 3223 | 3317 | const linker_defined_index = self.linker_defined_index orelse return; |
| 3224 | 3318 | const linker_defined = self.file(linker_defined_index).?.linker_defined; |
| 3225 | 3319 | self.dynamic_index = try linker_defined.addGlobal("_DYNAMIC", self); |
| ... | ... | @@ -3234,7 +3328,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3234 | 3328 | self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self); |
| 3235 | 3329 | self.end_index = try linker_defined.addGlobal("_end", self); |
| 3236 | 3330 | |
| 3237 | if (self.base.options.eh_frame_hdr) { | |
| 3331 | if (comp.link_eh_frame_hdr) { | |
| 3238 | 3332 | self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self); |
| 3239 | 3333 | } |
| 3240 | 3334 | |
| ... | ... | @@ -3248,7 +3342,6 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3248 | 3342 | |
| 3249 | 3343 | for (self.shdrs.items) |shdr| { |
| 3250 | 3344 | if (self.getStartStopBasename(shdr)) |name| { |
| 3251 | const gpa = self.base.allocator; | |
| 3252 | 3345 | try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2); |
| 3253 | 3346 | |
| 3254 | 3347 | const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| ... | ... | @@ -3265,6 +3358,9 @@ fn addLinkerDefinedSymbols(self: *Elf) !void { |
| 3265 | 3358 | } |
| 3266 | 3359 | |
| 3267 | 3360 | fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3361 | const comp = self.base.comp; | |
| 3362 | const link_mode = comp.config.link_mode; | |
| 3363 | ||
| 3268 | 3364 | // _DYNAMIC |
| 3269 | 3365 | if (self.dynamic_section_index) |shndx| { |
| 3270 | 3366 | const shdr = &self.shdrs.items[shndx]; |
| ... | ... | @@ -3276,7 +3372,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3276 | 3372 | // __ehdr_start |
| 3277 | 3373 | { |
| 3278 | 3374 | const symbol_ptr = self.symbol(self.ehdr_start_index.?); |
| 3279 | symbol_ptr.value = self.calcImageBase(); | |
| 3375 | symbol_ptr.value = self.image_base; | |
| 3280 | 3376 | symbol_ptr.output_section_index = 1; |
| 3281 | 3377 | } |
| 3282 | 3378 | |
| ... | ... | @@ -3347,7 +3443,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3347 | 3443 | |
| 3348 | 3444 | // __rela_iplt_start, __rela_iplt_end |
| 3349 | 3445 | 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; | |
| 3351 | 3447 | const shdr = &self.shdrs.items[shndx]; |
| 3352 | 3448 | const end_addr = shdr.sh_addr + shdr.sh_size; |
| 3353 | 3449 | const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); |
| ... | ... | @@ -3394,6 +3490,8 @@ fn initOutputSections(self: *Elf) !void { |
| 3394 | 3490 | } |
| 3395 | 3491 | |
| 3396 | 3492 | fn initSyntheticSections(self: *Elf) !void { |
| 3493 | const comp = self.base.comp; | |
| 3494 | const target = comp.root_mod.resolved_target.result; | |
| 3397 | 3495 | const ptr_size = self.ptrWidthBytes(); |
| 3398 | 3496 | |
| 3399 | 3497 | const needs_eh_frame = for (self.objects.items) |index| { |
| ... | ... | @@ -3408,7 +3506,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3408 | 3506 | .offset = std.math.maxInt(u64), |
| 3409 | 3507 | }); |
| 3410 | 3508 | |
| 3411 | if (self.base.options.eh_frame_hdr) { | |
| 3509 | if (comp.link_eh_frame_hdr) { | |
| 3412 | 3510 | self.eh_frame_hdr_section_index = try self.addSection(.{ |
| 3413 | 3511 | .name = ".eh_frame_hdr", |
| 3414 | 3512 | .type = elf.SHT_PROGBITS, |
| ... | ... | @@ -3502,8 +3600,8 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3502 | 3600 | // In this case, if we do generate .interp section and segment, we will get |
| 3503 | 3601 | // a segfault in the dynamic linker trying to load a binary that is static |
| 3504 | 3602 | // 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; | |
| 3507 | 3605 | }; |
| 3508 | 3606 | if (needs_interp) { |
| 3509 | 3607 | self.interp_section_index = try self.addSection(.{ |
| ... | ... | @@ -3515,7 +3613,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3515 | 3613 | }); |
| 3516 | 3614 | } |
| 3517 | 3615 | |
| 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) { | |
| 3519 | 3617 | self.dynstrtab_section_index = try self.addSection(.{ |
| 3520 | 3618 | .name = ".dynstr", |
| 3521 | 3619 | .flags = elf.SHF_ALLOC, |
| ... | ... | @@ -3613,7 +3711,7 @@ fn initSectionsObject(self: *Elf) !void { |
| 3613 | 3711 | } |
| 3614 | 3712 | |
| 3615 | 3713 | fn initComdatGroups(self: *Elf) !void { |
| 3616 | const gpa = self.base.allocator; | |
| 3714 | const gpa = self.base.comp.gpa; | |
| 3617 | 3715 | |
| 3618 | 3716 | for (self.objects.items) |index| { |
| 3619 | 3717 | const object = self.file(index).?.object; |
| ... | ... | @@ -3700,7 +3798,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3700 | 3798 | self.phdr_gnu_stack_index = try self.addPhdr(.{ |
| 3701 | 3799 | .type = elf.PT_GNU_STACK, |
| 3702 | 3800 | .flags = elf.PF_W | elf.PF_R, |
| 3703 | .memsz = self.base.options.stack_size_override orelse 0, | |
| 3801 | .memsz = self.base.stack_size, | |
| 3704 | 3802 | .@"align" = 1, |
| 3705 | 3803 | }); |
| 3706 | 3804 | |
| ... | ... | @@ -3732,7 +3830,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3732 | 3830 | /// Ties are broken by the file prority which corresponds to the inclusion of input sections in this output section |
| 3733 | 3831 | /// we are about to sort. |
| 3734 | 3832 | fn sortInitFini(self: *Elf) !void { |
| 3735 | const gpa = self.base.allocator; | |
| 3833 | const gpa = self.base.comp.gpa; | |
| 3736 | 3834 | |
| 3737 | 3835 | const Entry = struct { |
| 3738 | 3836 | priority: i32, |
| ... | ... | @@ -3806,8 +3904,8 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void { |
| 3806 | 3904 | try self.dynamic.addNeeded(shared_object, self); |
| 3807 | 3905 | } |
| 3808 | 3906 | |
| 3809 | if (self.isDynLib()) { | |
| 3810 | if (self.base.options.soname) |soname| { | |
| 3907 | if (self.base.isDynLib()) { | |
| 3908 | if (self.soname) |soname| { | |
| 3811 | 3909 | try self.dynamic.setSoname(soname, self); |
| 3812 | 3910 | } |
| 3813 | 3911 | } |
| ... | ... | @@ -3821,8 +3919,9 @@ fn sortDynamicSymtab(self: *Elf) void { |
| 3821 | 3919 | } |
| 3822 | 3920 | |
| 3823 | 3921 | fn setVersionSymtab(self: *Elf) !void { |
| 3922 | const gpa = self.base.comp.gpa; | |
| 3824 | 3923 | 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()); | |
| 3826 | 3925 | self.versym.items[0] = elf.VER_NDX_LOCAL; |
| 3827 | 3926 | for (self.dynsym.entries.items, 1..) |entry, i| { |
| 3828 | 3927 | const sym = self.symbol(entry.symbol_index); |
| ... | ... | @@ -3872,7 +3971,7 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 3872 | 3971 | } |
| 3873 | 3972 | }; |
| 3874 | 3973 | |
| 3875 | const gpa = self.base.allocator; | |
| 3974 | const gpa = self.base.comp.gpa; | |
| 3876 | 3975 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.phdrs.items.len); |
| 3877 | 3976 | defer entries.deinit(); |
| 3878 | 3977 | for (0..self.phdrs.items.len) |phndx| { |
| ... | ... | @@ -3977,7 +4076,7 @@ fn sortShdrs(self: *Elf) !void { |
| 3977 | 4076 | } |
| 3978 | 4077 | }; |
| 3979 | 4078 | |
| 3980 | const gpa = self.base.allocator; | |
| 4079 | const gpa = self.base.comp.gpa; | |
| 3981 | 4080 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len); |
| 3982 | 4081 | defer entries.deinit(); |
| 3983 | 4082 | for (0..self.shdrs.items.len) |shndx| { |
| ... | ... | @@ -4004,7 +4103,7 @@ fn sortShdrs(self: *Elf) !void { |
| 4004 | 4103 | } |
| 4005 | 4104 | |
| 4006 | 4105 | fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void { |
| 4007 | const gpa = self.base.allocator; | |
| 4106 | const gpa = self.base.comp.gpa; | |
| 4008 | 4107 | |
| 4009 | 4108 | for (&[_]*?u16{ |
| 4010 | 4109 | &self.eh_frame_section_index, |
| ... | ... | @@ -4187,6 +4286,7 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void { |
| 4187 | 4286 | } |
| 4188 | 4287 | |
| 4189 | 4288 | fn updateSectionSizes(self: *Elf) !void { |
| 4289 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4190 | 4290 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 4191 | 4291 | const shdr = &self.shdrs.items[shndx]; |
| 4192 | 4292 | for (atom_list.items) |atom_index| { |
| ... | ... | @@ -4244,7 +4344,7 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4244 | 4344 | } |
| 4245 | 4345 | |
| 4246 | 4346 | 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; | |
| 4248 | 4348 | } |
| 4249 | 4349 | |
| 4250 | 4350 | if (self.hash_section_index) |index| { |
| ... | ... | @@ -4453,7 +4553,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4453 | 4553 | // as we are more interested in quick turnaround and compatibility |
| 4454 | 4554 | // with `findFreeSpace` mechanics than anything else. |
| 4455 | 4555 | const Cover = std.ArrayList(u16); |
| 4456 | const gpa = self.base.allocator; | |
| 4556 | const gpa = self.base.comp.gpa; | |
| 4457 | 4557 | var covers: [max_number_of_object_segments]Cover = undefined; |
| 4458 | 4558 | for (&covers) |*cover| { |
| 4459 | 4559 | cover.* = Cover.init(gpa); |
| ... | ... | @@ -4691,7 +4791,7 @@ fn allocateAtoms(self: *Elf) void { |
| 4691 | 4791 | } |
| 4692 | 4792 | |
| 4693 | 4793 | fn writeAtoms(self: *Elf) !void { |
| 4694 | const gpa = self.base.allocator; | |
| 4794 | const gpa = self.base.comp.gpa; | |
| 4695 | 4795 | |
| 4696 | 4796 | var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Atom.Index)).init(gpa); |
| 4697 | 4797 | defer { |
| ... | ... | @@ -4779,7 +4879,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4779 | 4879 | } |
| 4780 | 4880 | |
| 4781 | 4881 | fn writeAtomsObject(self: *Elf) !void { |
| 4782 | const gpa = self.base.allocator; | |
| 4882 | const gpa = self.base.comp.gpa; | |
| 4783 | 4883 | |
| 4784 | 4884 | // TODO iterate over `output_sections` directly |
| 4785 | 4885 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| ... | ... | @@ -4852,7 +4952,7 @@ fn updateSymtabSize(self: *Elf) !void { |
| 4852 | 4952 | var nglobals: u32 = 0; |
| 4853 | 4953 | var strsize: u32 = 0; |
| 4854 | 4954 | |
| 4855 | const gpa = self.base.allocator; | |
| 4955 | const gpa = self.base.comp.gpa; | |
| 4856 | 4956 | var files = std.ArrayList(File.Index).init(gpa); |
| 4857 | 4957 | defer files.deinit(); |
| 4858 | 4958 | try files.ensureTotalCapacityPrecise(self.objects.items.len + self.shared_objects.items.len + 2); |
| ... | ... | @@ -4935,17 +5035,18 @@ fn updateSymtabSize(self: *Elf) !void { |
| 4935 | 5035 | } |
| 4936 | 5036 | |
| 4937 | 5037 | fn 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; | |
| 4939 | 5040 | |
| 4940 | 5041 | 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]; | |
| 4941 | 5047 | 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); | |
| 4949 | 5050 | } |
| 4950 | 5051 | |
| 4951 | 5052 | if (self.hash_section_index) |shndx| { |
| ... | ... | @@ -5065,7 +5166,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 5065 | 5166 | } |
| 5066 | 5167 | |
| 5067 | 5168 | fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5068 | const gpa = self.base.allocator; | |
| 5169 | const gpa = self.base.comp.gpa; | |
| 5069 | 5170 | |
| 5070 | 5171 | for (self.output_rela_sections.values()) |sec| { |
| 5071 | 5172 | if (sec.atom_list.items.len == 0) continue; |
| ... | ... | @@ -5135,7 +5236,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5135 | 5236 | } |
| 5136 | 5237 | |
| 5137 | 5238 | fn writeComdatGroups(self: *Elf) !void { |
| 5138 | const gpa = self.base.allocator; | |
| 5239 | const gpa = self.base.comp.gpa; | |
| 5139 | 5240 | for (self.comdat_group_sections.items) |cgs| { |
| 5140 | 5241 | const shdr = self.shdrs.items[cgs.shndx]; |
| 5141 | 5242 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| ... | ... | @@ -5160,7 +5261,8 @@ fn writeShStrtab(self: *Elf) !void { |
| 5160 | 5261 | } |
| 5161 | 5262 | |
| 5162 | 5263 | fn 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; | |
| 5164 | 5266 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; |
| 5165 | 5267 | const strtab_shdr = self.shdrs.items[self.strtab_section_index.?]; |
| 5166 | 5268 | const sym_size: u64 = switch (self.ptr_width) { |
| ... | ... | @@ -5220,7 +5322,7 @@ fn writeSymtab(self: *Elf) !void { |
| 5220 | 5322 | self.plt_got.writeSymtab(self); |
| 5221 | 5323 | } |
| 5222 | 5324 | |
| 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(); | |
| 5224 | 5326 | switch (self.ptr_width) { |
| 5225 | 5327 | .p32 => { |
| 5226 | 5328 | const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len); |
| ... | ... | @@ -5299,7 +5401,8 @@ fn ptrWidthBytes(self: Elf) u8 { |
| 5299 | 5401 | /// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes |
| 5300 | 5402 | /// in a 32-bit ELF file. |
| 5301 | 5403 | pub 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)); | |
| 5303 | 5406 | } |
| 5304 | 5407 | |
| 5305 | 5408 | fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { |
| ... | ... | @@ -5393,9 +5496,11 @@ const CsuObjects = struct { |
| 5393 | 5496 | crtend: ?[]const u8 = null, |
| 5394 | 5497 | crtn: ?[]const u8 = null, |
| 5395 | 5498 | |
| 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 { | |
| 5397 | 5502 | // crt objects are only required for libc. |
| 5398 | if (!link_options.link_libc) return CsuObjects{}; | |
| 5503 | if (!comp.config.link_libc) return .{}; | |
| 5399 | 5504 | |
| 5400 | 5505 | var result: CsuObjects = .{}; |
| 5401 | 5506 | |
| ... | ... | @@ -5406,19 +5511,21 @@ const CsuObjects = struct { |
| 5406 | 5511 | dynamic_pie, |
| 5407 | 5512 | static_exe, |
| 5408 | 5513 | static_pie, |
| 5409 | } = switch (link_options.output_mode) { | |
| 5514 | } = switch (comp.config.output_mode) { | |
| 5410 | 5515 | .Obj => return CsuObjects{}, |
| 5411 | .Lib => switch (link_options.link_mode) { | |
| 5516 | .Lib => switch (comp.config.link_mode) { | |
| 5412 | 5517 | .Dynamic => .dynamic_lib, |
| 5413 | 5518 | .Static => return CsuObjects{}, |
| 5414 | 5519 | }, |
| 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, | |
| 5418 | 5523 | }, |
| 5419 | 5524 | }; |
| 5420 | 5525 | |
| 5421 | if (link_options.target.isAndroid()) { | |
| 5526 | const target = comp.root_mod.resolved_target.result; | |
| 5527 | ||
| 5528 | if (target.isAndroid()) { | |
| 5422 | 5529 | switch (mode) { |
| 5423 | 5530 | // zig fmt: off |
| 5424 | 5531 | .dynamic_lib => result.set( null, null, "crtbegin_so.o", "crtend_so.o", null ), |
| ... | ... | @@ -5429,7 +5536,7 @@ const CsuObjects = struct { |
| 5429 | 5536 | // zig fmt: on |
| 5430 | 5537 | } |
| 5431 | 5538 | } else { |
| 5432 | switch (link_options.target.os.tag) { | |
| 5539 | switch (target.os.tag) { | |
| 5433 | 5540 | .linux => { |
| 5434 | 5541 | switch (mode) { |
| 5435 | 5542 | // zig fmt: off |
| ... | ... | @@ -5440,7 +5547,7 @@ const CsuObjects = struct { |
| 5440 | 5547 | .static_pie => result.set( "rcrt1.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), |
| 5441 | 5548 | // zig fmt: on |
| 5442 | 5549 | } |
| 5443 | if (link_options.libc_installation) |_| { | |
| 5550 | if (comp.libc_installation) |_| { | |
| 5444 | 5551 | // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs |
| 5445 | 5552 | // and they are not known at comptime. For now null-out crtbegin/end objects; |
| 5446 | 5553 | // there is no feature loss, zig has never linked those objects in before. |
| ... | ... | @@ -5448,7 +5555,7 @@ const CsuObjects = struct { |
| 5448 | 5555 | result.crtend = null; |
| 5449 | 5556 | } else { |
| 5450 | 5557 | // 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"; | |
| 5452 | 5559 | } |
| 5453 | 5560 | }, |
| 5454 | 5561 | .dragonfly => switch (mode) { |
| ... | ... | @@ -5510,16 +5617,16 @@ const CsuObjects = struct { |
| 5510 | 5617 | } |
| 5511 | 5618 | |
| 5512 | 5619 | // Convert each object to a full pathname. |
| 5513 | if (link_options.libc_installation) |lci| { | |
| 5620 | if (comp.libc_installation) |lci| { | |
| 5514 | 5621 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir; |
| 5515 | switch (link_options.target.os.tag) { | |
| 5622 | switch (target.os.tag) { | |
| 5516 | 5623 | .dragonfly => { |
| 5517 | 5624 | if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5518 | 5625 | if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5519 | 5626 | if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5520 | 5627 | |
| 5521 | 5628 | 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) { | |
| 5523 | 5630 | gccv = "gcc80"; |
| 5524 | 5631 | } else { |
| 5525 | 5632 | gccv = "gcc54"; |
| ... | ... | @@ -5576,39 +5683,6 @@ const CsuObjects = struct { |
| 5576 | 5683 | } |
| 5577 | 5684 | }; |
| 5578 | 5685 | |
| 5579 | pub 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 | ||
| 5588 | pub fn isStatic(self: Elf) bool { | |
| 5589 | return self.base.options.link_mode == .Static; | |
| 5590 | } | |
| 5591 | ||
| 5592 | pub fn isObject(self: Elf) bool { | |
| 5593 | return self.base.options.output_mode == .Obj; | |
| 5594 | } | |
| 5595 | ||
| 5596 | pub fn isExe(self: Elf) bool { | |
| 5597 | return self.base.options.output_mode == .Exe; | |
| 5598 | } | |
| 5599 | ||
| 5600 | pub fn isStaticLib(self: Elf) bool { | |
| 5601 | return self.base.options.output_mode == .Lib and self.isStatic(); | |
| 5602 | } | |
| 5603 | ||
| 5604 | pub fn isRelocatable(self: Elf) bool { | |
| 5605 | return self.isObject() or self.isStaticLib(); | |
| 5606 | } | |
| 5607 | ||
| 5608 | pub fn isDynLib(self: Elf) bool { | |
| 5609 | return self.base.options.output_mode == .Lib and !self.isStatic(); | |
| 5610 | } | |
| 5611 | ||
| 5612 | 5686 | pub fn isZigSection(self: Elf, shndx: u16) bool { |
| 5613 | 5687 | inline for (&[_]?u16{ |
| 5614 | 5688 | self.zig_text_section_index, |
| ... | ... | @@ -5648,8 +5722,9 @@ fn addPhdr(self: *Elf, opts: struct { |
| 5648 | 5722 | filesz: u64 = 0, |
| 5649 | 5723 | memsz: u64 = 0, |
| 5650 | 5724 | }) error{OutOfMemory}!u16 { |
| 5725 | const gpa = self.base.comp.gpa; | |
| 5651 | 5726 | const index = @as(u16, @intCast(self.phdrs.items.len)); |
| 5652 | try self.phdrs.append(self.base.allocator, .{ | |
| 5727 | try self.phdrs.append(gpa, .{ | |
| 5653 | 5728 | .p_type = opts.type, |
| 5654 | 5729 | .p_flags = opts.flags, |
| 5655 | 5730 | .p_offset = opts.offset, |
| ... | ... | @@ -5694,7 +5769,7 @@ pub const AddSectionOpts = struct { |
| 5694 | 5769 | }; |
| 5695 | 5770 | |
| 5696 | 5771 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { |
| 5697 | const gpa = self.base.allocator; | |
| 5772 | const gpa = self.base.comp.gpa; | |
| 5698 | 5773 | const index = @as(u16, @intCast(self.shdrs.items.len)); |
| 5699 | 5774 | const shdr = try self.shdrs.addOne(gpa); |
| 5700 | 5775 | shdr.* = .{ |
| ... | ... | @@ -5798,8 +5873,9 @@ pub fn atom(self: *Elf, atom_index: Atom.Index) ?*Atom { |
| 5798 | 5873 | } |
| 5799 | 5874 | |
| 5800 | 5875 | pub fn addAtom(self: *Elf) !Atom.Index { |
| 5876 | const gpa = self.base.comp.gpa; | |
| 5801 | 5877 | 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); | |
| 5803 | 5879 | atom_ptr.* = .{ .atom_index = index }; |
| 5804 | 5880 | return index; |
| 5805 | 5881 | } |
| ... | ... | @@ -5821,14 +5897,15 @@ pub fn symbol(self: *Elf, sym_index: Symbol.Index) *Symbol { |
| 5821 | 5897 | } |
| 5822 | 5898 | |
| 5823 | 5899 | pub 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); | |
| 5825 | 5902 | const index = blk: { |
| 5826 | 5903 | if (self.symbols_free_list.popOrNull()) |index| { |
| 5827 | 5904 | log.debug(" (reusing symbol index {d})", .{index}); |
| 5828 | 5905 | break :blk index; |
| 5829 | 5906 | } else { |
| 5830 | 5907 | 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); | |
| 5832 | 5909 | _ = self.symbols.addOneAssumeCapacity(); |
| 5833 | 5910 | break :blk index; |
| 5834 | 5911 | } |
| ... | ... | @@ -5838,8 +5915,9 @@ pub fn addSymbol(self: *Elf) !Symbol.Index { |
| 5838 | 5915 | } |
| 5839 | 5916 | |
| 5840 | 5917 | pub fn addSymbolExtra(self: *Elf, extra: Symbol.Extra) !u32 { |
| 5918 | const gpa = self.base.comp.gpa; | |
| 5841 | 5919 | 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); | |
| 5843 | 5921 | return self.addSymbolExtraAssumeCapacity(extra); |
| 5844 | 5922 | } |
| 5845 | 5923 | |
| ... | ... | @@ -5887,11 +5965,12 @@ const GetOrPutGlobalResult = struct { |
| 5887 | 5965 | }; |
| 5888 | 5966 | |
| 5889 | 5967 | pub fn getOrPutGlobal(self: *Elf, name: []const u8) !GetOrPutGlobalResult { |
| 5890 | const gpa = self.base.allocator; | |
| 5968 | const gpa = self.base.comp.gpa; | |
| 5891 | 5969 | const name_off = try self.strings.insert(gpa, name); |
| 5892 | 5970 | const gop = try self.resolver.getOrPut(gpa, name_off); |
| 5893 | 5971 | if (!gop.found_existing) { |
| 5894 | 5972 | const index = try self.addSymbol(); |
| 5973 | log.debug("added symbol '{s}' at index {d}", .{ name, index }); | |
| 5895 | 5974 | const global = self.symbol(index); |
| 5896 | 5975 | global.name_offset = name_off; |
| 5897 | 5976 | global.flags.global = true; |
| ... | ... | @@ -5923,11 +6002,11 @@ const GetOrCreateComdatGroupOwnerResult = struct { |
| 5923 | 6002 | }; |
| 5924 | 6003 | |
| 5925 | 6004 | pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateComdatGroupOwnerResult { |
| 5926 | const gpa = self.base.allocator; | |
| 6005 | const gpa = self.base.comp.gpa; | |
| 5927 | 6006 | const off = try self.strings.insert(gpa, name); |
| 5928 | 6007 | const gop = try self.comdat_groups_table.getOrPut(gpa, off); |
| 5929 | 6008 | 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); | |
| 5931 | 6010 | const owner = try self.comdat_groups_owners.addOne(gpa); |
| 5932 | 6011 | owner.* = .{}; |
| 5933 | 6012 | gop.value_ptr.* = index; |
| ... | ... | @@ -5939,8 +6018,9 @@ pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateC |
| 5939 | 6018 | } |
| 5940 | 6019 | |
| 5941 | 6020 | pub fn addComdatGroup(self: *Elf) !ComdatGroup.Index { |
| 6021 | const gpa = self.base.comp.gpa; | |
| 5942 | 6022 | 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); | |
| 5944 | 6024 | return index; |
| 5945 | 6025 | } |
| 5946 | 6026 | |
| ... | ... | @@ -5971,7 +6051,7 @@ pub fn tlsAddress(self: *Elf) u64 { |
| 5971 | 6051 | } |
| 5972 | 6052 | |
| 5973 | 6053 | const ErrorWithNotes = struct { |
| 5974 | /// Allocated index in misc_errors array. | |
| 6054 | /// Allocated index in comp.link_errors array. | |
| 5975 | 6055 | index: usize, |
| 5976 | 6056 | |
| 5977 | 6057 | /// Next available note slot. |
| ... | ... | @@ -5983,8 +6063,9 @@ const ErrorWithNotes = struct { |
| 5983 | 6063 | comptime format: []const u8, |
| 5984 | 6064 | args: anytype, |
| 5985 | 6065 | ) 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]; | |
| 5988 | 6069 | err_msg.msg = try std.fmt.allocPrint(gpa, format, args); |
| 5989 | 6070 | } |
| 5990 | 6071 | |
| ... | ... | @@ -5994,8 +6075,9 @@ const ErrorWithNotes = struct { |
| 5994 | 6075 | comptime format: []const u8, |
| 5995 | 6076 | args: anytype, |
| 5996 | 6077 | ) 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]; | |
| 5999 | 6081 | assert(err.note_slot < err_msg.notes.len); |
| 6000 | 6082 | err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) }; |
| 6001 | 6083 | err.note_slot += 1; |
| ... | ... | @@ -6003,14 +6085,18 @@ const ErrorWithNotes = struct { |
| 6003 | 6085 | }; |
| 6004 | 6086 | |
| 6005 | 6087 | pub 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); | |
| 6007 | 6091 | return self.addErrorWithNotesAssumeCapacity(note_count); |
| 6008 | 6092 | } |
| 6009 | 6093 | |
| 6010 | 6094 | fn 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) }; | |
| 6014 | 6100 | return .{ .index = index }; |
| 6015 | 6101 | } |
| 6016 | 6102 | |
| ... | ... | @@ -6020,9 +6106,10 @@ pub fn getShString(self: Elf, off: u32) [:0]const u8 { |
| 6020 | 6106 | } |
| 6021 | 6107 | |
| 6022 | 6108 | pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 { |
| 6109 | const gpa = self.base.comp.gpa; | |
| 6023 | 6110 | 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; | |
| 6026 | 6113 | return off; |
| 6027 | 6114 | } |
| 6028 | 6115 | |
| ... | ... | @@ -6032,17 +6119,19 @@ pub fn getDynString(self: Elf, off: u32) [:0]const u8 { |
| 6032 | 6119 | } |
| 6033 | 6120 | |
| 6034 | 6121 | pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 { |
| 6122 | const gpa = self.base.comp.gpa; | |
| 6035 | 6123 | 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; | |
| 6038 | 6126 | return off; |
| 6039 | 6127 | } |
| 6040 | 6128 | |
| 6041 | 6129 | fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void { |
| 6042 | const gpa = self.base.allocator; | |
| 6130 | const comp = self.base.comp; | |
| 6131 | const gpa = comp.gpa; | |
| 6043 | 6132 | const max_notes = 4; |
| 6044 | 6133 | |
| 6045 | try self.misc_errors.ensureUnusedCapacity(gpa, undefs.count()); | |
| 6134 | try comp.link_errors.ensureUnusedCapacity(gpa, undefs.count()); | |
| 6046 | 6135 | |
| 6047 | 6136 | var it = undefs.iterator(); |
| 6048 | 6137 | while (it.next()) |entry| { |
| ... | ... | @@ -6427,6 +6516,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); |
| 6427 | 6516 | pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1; |
| 6428 | 6517 | pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2; |
| 6429 | 6518 | |
| 6519 | fn 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 | ||
| 6430 | 6526 | const std = @import("std"); |
| 6431 | 6527 | const build_options = @import("build_options"); |
| 6432 | 6528 | const builtin = @import("builtin"); |
src/link/Elf/Archive.zig+4-2| ... | ... | @@ -20,7 +20,8 @@ pub fn deinit(self: *Archive, allocator: Allocator) void { |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | pub 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; | |
| 24 | 25 | |
| 25 | 26 | var stream = std.io.fixedBufferStream(self.data); |
| 26 | 27 | const reader = stream.reader(); |
| ... | ... | @@ -150,7 +151,8 @@ pub const ArSymtab = struct { |
| 150 | 151 | const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) }); |
| 151 | 152 | try writer.writeAll(mem.asBytes(&hdr)); |
| 152 | 153 | |
| 153 | const gpa = elf_file.base.allocator; | |
| 154 | const comp = elf_file.base.comp; | |
| 155 | const gpa = comp.gpa; | |
| 154 | 156 | var offsets = std.AutoHashMap(File.Index, u64).init(gpa); |
| 155 | 157 | defer offsets.deinit(); |
| 156 | 158 | 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 { |
| 227 | 227 | pub fn free(self: *Atom, elf_file: *Elf) void { |
| 228 | 228 | log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) }); |
| 229 | 229 | |
| 230 | const gpa = elf_file.base.allocator; | |
| 230 | const comp = elf_file.base.comp; | |
| 231 | const gpa = comp.gpa; | |
| 231 | 232 | const shndx = self.outputShndx().?; |
| 232 | 233 | const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; |
| 233 | 234 | const free_list = &meta.free_list; |
| ... | ... | @@ -352,7 +353,8 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void { |
| 352 | 353 | } |
| 353 | 354 | |
| 354 | 355 | pub 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; | |
| 356 | 358 | const file_ptr = self.file(elf_file).?; |
| 357 | 359 | assert(file_ptr == .zig_object); |
| 358 | 360 | const zig_object = file_ptr.zig_object; |
| ... | ... | @@ -375,8 +377,8 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
| 375 | 377 | } |
| 376 | 378 | |
| 377 | 379 | pub 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(); | |
| 380 | 382 | const file_ptr = self.file(elf_file).?; |
| 381 | 383 | const rels = self.relocs(elf_file); |
| 382 | 384 | var i: usize = 0; |
| ... | ... | @@ -543,7 +545,7 @@ fn scanReloc( |
| 543 | 545 | try self.reportPicError(symbol, rel, elf_file), |
| 544 | 546 | |
| 545 | 547 | .copyrel => { |
| 546 | if (elf_file.base.options.z_nocopyreloc) { | |
| 548 | if (elf_file.z_nocopyreloc) { | |
| 547 | 549 | if (symbol.isAbs(elf_file)) |
| 548 | 550 | try self.reportNoPicError(symbol, rel, elf_file) |
| 549 | 551 | else |
| ... | ... | @@ -553,9 +555,9 @@ fn scanReloc( |
| 553 | 555 | }, |
| 554 | 556 | |
| 555 | 557 | .dyn_copyrel => { |
| 556 | if (is_writeable or elf_file.base.options.z_nocopyreloc) { | |
| 558 | if (is_writeable or elf_file.z_nocopyreloc) { | |
| 557 | 559 | if (!is_writeable) { |
| 558 | if (elf_file.base.options.z_notext) { | |
| 560 | if (elf_file.z_notext) { | |
| 559 | 561 | elf_file.has_text_reloc = true; |
| 560 | 562 | } else { |
| 561 | 563 | try self.reportTextRelocError(symbol, rel, elf_file); |
| ... | ... | @@ -587,7 +589,7 @@ fn scanReloc( |
| 587 | 589 | |
| 588 | 590 | .dynrel, .baserel, .ifunc => { |
| 589 | 591 | if (!is_writeable) { |
| 590 | if (elf_file.base.options.z_notext) { | |
| 592 | if (elf_file.z_notext) { | |
| 591 | 593 | elf_file.has_text_reloc = true; |
| 592 | 594 | } else { |
| 593 | 595 | try self.reportTextRelocError(symbol, rel, elf_file); |
| ... | ... | @@ -657,11 +659,12 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction { |
| 657 | 659 | } |
| 658 | 660 | |
| 659 | 661 | fn 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) { | |
| 662 | 665 | .Obj => unreachable, |
| 663 | 666 | .Lib => 0, |
| 664 | .Exe => if (elf_file.base.options.pie) 1 else 2, | |
| 667 | .Exe => if (comp.config.pie) 1 else 2, | |
| 665 | 668 | }; |
| 666 | 669 | } |
| 667 | 670 | |
| ... | ... | @@ -746,6 +749,8 @@ fn reportUndefined( |
| 746 | 749 | rel: elf.Elf64_Rela, |
| 747 | 750 | undefs: anytype, |
| 748 | 751 | ) !void { |
| 752 | const comp = elf_file.base.comp; | |
| 753 | const gpa = comp.gpa; | |
| 749 | 754 | const rel_esym = switch (self.file(elf_file).?) { |
| 750 | 755 | .zig_object => |x| x.elfSym(rel.r_sym()).*, |
| 751 | 756 | .object => |x| x.symtab.items[rel.r_sym()], |
| ... | ... | @@ -760,7 +765,7 @@ fn reportUndefined( |
| 760 | 765 | { |
| 761 | 766 | const gop = try undefs.getOrPut(sym_index); |
| 762 | 767 | 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); | |
| 764 | 769 | } |
| 765 | 770 | try gop.value_ptr.append(self.atom_index); |
| 766 | 771 | } |
| ... | ... | @@ -956,6 +961,8 @@ fn resolveDynAbsReloc( |
| 956 | 961 | elf_file: *Elf, |
| 957 | 962 | writer: anytype, |
| 958 | 963 | ) !void { |
| 964 | const comp = elf_file.base.comp; | |
| 965 | const gpa = comp.gpa; | |
| 959 | 966 | const P = self.value + rel.r_offset; |
| 960 | 967 | const A = rel.r_addend; |
| 961 | 968 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); |
| ... | ... | @@ -966,7 +973,7 @@ fn resolveDynAbsReloc( |
| 966 | 973 | .shared_object => unreachable, |
| 967 | 974 | inline else => |x| x.num_dynrelocs, |
| 968 | 975 | }; |
| 969 | try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, num_dynrelocs); | |
| 976 | try elf_file.rela_dyn.ensureUnusedCapacity(gpa, num_dynrelocs); | |
| 970 | 977 | |
| 971 | 978 | switch (action) { |
| 972 | 979 | .@"error", |
| ... | ... | @@ -979,7 +986,7 @@ fn resolveDynAbsReloc( |
| 979 | 986 | => try writer.writeInt(i32, @as(i32, @truncate(S + A)), .little), |
| 980 | 987 | |
| 981 | 988 | .dyn_copyrel => { |
| 982 | if (is_writeable or elf_file.base.options.z_nocopyreloc) { | |
| 989 | if (is_writeable or elf_file.z_nocopyreloc) { | |
| 983 | 990 | elf_file.addRelaDynAssumeCapacity(.{ |
| 984 | 991 | .offset = P, |
| 985 | 992 | .sym = target.extra(elf_file).?.dynamic, |
src/link/Elf/LdScript.zig+2-1| ... | ... | @@ -14,7 +14,8 @@ pub const Error = error{ |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | 16 | pub 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; | |
| 18 | 19 | var tokenizer = Tokenizer{ .source = data }; |
| 19 | 20 | var tokens = std.ArrayList(Token).init(gpa); |
| 20 | 21 | defer tokens.deinit(); |
src/link/Elf/LinkerDefined.zig+2-1| ... | ... | @@ -12,7 +12,8 @@ pub fn deinit(self: *LinkerDefined, allocator: Allocator) void { |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | 14 | pub 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; | |
| 16 | 17 | try self.symtab.ensureUnusedCapacity(gpa, 1); |
| 17 | 18 | try self.symbols.ensureUnusedCapacity(gpa, 1); |
| 18 | 19 | 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 { |
| 54 | 54 | |
| 55 | 55 | self.header = try reader.readStruct(elf.Elf64_Ehdr); |
| 56 | 56 | |
| 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().?) { | |
| 58 | 59 | try elf_file.reportParseError2( |
| 59 | 60 | self.index, |
| 60 | 61 | "invalid cpu architecture: {s}", |
| ... | ... | @@ -65,7 +66,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 65 | 66 | |
| 66 | 67 | if (self.header.?.e_shnum == 0) return; |
| 67 | 68 | |
| 68 | const gpa = elf_file.base.allocator; | |
| 69 | const comp = elf_file.base.comp; | |
| 70 | const gpa = comp.gpa; | |
| 69 | 71 | |
| 70 | 72 | if (self.data.len < self.header.?.e_shoff or |
| 71 | 73 | 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 { |
| 148 | 150 | } |
| 149 | 151 | |
| 150 | 152 | fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 153 | const comp = elf_file.base.comp; | |
| 154 | const gpa = comp.gpa; | |
| 151 | 155 | const shdrs = self.shdrs.items; |
| 152 | try self.atoms.resize(elf_file.base.allocator, shdrs.len); | |
| 156 | try self.atoms.resize(gpa, shdrs.len); | |
| 153 | 157 | @memset(self.atoms.items, 0); |
| 154 | 158 | |
| 155 | 159 | for (shdrs, 0..) |shdr, i| { |
| ... | ... | @@ -184,7 +188,6 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 184 | 188 | continue; |
| 185 | 189 | } |
| 186 | 190 | |
| 187 | const gpa = elf_file.base.allocator; | |
| 188 | 191 | const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature); |
| 189 | 192 | const comdat_group_index = try elf_file.addComdatGroup(); |
| 190 | 193 | 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 |
| 247 | 250 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 { |
| 248 | 251 | const name = blk: { |
| 249 | 252 | const name = self.getString(shdr.sh_name); |
| 250 | if (elf_file.isRelocatable()) break :blk name; | |
| 253 | if (elf_file.base.isRelocatable()) break :blk name; | |
| 251 | 254 | if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name; |
| 252 | 255 | const sh_name_prefixes: []const [:0]const u8 = &.{ |
| 253 | 256 | ".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 |
| 275 | 278 | }; |
| 276 | 279 | const flags = blk: { |
| 277 | 280 | var flags = shdr.sh_flags; |
| 278 | if (!elf_file.isRelocatable()) { | |
| 281 | if (!elf_file.base.isRelocatable()) { | |
| 279 | 282 | flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN); |
| 280 | 283 | } |
| 281 | 284 | break :blk switch (@"type") { |
| ... | ... | @@ -292,13 +295,14 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem |
| 292 | 295 | } |
| 293 | 296 | |
| 294 | 297 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 298 | const comp = elf_file.base.comp; | |
| 295 | 299 | const shdr = self.shdrs.items[index]; |
| 296 | 300 | const name = self.getString(shdr.sh_name); |
| 297 | 301 | const ignore = blk: { |
| 298 | 302 | if (mem.startsWith(u8, name, ".note")) break :blk true; |
| 299 | 303 | if (mem.startsWith(u8, name, ".comment")) break :blk true; |
| 300 | 304 | 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 | |
| 302 | 306 | mem.startsWith(u8, name, ".debug")) break :blk true; |
| 303 | 307 | break :blk false; |
| 304 | 308 | }; |
| ... | ... | @@ -306,7 +310,8 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 306 | 310 | } |
| 307 | 311 | |
| 308 | 312 | fn 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; | |
| 310 | 315 | const first_global = self.first_global orelse self.symtab.items.len; |
| 311 | 316 | |
| 312 | 317 | try self.symbols.ensureTotalCapacityPrecise(gpa, self.symtab.items.len); |
| ... | ... | @@ -338,7 +343,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void { |
| 338 | 343 | return; |
| 339 | 344 | }; |
| 340 | 345 | |
| 341 | const gpa = elf_file.base.allocator; | |
| 346 | const comp = elf_file.base.comp; | |
| 347 | const gpa = comp.gpa; | |
| 342 | 348 | const raw = self.shdrContents(shndx); |
| 343 | 349 | const relocs = self.getRelocs(relocs_shndx); |
| 344 | 350 | const fdes_start = self.fdes.items.len; |
| ... | ... | @@ -438,6 +444,8 @@ fn filterRelocs( |
| 438 | 444 | } |
| 439 | 445 | |
| 440 | 446 | pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 447 | const comp = elf_file.base.comp; | |
| 448 | const gpa = comp.gpa; | |
| 441 | 449 | for (self.atoms.items) |atom_index| { |
| 442 | 450 | const atom = elf_file.atom(atom_index) orelse continue; |
| 443 | 451 | if (!atom.flags.alive) continue; |
| ... | ... | @@ -448,7 +456,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 448 | 456 | // TODO ideally, we don't have to decompress at this stage (should already be done) |
| 449 | 457 | // and we just fetch the code slice. |
| 450 | 458 | const code = try self.codeDecompressAlloc(elf_file, atom_index); |
| 451 | defer elf_file.base.allocator.free(code); | |
| 459 | defer gpa.free(code); | |
| 452 | 460 | try atom.scanRelocs(elf_file, code, undefs); |
| 453 | 461 | } else try atom.scanRelocs(elf_file, null, undefs); |
| 454 | 462 | } |
| ... | ... | @@ -512,7 +520,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { |
| 512 | 520 | } |
| 513 | 521 | |
| 514 | 522 | const is_import = blk: { |
| 515 | if (!elf_file.isDynLib()) break :blk false; | |
| 523 | if (!elf_file.base.isDynLib()) break :blk false; | |
| 516 | 524 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); |
| 517 | 525 | if (vis == .HIDDEN) break :blk false; |
| 518 | 526 | break :blk true; |
| ... | ... | @@ -621,7 +629,8 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { |
| 621 | 629 | continue; |
| 622 | 630 | } |
| 623 | 631 | |
| 624 | const gpa = elf_file.base.allocator; | |
| 632 | const comp = elf_file.base.comp; | |
| 633 | const gpa = comp.gpa; | |
| 625 | 634 | |
| 626 | 635 | const atom_index = try elf_file.addAtom(); |
| 627 | 636 | try self.atoms.append(gpa, atom_index); |
| ... | ... | @@ -680,7 +689,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { |
| 680 | 689 | const shdr = atom.inputShdr(elf_file); |
| 681 | 690 | atom.output_section_index = self.initOutputSection(elf_file, shdr) catch unreachable; |
| 682 | 691 | |
| 683 | const gpa = elf_file.base.allocator; | |
| 692 | const comp = elf_file.base.comp; | |
| 693 | const gpa = comp.gpa; | |
| 684 | 694 | const gop = try elf_file.output_sections.getOrPut(gpa, atom.output_section_index); |
| 685 | 695 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 686 | 696 | try gop.value_ptr.append(gpa, atom_index); |
| ... | ... | @@ -740,7 +750,8 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void { |
| 740 | 750 | shdr.sh_info = atom.outputShndx().?; |
| 741 | 751 | shdr.sh_link = elf_file.symtab_section_index.?; |
| 742 | 752 | |
| 743 | const gpa = elf_file.base.allocator; | |
| 753 | const comp = elf_file.base.comp; | |
| 754 | const gpa = comp.gpa; | |
| 744 | 755 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom.outputShndx().?); |
| 745 | 756 | if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx }; |
| 746 | 757 | try gop.value_ptr.atom_list.append(gpa, atom_index); |
| ... | ... | @@ -748,7 +759,8 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void { |
| 748 | 759 | } |
| 749 | 760 | |
| 750 | 761 | pub 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; | |
| 752 | 764 | const start = self.first_global orelse self.symtab.items.len; |
| 753 | 765 | |
| 754 | 766 | try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.symtab.items.len - start); |
| ... | ... | @@ -855,7 +867,8 @@ pub fn shdrContents(self: Object, index: u32) []const u8 { |
| 855 | 867 | /// Returns atom's code and optionally uncompresses data if required (for compressed sections). |
| 856 | 868 | /// Caller owns the memory. |
| 857 | 869 | pub 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; | |
| 859 | 872 | const atom_ptr = elf_file.atom(atom_index).?; |
| 860 | 873 | assert(atom_ptr.file_index == self.index); |
| 861 | 874 | 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 { |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | pub 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; | |
| 51 | 52 | var stream = std.io.fixedBufferStream(self.data); |
| 52 | 53 | const reader = stream.reader(); |
| 53 | 54 | |
| 54 | 55 | self.header = try reader.readStruct(elf.Elf64_Ehdr); |
| 55 | 56 | |
| 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().?) { | |
| 57 | 59 | try elf_file.reportParseError2( |
| 58 | 60 | self.index, |
| 59 | 61 | "invalid cpu architecture: {s}", |
| ... | ... | @@ -100,7 +102,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void { |
| 100 | 102 | } |
| 101 | 103 | |
| 102 | 104 | fn 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; | |
| 104 | 107 | const symtab = self.getSymtabRaw(); |
| 105 | 108 | |
| 106 | 109 | try self.verstrings.resize(gpa, 2); |
| ... | ... | @@ -145,7 +148,8 @@ fn parseVersions(self: *SharedObject, elf_file: *Elf) !void { |
| 145 | 148 | } |
| 146 | 149 | |
| 147 | 150 | pub 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; | |
| 149 | 153 | const symtab = self.getSymtabRaw(); |
| 150 | 154 | const strtab = self.getStrtabRaw(); |
| 151 | 155 | |
| ... | ... | @@ -294,7 +298,8 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void { |
| 294 | 298 | } |
| 295 | 299 | }; |
| 296 | 300 | |
| 297 | const gpa = elf_file.base.allocator; | |
| 301 | const comp = elf_file.base.comp; | |
| 302 | const gpa = comp.gpa; | |
| 298 | 303 | var aliases = std.ArrayList(Symbol.Index).init(gpa); |
| 299 | 304 | defer aliases.deinit(); |
| 300 | 305 | try aliases.ensureTotalCapacityPrecise(self.globals().len); |
src/link/Elf/Symbol.zig+3-3| ... | ... | @@ -43,7 +43,7 @@ pub fn outputShndx(symbol: Symbol) ?u16 { |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | pub 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; | |
| 47 | 47 | return !(symbol.flags.import or symbol.flags.@"export"); |
| 48 | 48 | } |
| 49 | 49 | |
| ... | ... | @@ -186,7 +186,7 @@ const GetOrCreateZigGotEntryResult = struct { |
| 186 | 186 | }; |
| 187 | 187 | |
| 188 | 188 | pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { |
| 189 | assert(!elf_file.isRelocatable()); | |
| 189 | assert(!elf_file.base.isRelocatable()); | |
| 190 | 190 | assert(symbol.flags.needs_zig_got); |
| 191 | 191 | if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got }; |
| 192 | 192 | 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 { |
| 237 | 237 | const st_shndx = blk: { |
| 238 | 238 | if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?; |
| 239 | 239 | 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; | |
| 241 | 241 | if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS; |
| 242 | 242 | break :blk symbol.outputShndx() orelse elf.SHN_UNDEF; |
| 243 | 243 | }; |
src/link/Elf/ZigObject.zig+68-51| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | //! Think about this as fake in-memory Object file for the Zig module. |
| 5 | 5 | |
| 6 | 6 | data: std.ArrayListUnmanaged(u8) = .{}, |
| 7 | /// Externally owned memory. | |
| 7 | 8 | path: []const u8, |
| 8 | 9 | index: File.Index, |
| 9 | 10 | |
| ... | ... | @@ -76,7 +77,8 @@ pub const symbol_mask: u32 = 0x7fffffff; |
| 76 | 77 | pub const SHN_ATOM: u16 = 0x100; |
| 77 | 78 | |
| 78 | 79 | pub 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; | |
| 80 | 82 | |
| 81 | 83 | try self.atoms.append(gpa, 0); // null input section |
| 82 | 84 | try self.relocs.append(gpa, .{}); // null relocs section |
| ... | ... | @@ -96,14 +98,18 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 96 | 98 | esym.st_shndx = elf.SHN_ABS; |
| 97 | 99 | symbol_ptr.esym_index = esym_index; |
| 98 | 100 | |
| 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, | |
| 101 | 108 | } |
| 102 | 109 | } |
| 103 | 110 | |
| 104 | 111 | pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 105 | 112 | self.data.deinit(allocator); |
| 106 | allocator.free(self.path); | |
| 107 | 113 | self.local_esyms.deinit(allocator); |
| 108 | 114 | self.global_esyms.deinit(allocator); |
| 109 | 115 | self.strtab.deinit(allocator); |
| ... | ... | @@ -155,13 +161,13 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 155 | 161 | pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 156 | 162 | // Handle any lazy symbols that were emitted by incremental compilation. |
| 157 | 163 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 158 | const module = elf_file.base.options.module.?; | |
| 164 | const zcu = elf_file.base.comp.module.?; | |
| 159 | 165 | |
| 160 | 166 | // Most lazy symbols can be updated on first use, but |
| 161 | 167 | // anyerror needs to wait for everything to be flushed. |
| 162 | 168 | if (metadata.text_state != .unused) self.updateLazySymbol( |
| 163 | 169 | elf_file, |
| 164 | link.File.LazySymbol.initDecl(.code, null, module), | |
| 170 | link.File.LazySymbol.initDecl(.code, null, zcu), | |
| 165 | 171 | metadata.text_symbol_index, |
| 166 | 172 | ) catch |err| return switch (err) { |
| 167 | 173 | error.CodegenFail => error.FlushFailure, |
| ... | ... | @@ -169,7 +175,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 169 | 175 | }; |
| 170 | 176 | if (metadata.rodata_state != .unused) self.updateLazySymbol( |
| 171 | 177 | elf_file, |
| 172 | link.File.LazySymbol.initDecl(.const_data, null, module), | |
| 178 | link.File.LazySymbol.initDecl(.const_data, null, zcu), | |
| 173 | 179 | metadata.rodata_symbol_index, |
| 174 | 180 | ) catch |err| return switch (err) { |
| 175 | 181 | error.CodegenFail => error.FlushFailure, |
| ... | ... | @@ -182,7 +188,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 182 | 188 | } |
| 183 | 189 | |
| 184 | 190 | 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); | |
| 186 | 193 | |
| 187 | 194 | // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections |
| 188 | 195 | // extracted from input object files correctly. |
| ... | ... | @@ -195,7 +202,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void { |
| 195 | 202 | const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?]; |
| 196 | 203 | const low_pc = text_shdr.sh_addr; |
| 197 | 204 | 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); | |
| 199 | 206 | self.debug_info_header_dirty = false; |
| 200 | 207 | } |
| 201 | 208 | |
| ... | ... | @@ -268,7 +275,7 @@ pub fn addGlobalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| 268 | 275 | } |
| 269 | 276 | |
| 270 | 277 | pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { |
| 271 | const gpa = elf_file.base.allocator; | |
| 278 | const gpa = elf_file.base.comp.gpa; | |
| 272 | 279 | const atom_index = try elf_file.addAtom(); |
| 273 | 280 | const symbol_index = try elf_file.addSymbol(); |
| 274 | 281 | const esym_index = try self.addLocalEsym(gpa); |
| ... | ... | @@ -363,7 +370,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { |
| 363 | 370 | } |
| 364 | 371 | |
| 365 | 372 | const is_import = blk: { |
| 366 | if (!elf_file.isDynLib()) break :blk false; | |
| 373 | if (!elf_file.base.isDynLib()) break :blk false; | |
| 367 | 374 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); |
| 368 | 375 | if (vis == .HIDDEN) break :blk false; |
| 369 | 376 | break :blk true; |
| ... | ... | @@ -411,6 +418,7 @@ pub fn allocateTlvAtoms(self: ZigObject, elf_file: *Elf) void { |
| 411 | 418 | } |
| 412 | 419 | |
| 413 | 420 | pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 421 | const gpa = elf_file.base.comp.gpa; | |
| 414 | 422 | for (self.atoms.items) |atom_index| { |
| 415 | 423 | const atom = elf_file.atom(atom_index) orelse continue; |
| 416 | 424 | if (!atom.flags.alive) continue; |
| ... | ... | @@ -421,7 +429,7 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 421 | 429 | // Perhaps it would make sense to save the code until flushModule where we |
| 422 | 430 | // would free all of generated code? |
| 423 | 431 | const code = try self.codeAlloc(elf_file, atom_index); |
| 424 | defer elf_file.base.allocator.free(code); | |
| 432 | defer gpa.free(code); | |
| 425 | 433 | try atom.scanRelocs(elf_file, code, undefs); |
| 426 | 434 | } else try atom.scanRelocs(elf_file, null, undefs); |
| 427 | 435 | } |
| ... | ... | @@ -447,7 +455,7 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void { |
| 447 | 455 | /// We need this so that we can write to an archive. |
| 448 | 456 | /// TODO implement writing ZigObject data directly to a buffer instead. |
| 449 | 457 | pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { |
| 450 | const gpa = elf_file.base.allocator; | |
| 458 | const gpa = elf_file.base.comp.gpa; | |
| 451 | 459 | const shsize: u64 = switch (elf_file.ptr_width) { |
| 452 | 460 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| 453 | 461 | .p64 => @sizeOf(elf.Elf64_Shdr), |
| ... | ... | @@ -465,7 +473,7 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { |
| 465 | 473 | } |
| 466 | 474 | |
| 467 | 475 | pub 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; | |
| 469 | 477 | |
| 470 | 478 | try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.globals().len); |
| 471 | 479 | |
| ... | ... | @@ -508,7 +516,7 @@ pub fn addAtomsToRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 508 | 516 | const out_shdr = elf_file.shdrs.items[out_shndx]; |
| 509 | 517 | if (out_shdr.sh_type == elf.SHT_NOBITS) continue; |
| 510 | 518 | |
| 511 | const gpa = elf_file.base.allocator; | |
| 519 | const gpa = elf_file.base.comp.gpa; | |
| 512 | 520 | const sec = elf_file.output_rela_sections.getPtr(out_shndx).?; |
| 513 | 521 | try sec.atom_list.append(gpa, atom_index); |
| 514 | 522 | } |
| ... | ... | @@ -602,7 +610,7 @@ pub fn asFile(self: *ZigObject) File { |
| 602 | 610 | /// Returns atom's code. |
| 603 | 611 | /// Caller owns the memory. |
| 604 | 612 | pub 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; | |
| 606 | 614 | const atom = elf_file.atom(atom_index).?; |
| 607 | 615 | assert(atom.file_index == self.index); |
| 608 | 616 | const shdr = &elf_file.shdrs.items[atom.outputShndx().?]; |
| ... | ... | @@ -668,8 +676,8 @@ pub fn lowerAnonDecl( |
| 668 | 676 | explicit_alignment: InternPool.Alignment, |
| 669 | 677 | src_loc: Module.SrcLoc, |
| 670 | 678 | ) !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.?; | |
| 673 | 681 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 674 | 682 | const decl_alignment = switch (explicit_alignment) { |
| 675 | 683 | .none => ty.abiAlignment(mod), |
| ... | ... | @@ -716,8 +724,8 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 716 | 724 | elf_file: *Elf, |
| 717 | 725 | lazy_sym: link.File.LazySymbol, |
| 718 | 726 | ) !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.?; | |
| 721 | 729 | const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod)); |
| 722 | 730 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 723 | 731 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| ... | ... | @@ -752,25 +760,28 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 752 | 760 | } |
| 753 | 761 | |
| 754 | 762 | fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void { |
| 763 | const gpa = elf_file.base.comp.gpa; | |
| 755 | 764 | const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return; |
| 756 | 765 | for (unnamed_consts.items) |sym_index| { |
| 757 | 766 | self.freeDeclMetadata(elf_file, sym_index); |
| 758 | 767 | } |
| 759 | unnamed_consts.clearAndFree(elf_file.base.allocator); | |
| 768 | unnamed_consts.clearAndFree(gpa); | |
| 760 | 769 | } |
| 761 | 770 | |
| 762 | 771 | fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void { |
| 763 | 772 | _ = self; |
| 773 | const gpa = elf_file.base.comp.gpa; | |
| 764 | 774 | const sym = elf_file.symbol(sym_index); |
| 765 | 775 | sym.atom(elf_file).?.free(elf_file); |
| 766 | 776 | 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 {}; | |
| 768 | 778 | elf_file.symbols.items[sym_index] = .{}; |
| 769 | 779 | // TODO free GOT entry here |
| 770 | 780 | } |
| 771 | 781 | |
| 772 | 782 | pub 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.?; | |
| 774 | 785 | const decl = mod.declPtr(decl_index); |
| 775 | 786 | |
| 776 | 787 | log.debug("freeDecl {*}", .{decl}); |
| ... | ... | @@ -780,7 +791,7 @@ pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclInd |
| 780 | 791 | const sym_index = kv.value.symbol_index; |
| 781 | 792 | self.freeDeclMetadata(elf_file, sym_index); |
| 782 | 793 | self.freeUnnamedConsts(elf_file, decl_index); |
| 783 | kv.value.exports.deinit(elf_file.base.allocator); | |
| 794 | kv.value.exports.deinit(gpa); | |
| 784 | 795 | } |
| 785 | 796 | |
| 786 | 797 | if (self.dwarf) |*dw| { |
| ... | ... | @@ -793,15 +804,16 @@ pub fn getOrCreateMetadataForDecl( |
| 793 | 804 | elf_file: *Elf, |
| 794 | 805 | decl_index: InternPool.DeclIndex, |
| 795 | 806 | ) !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); | |
| 797 | 809 | 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; | |
| 799 | 811 | const symbol_index = try self.addAtom(elf_file); |
| 800 | const mod = elf_file.base.options.module.?; | |
| 812 | const mod = elf_file.base.comp.module.?; | |
| 801 | 813 | const decl = mod.declPtr(decl_index); |
| 802 | 814 | const sym = elf_file.symbol(symbol_index); |
| 803 | 815 | if (decl.getOwnedVariable(mod)) |variable| { |
| 804 | if (variable.is_threadlocal and !single_threaded) { | |
| 816 | if (variable.is_threadlocal and any_non_single_threaded) { | |
| 805 | 817 | sym.flags.is_tls = true; |
| 806 | 818 | } |
| 807 | 819 | } |
| ... | ... | @@ -820,13 +832,13 @@ fn getDeclShdrIndex( |
| 820 | 832 | code: []const u8, |
| 821 | 833 | ) error{OutOfMemory}!u16 { |
| 822 | 834 | _ = 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; | |
| 825 | 837 | const shdr_index = switch (decl.ty.zigTypeTag(mod)) { |
| 826 | 838 | .Fn => elf_file.zig_text_section_index.?, |
| 827 | 839 | else => blk: { |
| 828 | 840 | if (decl.getOwnedVariable(mod)) |variable| { |
| 829 | if (variable.is_threadlocal and !single_threaded) { | |
| 841 | if (variable.is_threadlocal and any_non_single_threaded) { | |
| 830 | 842 | const is_all_zeroes = for (code) |byte| { |
| 831 | 843 | if (byte != 0) break false; |
| 832 | 844 | } else true; |
| ... | ... | @@ -846,9 +858,12 @@ fn getDeclShdrIndex( |
| 846 | 858 | } |
| 847 | 859 | if (variable.is_const) break :blk elf_file.zig_data_rel_ro_section_index.?; |
| 848 | 860 | 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 | }; | |
| 852 | 867 | } |
| 853 | 868 | // TODO I blatantly copied the logic from the Wasm linker, but is there a less |
| 854 | 869 | // intrusive check for all zeroes than this? |
| ... | ... | @@ -873,8 +888,8 @@ fn updateDeclCode( |
| 873 | 888 | code: []const u8, |
| 874 | 889 | stt_bits: u8, |
| 875 | 890 | ) !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.?; | |
| 878 | 893 | const decl = mod.declPtr(decl_index); |
| 879 | 894 | const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); |
| 880 | 895 | |
| ... | ... | @@ -911,7 +926,7 @@ fn updateDeclCode( |
| 911 | 926 | sym.value = atom_ptr.value; |
| 912 | 927 | esym.st_value = atom_ptr.value; |
| 913 | 928 | |
| 914 | if (!elf_file.isRelocatable()) { | |
| 929 | if (!elf_file.base.isRelocatable()) { | |
| 915 | 930 | log.debug(" (writing new offset table entry)", .{}); |
| 916 | 931 | assert(sym.flags.has_zig_got); |
| 917 | 932 | const extra = sym.extra(elf_file).?; |
| ... | ... | @@ -929,7 +944,7 @@ fn updateDeclCode( |
| 929 | 944 | sym.flags.needs_zig_got = true; |
| 930 | 945 | esym.st_value = atom_ptr.value; |
| 931 | 946 | |
| 932 | if (!elf_file.isRelocatable()) { | |
| 947 | if (!elf_file.base.isRelocatable()) { | |
| 933 | 948 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 934 | 949 | try elf_file.zig_got.writeOne(elf_file, gop.index); |
| 935 | 950 | } |
| ... | ... | @@ -971,8 +986,8 @@ fn updateTlv( |
| 971 | 986 | shndx: u16, |
| 972 | 987 | code: []const u8, |
| 973 | 988 | ) !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.?; | |
| 976 | 991 | const decl = mod.declPtr(decl_index); |
| 977 | 992 | const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); |
| 978 | 993 | |
| ... | ... | @@ -1026,6 +1041,7 @@ pub fn updateFunc( |
| 1026 | 1041 | const tracy = trace(@src()); |
| 1027 | 1042 | defer tracy.end(); |
| 1028 | 1043 | |
| 1044 | const gpa = elf_file.base.comp.gpa; | |
| 1029 | 1045 | const func = mod.funcInfo(func_index); |
| 1030 | 1046 | const decl_index = func.owner_decl; |
| 1031 | 1047 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -1034,7 +1050,7 @@ pub fn updateFunc( |
| 1034 | 1050 | self.freeUnnamedConsts(elf_file, decl_index); |
| 1035 | 1051 | elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); |
| 1036 | 1052 | |
| 1037 | var code_buffer = std.ArrayList(u8).init(elf_file.base.allocator); | |
| 1053 | var code_buffer = std.ArrayList(u8).init(gpa); | |
| 1038 | 1054 | defer code_buffer.deinit(); |
| 1039 | 1055 | |
| 1040 | 1056 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; |
| ... | ... | @@ -1117,7 +1133,8 @@ pub fn updateDecl( |
| 1117 | 1133 | const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 1118 | 1134 | elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); |
| 1119 | 1135 | |
| 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); | |
| 1121 | 1138 | defer code_buffer.deinit(); |
| 1122 | 1139 | |
| 1123 | 1140 | var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null; |
| ... | ... | @@ -1179,8 +1196,8 @@ fn updateLazySymbol( |
| 1179 | 1196 | sym: link.File.LazySymbol, |
| 1180 | 1197 | symbol_index: Symbol.Index, |
| 1181 | 1198 | ) !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.?; | |
| 1184 | 1201 | |
| 1185 | 1202 | var required_alignment: InternPool.Alignment = .none; |
| 1186 | 1203 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -1245,7 +1262,7 @@ fn updateLazySymbol( |
| 1245 | 1262 | local_sym.flags.needs_zig_got = true; |
| 1246 | 1263 | local_esym.st_value = atom_ptr.value; |
| 1247 | 1264 | |
| 1248 | if (!elf_file.isRelocatable()) { | |
| 1265 | if (!elf_file.base.isRelocatable()) { | |
| 1249 | 1266 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); |
| 1250 | 1267 | try elf_file.zig_got.writeOne(elf_file, gop.index); |
| 1251 | 1268 | } |
| ... | ... | @@ -1261,8 +1278,8 @@ pub fn lowerUnnamedConst( |
| 1261 | 1278 | typed_value: TypedValue, |
| 1262 | 1279 | decl_index: InternPool.DeclIndex, |
| 1263 | 1280 | ) !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.?; | |
| 1266 | 1283 | const gop = try self.unnamed_consts.getOrPut(gpa, decl_index); |
| 1267 | 1284 | if (!gop.found_existing) { |
| 1268 | 1285 | gop.value_ptr.* = .{}; |
| ... | ... | @@ -1308,7 +1325,7 @@ fn lowerConst( |
| 1308 | 1325 | output_section_index: u16, |
| 1309 | 1326 | src_loc: Module.SrcLoc, |
| 1310 | 1327 | ) !LowerConstResult { |
| 1311 | const gpa = elf_file.base.allocator; | |
| 1328 | const gpa = elf_file.base.comp.gpa; | |
| 1312 | 1329 | |
| 1313 | 1330 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1314 | 1331 | defer code_buffer.deinit(); |
| ... | ... | @@ -1364,7 +1381,7 @@ pub fn updateExports( |
| 1364 | 1381 | const tracy = trace(@src()); |
| 1365 | 1382 | defer tracy.end(); |
| 1366 | 1383 | |
| 1367 | const gpa = elf_file.base.allocator; | |
| 1384 | const gpa = elf_file.base.comp.gpa; | |
| 1368 | 1385 | const metadata = switch (exported) { |
| 1369 | 1386 | .decl_index => |decl_index| blk: { |
| 1370 | 1387 | _ = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| ... | ... | @@ -1467,7 +1484,7 @@ pub fn deleteDeclExport( |
| 1467 | 1484 | name: InternPool.NullTerminatedString, |
| 1468 | 1485 | ) void { |
| 1469 | 1486 | 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.?; | |
| 1471 | 1488 | const exp_name = mod.intern_pool.stringToSlice(name); |
| 1472 | 1489 | const esym_index = metadata.@"export"(self, exp_name) orelse return; |
| 1473 | 1490 | log.debug("deleting export '{s}'", .{exp_name}); |
| ... | ... | @@ -1485,7 +1502,7 @@ pub fn deleteDeclExport( |
| 1485 | 1502 | |
| 1486 | 1503 | pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 { |
| 1487 | 1504 | _ = lib_name; |
| 1488 | const gpa = elf_file.base.allocator; | |
| 1505 | const gpa = elf_file.base.comp.gpa; | |
| 1489 | 1506 | const off = try self.strtab.insert(gpa, name); |
| 1490 | 1507 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); |
| 1491 | 1508 | if (!lookup_gop.found_existing) { |
src/link/Elf/eh_frame.zig+13-5| ... | ... | @@ -233,9 +233,12 @@ pub const Iterator = struct { |
| 233 | 233 | }; |
| 234 | 234 | |
| 235 | 235 | pub fn calcEhFrameSize(elf_file: *Elf) !usize { |
| 236 | const comp = elf_file.base.comp; | |
| 237 | const gpa = comp.gpa; | |
| 238 | ||
| 236 | 239 | var offset: usize = 0; |
| 237 | 240 | |
| 238 | var cies = std.ArrayList(Cie).init(elf_file.base.allocator); | |
| 241 | var cies = std.ArrayList(Cie).init(gpa); | |
| 239 | 242 | defer cies.deinit(); |
| 240 | 243 | |
| 241 | 244 | for (elf_file.objects.items) |index| { |
| ... | ... | @@ -268,7 +271,7 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize { |
| 268 | 271 | } |
| 269 | 272 | } |
| 270 | 273 | |
| 271 | if (!elf_file.isRelocatable()) { | |
| 274 | if (!elf_file.base.isRelocatable()) { | |
| 272 | 275 | offset += 4; // NULL terminator |
| 273 | 276 | } |
| 274 | 277 | |
| ... | ... | @@ -327,7 +330,8 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 327 | 330 | } |
| 328 | 331 | |
| 329 | 332 | pub 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; | |
| 331 | 335 | |
| 332 | 336 | relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr}); |
| 333 | 337 | |
| ... | ... | @@ -378,7 +382,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 378 | 382 | } |
| 379 | 383 | |
| 380 | 384 | pub 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; | |
| 382 | 387 | |
| 383 | 388 | for (elf_file.objects.items) |index| { |
| 384 | 389 | const object = elf_file.file(index).?.object; |
| ... | ... | @@ -467,6 +472,9 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 467 | 472 | } |
| 468 | 473 | |
| 469 | 474 | pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 475 | const comp = elf_file.base.comp; | |
| 476 | const gpa = comp.gpa; | |
| 477 | ||
| 470 | 478 | try writer.writeByte(1); // version |
| 471 | 479 | try writer.writeByte(EH_PE.pcrel | EH_PE.sdata4); |
| 472 | 480 | try writer.writeByte(EH_PE.udata4); |
| ... | ... | @@ -495,7 +503,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 495 | 503 | } |
| 496 | 504 | }; |
| 497 | 505 | |
| 498 | var entries = std.ArrayList(Entry).init(elf_file.base.allocator); | |
| 506 | var entries = std.ArrayList(Entry).init(gpa); | |
| 499 | 507 | defer entries.deinit(); |
| 500 | 508 | try entries.ensureTotalCapacityPrecise(num_fdes); |
| 501 | 509 |
src/link/Elf/gc.zig+2-1| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | pub 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; | |
| 3 | 4 | const num_files = elf_file.objects.items.len + @intFromBool(elf_file.zig_object_index != null); |
| 4 | 5 | var files = try std.ArrayList(File.Index).initCapacity(gpa, num_files); |
| 5 | 6 | defer files.deinit(); |
src/link/Elf/synthetic_sections.zig+78-39| ... | ... | @@ -8,14 +8,16 @@ pub const DynamicSection = struct { |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | 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; | |
| 12 | 13 | const off = try elf_file.insertDynString(shared.soname()); |
| 13 | 14 | try dt.needed.append(gpa, off); |
| 14 | 15 | } |
| 15 | 16 | |
| 16 | 17 | pub fn setRpath(dt: *DynamicSection, rpath_list: []const []const u8, elf_file: *Elf) !void { |
| 17 | 18 | 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; | |
| 19 | 21 | var rpath = std.ArrayList(u8).init(gpa); |
| 20 | 22 | defer rpath.deinit(); |
| 21 | 23 | for (rpath_list, 0..) |path, i| { |
| ... | ... | @@ -32,7 +34,7 @@ pub const DynamicSection = struct { |
| 32 | 34 | fn getFlags(dt: DynamicSection, elf_file: *Elf) ?u64 { |
| 33 | 35 | _ = dt; |
| 34 | 36 | var flags: u64 = 0; |
| 35 | if (elf_file.base.options.z_now) { | |
| 37 | if (elf_file.z_now) { | |
| 36 | 38 | flags |= elf.DF_BIND_NOW; |
| 37 | 39 | } |
| 38 | 40 | for (elf_file.got.entries.items) |entry| switch (entry.tag) { |
| ... | ... | @@ -49,15 +51,16 @@ pub const DynamicSection = struct { |
| 49 | 51 | } |
| 50 | 52 | |
| 51 | 53 | fn getFlags1(dt: DynamicSection, elf_file: *Elf) ?u64 { |
| 54 | const comp = elf_file.base.comp; | |
| 52 | 55 | _ = dt; |
| 53 | 56 | var flags_1: u64 = 0; |
| 54 | if (elf_file.base.options.z_now) { | |
| 57 | if (elf_file.z_now) { | |
| 55 | 58 | flags_1 |= elf.DF_1_NOW; |
| 56 | 59 | } |
| 57 | if (elf_file.isExe() and elf_file.base.options.pie) { | |
| 60 | if (elf_file.base.isExe() and comp.config.pie) { | |
| 58 | 61 | flags_1 |= elf.DF_1_PIE; |
| 59 | 62 | } |
| 60 | // if (elf_file.base.options.z_nodlopen) { | |
| 63 | // if (elf_file.z_nodlopen) { | |
| 61 | 64 | // flags_1 |= elf.DF_1_NOOPEN; |
| 62 | 65 | // } |
| 63 | 66 | return if (flags_1 > 0) flags_1 else null; |
| ... | ... | @@ -86,7 +89,7 @@ pub const DynamicSection = struct { |
| 86 | 89 | if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED |
| 87 | 90 | if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS |
| 88 | 91 | 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 | |
| 90 | 93 | nentries += 1; // NULL |
| 91 | 94 | return nentries * @sizeOf(elf.Elf64_Dyn); |
| 92 | 95 | } |
| ... | ... | @@ -213,7 +216,7 @@ pub const DynamicSection = struct { |
| 213 | 216 | } |
| 214 | 217 | |
| 215 | 218 | // 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 }); | |
| 217 | 220 | |
| 218 | 221 | // NULL |
| 219 | 222 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 }); |
| ... | ... | @@ -246,12 +249,14 @@ pub const ZigGotSection = struct { |
| 246 | 249 | } |
| 247 | 250 | |
| 248 | 251 | 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); | |
| 250 | 255 | const entry = &zig_got.entries.items[index]; |
| 251 | 256 | entry.* = sym_index; |
| 252 | 257 | const symbol = elf_file.symbol(sym_index); |
| 253 | 258 | 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)) { | |
| 255 | 260 | zig_got.flags.needs_rela = true; |
| 256 | 261 | } |
| 257 | 262 | if (symbol.extra(elf_file)) |extra| { |
| ... | ... | @@ -287,7 +292,8 @@ pub const ZigGotSection = struct { |
| 287 | 292 | zig_got.flags.dirty = false; |
| 288 | 293 | } |
| 289 | 294 | 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(); | |
| 291 | 297 | const off = zig_got.entryOffset(index, elf_file); |
| 292 | 298 | const vaddr = zig_got.entryAddress(index, elf_file); |
| 293 | 299 | const entry = zig_got.entries.items[index]; |
| ... | ... | @@ -346,7 +352,9 @@ pub const ZigGotSection = struct { |
| 346 | 352 | } |
| 347 | 353 | |
| 348 | 354 | 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()); | |
| 350 | 358 | for (zig_got.entries.items) |entry| { |
| 351 | 359 | const symbol = elf_file.symbol(entry); |
| 352 | 360 | const offset = symbol.zigGotAddress(elf_file); |
| ... | ... | @@ -477,14 +485,16 @@ pub const GotSection = struct { |
| 477 | 485 | } |
| 478 | 486 | |
| 479 | 487 | 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); | |
| 481 | 491 | const entry = &got.entries.items[index]; |
| 482 | 492 | entry.tag = .got; |
| 483 | 493 | entry.symbol_index = sym_index; |
| 484 | 494 | const symbol = elf_file.symbol(sym_index); |
| 485 | 495 | symbol.flags.has_got = true; |
| 486 | 496 | 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))) | |
| 488 | 498 | { |
| 489 | 499 | got.flags.needs_rela = true; |
| 490 | 500 | } |
| ... | ... | @@ -497,8 +507,10 @@ pub const GotSection = struct { |
| 497 | 507 | } |
| 498 | 508 | |
| 499 | 509 | pub fn addTlsLdSymbol(got: *GotSection, elf_file: *Elf) !void { |
| 510 | const comp = elf_file.base.comp; | |
| 511 | const gpa = comp.gpa; | |
| 500 | 512 | assert(got.flags.needs_tlsld); |
| 501 | const index = try got.allocateEntry(elf_file.base.allocator); | |
| 513 | const index = try got.allocateEntry(gpa); | |
| 502 | 514 | const entry = &got.entries.items[index]; |
| 503 | 515 | entry.tag = .tlsld; |
| 504 | 516 | entry.symbol_index = undefined; // unused |
| ... | ... | @@ -507,13 +519,15 @@ pub const GotSection = struct { |
| 507 | 519 | } |
| 508 | 520 | |
| 509 | 521 | 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); | |
| 511 | 525 | const entry = &got.entries.items[index]; |
| 512 | 526 | entry.tag = .tlsgd; |
| 513 | 527 | entry.symbol_index = sym_index; |
| 514 | 528 | const symbol = elf_file.symbol(sym_index); |
| 515 | 529 | 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; | |
| 517 | 531 | if (symbol.extra(elf_file)) |extra| { |
| 518 | 532 | var new_extra = extra; |
| 519 | 533 | new_extra.tlsgd = index; |
| ... | ... | @@ -522,13 +536,15 @@ pub const GotSection = struct { |
| 522 | 536 | } |
| 523 | 537 | |
| 524 | 538 | 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); | |
| 526 | 542 | const entry = &got.entries.items[index]; |
| 527 | 543 | entry.tag = .gottp; |
| 528 | 544 | entry.symbol_index = sym_index; |
| 529 | 545 | const symbol = elf_file.symbol(sym_index); |
| 530 | 546 | 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; | |
| 532 | 548 | if (symbol.extra(elf_file)) |extra| { |
| 533 | 549 | var new_extra = extra; |
| 534 | 550 | new_extra.gottp = index; |
| ... | ... | @@ -537,7 +553,9 @@ pub const GotSection = struct { |
| 537 | 553 | } |
| 538 | 554 | |
| 539 | 555 | 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); | |
| 541 | 559 | const entry = &got.entries.items[index]; |
| 542 | 560 | entry.tag = .tlsdesc; |
| 543 | 561 | entry.symbol_index = sym_index; |
| ... | ... | @@ -560,7 +578,8 @@ pub const GotSection = struct { |
| 560 | 578 | } |
| 561 | 579 | |
| 562 | 580 | 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(); | |
| 564 | 583 | const apply_relocs = true; // TODO add user option for this |
| 565 | 584 | |
| 566 | 585 | for (got.entries.items) |entry| { |
| ... | ... | @@ -575,7 +594,7 @@ pub const GotSection = struct { |
| 575 | 594 | if (symbol.?.flags.import) break :blk 0; |
| 576 | 595 | if (symbol.?.isIFunc(elf_file)) |
| 577 | 596 | 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 | |
| 579 | 598 | !symbol.?.isAbs(elf_file)) |
| 580 | 599 | { |
| 581 | 600 | break :blk if (apply_relocs) value else 0; |
| ... | ... | @@ -622,8 +641,10 @@ pub const GotSection = struct { |
| 622 | 641 | } |
| 623 | 642 | |
| 624 | 643 | 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)); | |
| 627 | 648 | |
| 628 | 649 | for (got.entries.items) |entry| { |
| 629 | 650 | const symbol = switch (entry.tag) { |
| ... | ... | @@ -651,7 +672,7 @@ pub const GotSection = struct { |
| 651 | 672 | }); |
| 652 | 673 | continue; |
| 653 | 674 | } |
| 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 | |
| 655 | 676 | !symbol.?.isAbs(elf_file)) |
| 656 | 677 | { |
| 657 | 678 | elf_file.addRelaDynAssumeCapacity(.{ |
| ... | ... | @@ -724,7 +745,8 @@ pub const GotSection = struct { |
| 724 | 745 | } |
| 725 | 746 | |
| 726 | 747 | 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(); | |
| 728 | 750 | var num: usize = 0; |
| 729 | 751 | for (got.entries.items) |entry| { |
| 730 | 752 | const symbol = switch (entry.tag) { |
| ... | ... | @@ -733,7 +755,7 @@ pub const GotSection = struct { |
| 733 | 755 | }; |
| 734 | 756 | switch (entry.tag) { |
| 735 | 757 | .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 | |
| 737 | 759 | !symbol.?.isAbs(elf_file))) |
| 738 | 760 | { |
| 739 | 761 | num += 1; |
| ... | ... | @@ -840,6 +862,8 @@ pub const PltSection = struct { |
| 840 | 862 | } |
| 841 | 863 | |
| 842 | 864 | 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; | |
| 843 | 867 | const index = @as(u32, @intCast(plt.symbols.items.len)); |
| 844 | 868 | const symbol = elf_file.symbol(sym_index); |
| 845 | 869 | symbol.flags.has_plt = true; |
| ... | ... | @@ -848,7 +872,7 @@ pub const PltSection = struct { |
| 848 | 872 | new_extra.plt = index; |
| 849 | 873 | symbol.setExtra(new_extra, elf_file); |
| 850 | 874 | } 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); | |
| 852 | 876 | } |
| 853 | 877 | |
| 854 | 878 | pub fn size(plt: PltSection) usize { |
| ... | ... | @@ -888,7 +912,9 @@ pub const PltSection = struct { |
| 888 | 912 | } |
| 889 | 913 | |
| 890 | 914 | 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()); | |
| 892 | 918 | for (plt.symbols.items) |sym_index| { |
| 893 | 919 | const sym = elf_file.symbol(sym_index); |
| 894 | 920 | assert(sym.flags.import); |
| ... | ... | @@ -1003,6 +1029,8 @@ pub const PltGotSection = struct { |
| 1003 | 1029 | } |
| 1004 | 1030 | |
| 1005 | 1031 | 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; | |
| 1006 | 1034 | const index = @as(u32, @intCast(plt_got.symbols.items.len)); |
| 1007 | 1035 | const symbol = elf_file.symbol(sym_index); |
| 1008 | 1036 | symbol.flags.has_plt = true; |
| ... | ... | @@ -1012,7 +1040,7 @@ pub const PltGotSection = struct { |
| 1012 | 1040 | new_extra.plt_got = index; |
| 1013 | 1041 | symbol.setExtra(new_extra, elf_file); |
| 1014 | 1042 | } 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); | |
| 1016 | 1044 | } |
| 1017 | 1045 | |
| 1018 | 1046 | pub fn size(plt_got: PltGotSection) usize { |
| ... | ... | @@ -1070,6 +1098,8 @@ pub const CopyRelSection = struct { |
| 1070 | 1098 | } |
| 1071 | 1099 | |
| 1072 | 1100 | 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; | |
| 1073 | 1103 | const index = @as(u32, @intCast(copy_rel.symbols.items.len)); |
| 1074 | 1104 | const symbol = elf_file.symbol(sym_index); |
| 1075 | 1105 | symbol.flags.import = true; |
| ... | ... | @@ -1082,7 +1112,7 @@ pub const CopyRelSection = struct { |
| 1082 | 1112 | new_extra.copy_rel = index; |
| 1083 | 1113 | symbol.setExtra(new_extra, elf_file); |
| 1084 | 1114 | } 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); | |
| 1086 | 1116 | |
| 1087 | 1117 | const shared_object = symbol.file(elf_file).?.shared_object; |
| 1088 | 1118 | if (shared_object.aliases == null) { |
| ... | ... | @@ -1122,7 +1152,9 @@ pub const CopyRelSection = struct { |
| 1122 | 1152 | } |
| 1123 | 1153 | |
| 1124 | 1154 | 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()); | |
| 1126 | 1158 | for (copy_rel.symbols.items) |sym_index| { |
| 1127 | 1159 | const sym = elf_file.symbol(sym_index); |
| 1128 | 1160 | assert(sym.flags.import and sym.flags.has_copy_rel); |
| ... | ... | @@ -1155,7 +1187,8 @@ pub const DynsymSection = struct { |
| 1155 | 1187 | } |
| 1156 | 1188 | |
| 1157 | 1189 | 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; | |
| 1159 | 1192 | const index = @as(u32, @intCast(dynsym.entries.items.len + 1)); |
| 1160 | 1193 | const sym = elf_file.symbol(sym_index); |
| 1161 | 1194 | sym.flags.has_dynamic = true; |
| ... | ... | @@ -1237,7 +1270,8 @@ pub const HashSection = struct { |
| 1237 | 1270 | pub fn generate(hs: *HashSection, elf_file: *Elf) !void { |
| 1238 | 1271 | if (elf_file.dynsym.count() == 1) return; |
| 1239 | 1272 | |
| 1240 | const gpa = elf_file.base.allocator; | |
| 1273 | const comp = elf_file.base.comp; | |
| 1274 | const gpa = comp.gpa; | |
| 1241 | 1275 | const nsyms = elf_file.dynsym.count(); |
| 1242 | 1276 | |
| 1243 | 1277 | var buckets = try gpa.alloc(u32, nsyms); |
| ... | ... | @@ -1325,7 +1359,8 @@ pub const GnuHashSection = struct { |
| 1325 | 1359 | try cwriter.writeInt(u32, hash.num_bloom, .little); |
| 1326 | 1360 | try cwriter.writeInt(u32, bloom_shift, .little); |
| 1327 | 1361 | |
| 1328 | const gpa = elf_file.base.allocator; | |
| 1362 | const comp = elf_file.base.comp; | |
| 1363 | const gpa = comp.gpa; | |
| 1329 | 1364 | const hashes = try gpa.alloc(u32, exports.len); |
| 1330 | 1365 | defer gpa.free(hashes); |
| 1331 | 1366 | const indices = try gpa.alloc(u32, exports.len); |
| ... | ... | @@ -1427,7 +1462,8 @@ pub const VerneedSection = struct { |
| 1427 | 1462 | } |
| 1428 | 1463 | }; |
| 1429 | 1464 | |
| 1430 | const gpa = elf_file.base.allocator; | |
| 1465 | const comp = elf_file.base.comp; | |
| 1466 | const gpa = comp.gpa; | |
| 1431 | 1467 | var verneed = std.ArrayList(VersionedSymbol).init(gpa); |
| 1432 | 1468 | defer verneed.deinit(); |
| 1433 | 1469 | try verneed.ensureTotalCapacity(dynsyms.len); |
| ... | ... | @@ -1483,7 +1519,8 @@ pub const VerneedSection = struct { |
| 1483 | 1519 | } |
| 1484 | 1520 | |
| 1485 | 1521 | 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; | |
| 1487 | 1524 | const sym = try vern.verneed.addOne(gpa); |
| 1488 | 1525 | sym.* = .{ |
| 1489 | 1526 | .vn_version = 1, |
| ... | ... | @@ -1501,7 +1538,8 @@ pub const VerneedSection = struct { |
| 1501 | 1538 | version: [:0]const u8, |
| 1502 | 1539 | elf_file: *Elf, |
| 1503 | 1540 | ) !elf.Elf64_Vernaux { |
| 1504 | const gpa = elf_file.base.allocator; | |
| 1541 | const comp = elf_file.base.comp; | |
| 1542 | const gpa = comp.gpa; | |
| 1505 | 1543 | const sym = try vern.vernaux.addOne(gpa); |
| 1506 | 1544 | sym.* = .{ |
| 1507 | 1545 | .vna_hash = HashSection.hasher(version), |
| ... | ... | @@ -1575,7 +1613,8 @@ pub const ComdatGroupSection = struct { |
| 1575 | 1613 | |
| 1576 | 1614 | fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void { |
| 1577 | 1615 | 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(); | |
| 1579 | 1618 | switch (entry_size) { |
| 1580 | 1619 | 2 => try writer.writeInt(u16, @intCast(value), endian), |
| 1581 | 1620 | 4 => try writer.writeInt(u32, @intCast(value), endian), |
src/link/MachO.zig+446-410| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | base: File, |
| 2 | entry_name: ?[]const u8, | |
| 2 | 3 | |
| 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. | |
| 4 | 5 | llvm_object: ?*LlvmObject = null, |
| 5 | 6 | |
| 6 | 7 | /// Debug symbols bundle (or dSym). |
| ... | ... | @@ -67,9 +68,6 @@ tlv_ptr_table: TableSection(SymbolWithLoc) = .{}, |
| 67 | 68 | thunk_table: std.AutoHashMapUnmanaged(Atom.Index, thunks.Thunk.Index) = .{}, |
| 68 | 69 | thunks: std.ArrayListUnmanaged(thunks.Thunk) = .{}, |
| 69 | 70 | |
| 70 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | |
| 71 | misc_errors: std.ArrayListUnmanaged(File.ErrorMsg) = .{}, | |
| 72 | ||
| 73 | 71 | segment_table_dirty: bool = false, |
| 74 | 72 | got_table_count_dirty: bool = false, |
| 75 | 73 | got_table_contents_dirty: bool = false, |
| ... | ... | @@ -77,12 +75,6 @@ stub_table_count_dirty: bool = false, |
| 77 | 75 | stub_table_contents_dirty: bool = false, |
| 78 | 76 | stub_helper_preamble_allocated: bool = false, |
| 79 | 77 | |
| 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. | |
| 84 | cold_start: bool = true, | |
| 85 | ||
| 86 | 78 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 87 | 79 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 88 | 80 | |
| ... | ... | @@ -143,89 +135,167 @@ tlv_table: TlvSymbolTable = .{}, |
| 143 | 135 | /// Hot-code swapping state. |
| 144 | 136 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| 145 | 137 | |
| 146 | pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { | |
| 147 | assert(options.target.ofmt == .macho); | |
| 138 | sdk_layout: ?SdkLayout, | |
| 139 | /// Size of the __PAGEZERO segment. | |
| 140 | pagezero_vmsize: u64, | |
| 141 | /// Minimum space for future expansion of the load commands. | |
| 142 | headerpad_size: u32, | |
| 143 | /// Set enough space as if all paths were MATPATHLEN. | |
| 144 | headerpad_max_install_names: bool, | |
| 145 | /// Remove dylibs that are unreachable by the entry point or exported symbols. | |
| 146 | dead_strip_dylibs: bool, | |
| 147 | frameworks: []const Framework, | |
| 148 | /// Install name for the dylib. | |
| 149 | /// TODO: unify with soname | |
| 150 | install_name: ?[]const u8, | |
| 151 | /// Path to entitlements file. | |
| 152 | entitlements: ?[]const u8, | |
| 153 | compatibility_version: ?std.SemanticVersion, | |
| 154 | ||
| 155 | /// When adding a new field, remember to update `hashAddFrameworks`. | |
| 156 | pub const Framework = struct { | |
| 157 | needed: bool = false, | |
| 158 | weak: bool = false, | |
| 159 | path: []const u8, | |
| 160 | }; | |
| 148 | 161 | |
| 149 | if (options.emit == null) { | |
| 150 | return createEmpty(allocator, options); | |
| 162 | pub 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); | |
| 151 | 167 | } |
| 168 | } | |
| 152 | 169 | |
| 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. | |
| 171 | pub 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 | ||
| 178 | pub 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}); | |
| 172 | 207 | |
| 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 | } | |
| 174 | 244 | errdefer self.base.destroy(); |
| 175 | 245 | |
| 246 | log.debug("selected linker mode '{s}'", .{@tagName(self.mode)}); | |
| 247 | ||
| 176 | 248 | 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 | |
| 181 | 250 | return self; |
| 182 | 251 | } |
| 183 | 252 | |
| 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, | |
| 186 | 255 | .read = true, |
| 187 | .mode = link.determineMode(options), | |
| 256 | .mode = link.File.determineMode(false, output_mode, link_mode), | |
| 188 | 257 | }); |
| 189 | errdefer file.close(); | |
| 190 | 258 | self.base.file = file; |
| 191 | 259 | |
| 192 | if (!options.strip and options.module != null) { | |
| 260 | if (comp.config.debug_format != .strip and comp.module != null) { | |
| 193 | 261 | // Create dSYM bundle. |
| 194 | log.debug("creating {s}.dSYM bundle", .{sub_path}); | |
| 262 | log.debug("creating {s}.dSYM bundle", .{emit.sub_path}); | |
| 195 | 263 | |
| 196 | 264 | const d_sym_path = try std.fmt.allocPrint( |
| 197 | allocator, | |
| 265 | arena, | |
| 198 | 266 | "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", |
| 199 | .{sub_path}, | |
| 267 | .{emit.sub_path}, | |
| 200 | 268 | ); |
| 201 | defer allocator.free(d_sym_path); | |
| 202 | 269 | |
| 203 | 270 | var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{}); |
| 204 | 271 | defer d_sym_bundle.close(); |
| 205 | 272 | |
| 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, .{ | |
| 207 | 274 | .truncate = false, |
| 208 | 275 | .read = true, |
| 209 | 276 | }); |
| 210 | 277 | |
| 211 | 278 | 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), | |
| 214 | 281 | .file = d_sym_file, |
| 215 | 282 | }; |
| 216 | 283 | } |
| 217 | 284 | |
| 218 | 285 | // Index 0 is always a null symbol. |
| 219 | try self.locals.append(allocator, .{ | |
| 286 | try self.locals.append(gpa, .{ | |
| 220 | 287 | .n_strx = 0, |
| 221 | 288 | .n_type = 0, |
| 222 | 289 | .n_sect = 0, |
| 223 | 290 | .n_desc = 0, |
| 224 | 291 | .n_value = 0, |
| 225 | 292 | }); |
| 226 | try self.strtab.buffer.append(allocator, 0); | |
| 293 | try self.strtab.buffer.append(gpa, 0); | |
| 227 | 294 | |
| 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 | }); | |
| 229 | 299 | |
| 230 | 300 | if (self.d_sym) |*d_sym| { |
| 231 | 301 | try d_sym.populateMissingMetadata(self); |
| ... | ... | @@ -234,75 +304,59 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { |
| 234 | 304 | return self; |
| 235 | 305 | } |
| 236 | 306 | |
| 237 | pub 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; | |
| 307 | pub 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); | |
| 261 | 316 | } |
| 262 | 317 | |
| 263 | pub 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 | } | |
| 318 | pub 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; | |
| 270 | 322 | |
| 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) { | |
| 272 | 324 | if (build_options.have_llvm) { |
| 273 | return self.base.linkAsArchive(comp, prog_node); | |
| 325 | return self.base.linkAsArchive(arena, prog_node); | |
| 274 | 326 | } 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"), | |
| 278 | 330 | }); |
| 279 | 331 | return error.FlushFailure; |
| 280 | 332 | } |
| 281 | 333 | } |
| 282 | 334 | |
| 283 | 335 | 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), | |
| 286 | 338 | } |
| 287 | 339 | } |
| 288 | 340 | |
| 289 | pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 341 | pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 290 | 342 | const tracy = trace(@src()); |
| 291 | 343 | defer tracy.end(); |
| 292 | 344 | |
| 345 | const comp = self.base.comp; | |
| 346 | const gpa = comp.gpa; | |
| 347 | ||
| 293 | 348 | 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; | |
| 295 | 351 | } |
| 296 | 352 | |
| 297 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | |
| 298 | defer arena_allocator.deinit(); | |
| 299 | const arena = arena_allocator.allocator(); | |
| 300 | ||
| 301 | 353 | var sub_prog_node = prog_node.start("MachO Flush", 0); |
| 302 | 354 | sub_prog_node.activate(); |
| 303 | 355 | defer sub_prog_node.end(); |
| 304 | 356 | |
| 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; | |
| 306 | 360 | |
| 307 | 361 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 308 | 362 | // 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 |
| 334 | 388 | } |
| 335 | 389 | |
| 336 | 390 | 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); | |
| 340 | 392 | |
| 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; | |
| 348 | 393 | self.base.releaseLock(); |
| 349 | 394 | |
| 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(); | |
| 401 | 401 | |
| 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); | |
| 405 | 403 | |
| 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(); | |
| 408 | 407 | |
| 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(); | |
| 420 | 410 | |
| 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); | |
| 422 | 421 | } |
| 423 | 422 | |
| 423 | try self.parseDependentLibs(&dependent_libs); | |
| 424 | ||
| 424 | 425 | try self.resolveSymbols(); |
| 425 | 426 | |
| 426 | 427 | if (self.getEntryPoint() == null) { |
| 427 | self.error_flags.no_entry_point_found = true; | |
| 428 | comp.link_error_flags.no_entry_point_found = true; | |
| 428 | 429 | } |
| 429 | 430 | if (self.unresolved.count() > 0) { |
| 430 | 431 | try self.reportUndefined(); |
| ... | ... | @@ -445,7 +446,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 445 | 446 | try self.createDyldPrivateAtom(); |
| 446 | 447 | try self.writeStubHelperPreamble(); |
| 447 | 448 | |
| 448 | if (self.base.options.output_mode == .Exe and self.getEntryPoint() != null) { | |
| 449 | if (output_mode == .Exe and self.getEntryPoint() != null) { | |
| 449 | 450 | const global = self.getEntryPoint().?; |
| 450 | 451 | if (self.getSymbol(global).undf()) { |
| 451 | 452 | // 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 |
| 470 | 471 | const section = self.sections.get(sym.n_sect - 1).header; |
| 471 | 472 | const file_offset = section.offset + sym.n_value - section.addr; |
| 472 | 473 | |
| 473 | var code = std.ArrayList(u8).init(self.base.allocator); | |
| 474 | var code = std.ArrayList(u8).init(gpa); | |
| 474 | 475 | defer code.deinit(); |
| 475 | 476 | try code.resize(math.cast(usize, atom.size) orelse return error.Overflow); |
| 476 | 477 | |
| ... | ... | @@ -509,21 +510,21 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 509 | 510 | |
| 510 | 511 | try self.writeLinkeditSegmentData(); |
| 511 | 512 | |
| 512 | var codesig: ?CodeSignature = if (requiresCodeSignature(&self.base.options)) blk: { | |
| 513 | var codesig: ?CodeSignature = if (self.requiresCodeSignature()) blk: { | |
| 513 | 514 | // Preallocate space for the code signature. |
| 514 | 515 | // We need to do this at this stage so that we have the load commands with proper values |
| 515 | 516 | // written out to the file. |
| 516 | 517 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment |
| 517 | 518 | // 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); | |
| 522 | 523 | } |
| 523 | 524 | try self.writeCodeSignaturePadding(&codesig); |
| 524 | 525 | break :blk codesig; |
| 525 | 526 | } else null; |
| 526 | defer if (codesig) |*csig| csig.deinit(self.base.allocator); | |
| 527 | defer if (codesig) |*csig| csig.deinit(gpa); | |
| 527 | 528 | |
| 528 | 529 | // Write load commands |
| 529 | 530 | var lc_buffer = std.ArrayList(u8).init(arena); |
| ... | ... | @@ -535,7 +536,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 535 | 536 | try lc_writer.writeStruct(self.dysymtab_cmd); |
| 536 | 537 | try load_commands.writeDylinkerLC(lc_writer); |
| 537 | 538 | |
| 538 | switch (self.base.options.output_mode) { | |
| 539 | switch (output_mode) { | |
| 539 | 540 | .Exe => blk: { |
| 540 | 541 | const seg_id = self.header_segment_cmd_index.?; |
| 541 | 542 | const seg = self.segments.items[seg_id]; |
| ... | ... | @@ -551,22 +552,22 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 551 | 552 | |
| 552 | 553 | try lc_writer.writeStruct(macho.entry_point_command{ |
| 553 | 554 | .entryoff = @as(u32, @intCast(addr - seg.vmaddr)), |
| 554 | .stacksize = self.base.options.stack_size_override orelse 0, | |
| 555 | .stacksize = self.base.stack_size, | |
| 555 | 556 | }); |
| 556 | 557 | }, |
| 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); | |
| 559 | 560 | }, |
| 560 | 561 | else => {}, |
| 561 | 562 | } |
| 562 | 563 | |
| 563 | try load_commands.writeRpathLCs(self.base.allocator, &self.base.options, lc_writer); | |
| 564 | try load_commands.writeRpathLCs(self, lc_writer); | |
| 564 | 565 | try lc_writer.writeStruct(macho.source_version_command{ |
| 565 | 566 | .version = 0, |
| 566 | 567 | }); |
| 567 | 568 | { |
| 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); | |
| 570 | 571 | if (platform.isBuildVersionCompatible()) { |
| 571 | 572 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| 572 | 573 | } else if (platform.isVersionMinCompatible()) { |
| ... | ... | @@ -590,7 +591,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 590 | 591 | |
| 591 | 592 | if (codesig) |*csig| { |
| 592 | 593 | try self.writeCodeSignature(comp, csig); // code signing always comes last |
| 593 | const emit = self.base.options.emit.?; | |
| 594 | const emit = self.base.emit; | |
| 594 | 595 | try invalidateKernelCache(emit.directory.handle, emit.sub_path); |
| 595 | 596 | } |
| 596 | 597 | |
| ... | ... | @@ -598,23 +599,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 598 | 599 | // Flush debug symbols bundle. |
| 599 | 600 | try d_sym.flushModule(self); |
| 600 | 601 | } |
| 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; | |
| 618 | 602 | } |
| 619 | 603 | |
| 620 | 604 | /// XNU starting with Big Sur running on arm64 is caching inodes of running binaries. |
| ... | ... | @@ -641,33 +625,20 @@ pub fn resolveLibSystem( |
| 641 | 625 | self: *MachO, |
| 642 | 626 | arena: Allocator, |
| 643 | 627 | comp: *Compilation, |
| 644 | search_dirs: []const []const u8, | |
| 645 | 628 | out_libs: anytype, |
| 646 | 629 | ) !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); | |
| 653 | 632 | |
| 654 | 633 | 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) { | |
| 664 | 635 | .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; | |
| 667 | 638 | }, |
| 668 | 639 | .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; | |
| 671 | 642 | }, |
| 672 | 643 | }; |
| 673 | 644 | |
| ... | ... | @@ -775,7 +746,8 @@ fn parseObject( |
| 775 | 746 | const tracy = trace(@src()); |
| 776 | 747 | defer tracy.end(); |
| 777 | 748 | |
| 778 | const gpa = self.base.allocator; | |
| 749 | const gpa = self.base.comp.gpa; | |
| 750 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 779 | 751 | const mtime: u64 = mtime: { |
| 780 | 752 | const stat = file.stat() catch break :mtime 0; |
| 781 | 753 | break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000))); |
| ... | ... | @@ -798,8 +770,8 @@ fn parseObject( |
| 798 | 770 | else => unreachable, |
| 799 | 771 | }; |
| 800 | 772 | 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); | |
| 803 | 775 | |
| 804 | 776 | if (this_cpu_arch != detected_cpu_arch or |
| 805 | 777 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -826,8 +798,10 @@ pub fn parseLibrary( |
| 826 | 798 | const tracy = trace(@src()); |
| 827 | 799 | defer tracy.end(); |
| 828 | 800 | |
| 801 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 802 | ||
| 829 | 803 | 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); | |
| 831 | 805 | try file.seekTo(offset); |
| 832 | 806 | |
| 833 | 807 | if (Archive.isArchive(file, offset)) { |
| ... | ... | @@ -868,7 +842,7 @@ pub fn parseFatLibrary( |
| 868 | 842 | cpu_arch: std.Target.Cpu.Arch, |
| 869 | 843 | ctx: *ParseErrorCtx, |
| 870 | 844 | ) ParseError!u64 { |
| 871 | const gpa = self.base.allocator; | |
| 845 | const gpa = self.base.comp.gpa; | |
| 872 | 846 | |
| 873 | 847 | const fat_archs = try fat.parseArchs(gpa, file); |
| 874 | 848 | defer gpa.free(fat_archs); |
| ... | ... | @@ -892,7 +866,8 @@ fn parseArchive( |
| 892 | 866 | must_link: bool, |
| 893 | 867 | ctx: *ParseErrorCtx, |
| 894 | 868 | ) 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; | |
| 896 | 871 | |
| 897 | 872 | // We take ownership of the file so that we can store it for the duration of symbol resolution. |
| 898 | 873 | // 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( |
| 922 | 897 | else => unreachable, |
| 923 | 898 | }; |
| 924 | 899 | 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); | |
| 927 | 902 | |
| 928 | 903 | if (this_cpu_arch != detected_cpu_arch or |
| 929 | 904 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -973,7 +948,8 @@ fn parseDylib( |
| 973 | 948 | dylib_options: DylibOpts, |
| 974 | 949 | ctx: *ParseErrorCtx, |
| 975 | 950 | ) 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; | |
| 977 | 953 | const file_stat = try file.stat(); |
| 978 | 954 | const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow; |
| 979 | 955 | |
| ... | ... | @@ -997,8 +973,8 @@ fn parseDylib( |
| 997 | 973 | else => unreachable, |
| 998 | 974 | }; |
| 999 | 975 | 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); | |
| 1002 | 978 | |
| 1003 | 979 | if (this_cpu_arch != detected_cpu_arch or |
| 1004 | 980 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -1019,7 +995,9 @@ fn parseLibStub( |
| 1019 | 995 | dylib_options: DylibOpts, |
| 1020 | 996 | ctx: *ParseErrorCtx, |
| 1021 | 997 | ) 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 | ||
| 1023 | 1001 | var lib_stub = try LibStub.loadFromFile(gpa, file); |
| 1024 | 1002 | defer lib_stub.deinit(); |
| 1025 | 1003 | |
| ... | ... | @@ -1027,7 +1005,7 @@ fn parseLibStub( |
| 1027 | 1005 | |
| 1028 | 1006 | // Verify target |
| 1029 | 1007 | { |
| 1030 | var matcher = try Dylib.TargetMatcher.init(gpa, self.base.options.target); | |
| 1008 | var matcher = try Dylib.TargetMatcher.init(gpa, target); | |
| 1031 | 1009 | defer matcher.deinit(); |
| 1032 | 1010 | |
| 1033 | 1011 | const first_tbd = lib_stub.inner[0]; |
| ... | ... | @@ -1050,7 +1028,7 @@ fn parseLibStub( |
| 1050 | 1028 | |
| 1051 | 1029 | try dylib.parseFromStub( |
| 1052 | 1030 | gpa, |
| 1053 | self.base.options.target, | |
| 1031 | target, | |
| 1054 | 1032 | lib_stub, |
| 1055 | 1033 | @intCast(self.dylibs.items.len), // TODO defer it till later |
| 1056 | 1034 | dependent_libs, |
| ... | ... | @@ -1072,7 +1050,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts, ctx: *ParseErr |
| 1072 | 1050 | } |
| 1073 | 1051 | } |
| 1074 | 1052 | |
| 1075 | const gpa = self.base.allocator; | |
| 1053 | const gpa = self.base.comp.gpa; | |
| 1076 | 1054 | const gop = try self.dylibs_map.getOrPut(gpa, dylib.id.?.name); |
| 1077 | 1055 | if (gop.found_existing) return error.DylibAlreadyExists; |
| 1078 | 1056 | |
| ... | ... | @@ -1080,7 +1058,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts, ctx: *ParseErr |
| 1080 | 1058 | try self.dylibs.append(gpa, dylib); |
| 1081 | 1059 | |
| 1082 | 1060 | 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; | |
| 1084 | 1062 | break :blk !(dylib_options.dependent or self.referenced_dylibs.contains(gop.value_ptr.*)); |
| 1085 | 1063 | }; |
| 1086 | 1064 | |
| ... | ... | @@ -1098,7 +1076,8 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { |
| 1098 | 1076 | // 2) afterwards, we parse dependents of the included dylibs |
| 1099 | 1077 | // TODO this should not be performed if the user specifies `-flat_namespace` flag. |
| 1100 | 1078 | // See ld64 manpages. |
| 1101 | const gpa = self.base.allocator; | |
| 1079 | const comp = self.base.comp; | |
| 1080 | const gpa = comp.gpa; | |
| 1102 | 1081 | |
| 1103 | 1082 | while (dependent_libs.readItem()) |dep_id| { |
| 1104 | 1083 | defer dep_id.id.deinit(gpa); |
| ... | ... | @@ -1118,7 +1097,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void { |
| 1118 | 1097 | var checked_paths = std.ArrayList([]const u8).init(arena); |
| 1119 | 1098 | |
| 1120 | 1099 | success: { |
| 1121 | if (self.base.options.sysroot) |root| { | |
| 1100 | if (comp.sysroot) |root| { | |
| 1122 | 1101 | const dir = try fs.path.join(arena, &[_][]const u8{ root, dirname }); |
| 1123 | 1102 | if (try accessLibPath(gpa, &test_path, &checked_paths, dir, stem)) break :success; |
| 1124 | 1103 | } |
| ... | ... | @@ -1162,7 +1141,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1162 | 1141 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); |
| 1163 | 1142 | |
| 1164 | 1143 | // 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); | |
| 1166 | 1146 | defer relocs.deinit(); |
| 1167 | 1147 | |
| 1168 | 1148 | if (self.relocs.getPtr(atom_index)) |rels| { |
| ... | ... | @@ -1194,7 +1174,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1194 | 1174 | |
| 1195 | 1175 | fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { |
| 1196 | 1176 | 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; | |
| 1198 | 1179 | const nwritten = if (!segment.isWriteable()) |
| 1199 | 1180 | try task.writeMemProtected(addr, code, cpu_arch) |
| 1200 | 1181 | else |
| ... | ... | @@ -1237,8 +1218,9 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 1237 | 1218 | fn writeStubHelperPreamble(self: *MachO) !void { |
| 1238 | 1219 | if (self.stub_helper_preamble_allocated) return; |
| 1239 | 1220 | |
| 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; | |
| 1242 | 1224 | const size = stubs.stubHelperPreambleSize(cpu_arch); |
| 1243 | 1225 | |
| 1244 | 1226 | var buf = try std.ArrayList(u8).initCapacity(gpa, size); |
| ... | ... | @@ -1264,11 +1246,12 @@ fn writeStubHelperPreamble(self: *MachO) !void { |
| 1264 | 1246 | } |
| 1265 | 1247 | |
| 1266 | 1248 | fn writeStubTableEntry(self: *MachO, index: usize) !void { |
| 1249 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1267 | 1250 | const stubs_sect_id = self.stubs_section_index.?; |
| 1268 | 1251 | const stub_helper_sect_id = self.stub_helper_section_index.?; |
| 1269 | 1252 | const laptr_sect_id = self.la_symbol_ptr_section_index.?; |
| 1270 | 1253 | |
| 1271 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 1254 | const cpu_arch = target.cpu.arch; | |
| 1272 | 1255 | const stub_entry_size = stubs.stubSize(cpu_arch); |
| 1273 | 1256 | const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch); |
| 1274 | 1257 | const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch); |
| ... | ... | @@ -1290,7 +1273,7 @@ fn writeStubTableEntry(self: *MachO, index: usize) !void { |
| 1290 | 1273 | self.stub_table_count_dirty = false; |
| 1291 | 1274 | } |
| 1292 | 1275 | |
| 1293 | const gpa = self.base.allocator; | |
| 1276 | const gpa = self.base.comp.gpa; | |
| 1294 | 1277 | |
| 1295 | 1278 | const stubs_header = self.sections.items(.header)[stubs_sect_id]; |
| 1296 | 1279 | const stub_helper_header = self.sections.items(.header)[stub_helper_sect_id]; |
| ... | ... | @@ -1469,7 +1452,7 @@ const CreateAtomOpts = struct { |
| 1469 | 1452 | }; |
| 1470 | 1453 | |
| 1471 | 1454 | pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Index { |
| 1472 | const gpa = self.base.allocator; | |
| 1455 | const gpa = self.base.comp.gpa; | |
| 1473 | 1456 | const index = @as(Atom.Index, @intCast(self.atoms.items.len)); |
| 1474 | 1457 | const atom = try self.atoms.addOne(gpa); |
| 1475 | 1458 | atom.* = .{}; |
| ... | ... | @@ -1481,7 +1464,7 @@ pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Inde |
| 1481 | 1464 | } |
| 1482 | 1465 | |
| 1483 | 1466 | pub fn createTentativeDefAtoms(self: *MachO) !void { |
| 1484 | const gpa = self.base.allocator; | |
| 1467 | const gpa = self.base.comp.gpa; | |
| 1485 | 1468 | |
| 1486 | 1469 | for (self.globals.items) |global| { |
| 1487 | 1470 | const sym = self.getSymbolPtr(global); |
| ... | ... | @@ -1536,7 +1519,8 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { |
| 1536 | 1519 | .size = @sizeOf(u64), |
| 1537 | 1520 | .alignment = .@"8", |
| 1538 | 1521 | }); |
| 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); | |
| 1540 | 1524 | |
| 1541 | 1525 | if (self.data_section_index == null) { |
| 1542 | 1526 | self.data_section_index = try self.initSection("__DATA", "__data", .{}); |
| ... | ... | @@ -1560,7 +1544,7 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { |
| 1560 | 1544 | } |
| 1561 | 1545 | |
| 1562 | 1546 | fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: SymbolWithLoc) !Atom.Index { |
| 1563 | const gpa = self.base.allocator; | |
| 1547 | const gpa = self.base.comp.gpa; | |
| 1564 | 1548 | const size = 3 * @sizeOf(u64); |
| 1565 | 1549 | const required_alignment: Alignment = .@"1"; |
| 1566 | 1550 | const sym_index = try self.allocateSymbol(); |
| ... | ... | @@ -1593,9 +1577,10 @@ fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: S |
| 1593 | 1577 | } |
| 1594 | 1578 | |
| 1595 | 1579 | pub 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; | |
| 1597 | 1582 | |
| 1598 | const gpa = self.base.allocator; | |
| 1583 | const gpa = self.base.comp.gpa; | |
| 1599 | 1584 | const sym_index = try self.allocateSymbol(); |
| 1600 | 1585 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 1601 | 1586 | const sym = self.getSymbolPtr(sym_loc); |
| ... | ... | @@ -1622,7 +1607,7 @@ pub fn createDsoHandleSymbol(self: *MachO) !void { |
| 1622 | 1607 | const global = self.getGlobalPtr("___dso_handle") orelse return; |
| 1623 | 1608 | if (!self.getSymbol(global.*).undf()) return; |
| 1624 | 1609 | |
| 1625 | const gpa = self.base.allocator; | |
| 1610 | const gpa = self.base.comp.gpa; | |
| 1626 | 1611 | const sym_index = try self.allocateSymbol(); |
| 1627 | 1612 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 1628 | 1613 | const sym = self.getSymbolPtr(sym_loc); |
| ... | ... | @@ -1643,16 +1628,19 @@ pub fn createDsoHandleSymbol(self: *MachO) !void { |
| 1643 | 1628 | } |
| 1644 | 1629 | |
| 1645 | 1630 | pub fn resolveSymbols(self: *MachO) !void { |
| 1631 | const comp = self.base.comp; | |
| 1632 | const output_mode = comp.config.output_mode; | |
| 1646 | 1633 | // We add the specified entrypoint as the first unresolved symbols so that |
| 1647 | 1634 | // we search for it in libraries should there be no object files specified |
| 1648 | 1635 | // 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 | } | |
| 1652 | 1640 | } |
| 1653 | 1641 | |
| 1654 | 1642 | // 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| { | |
| 1656 | 1644 | _ = try self.addUndefined(sym_name, .{}); |
| 1657 | 1645 | } |
| 1658 | 1646 | |
| ... | ... | @@ -1667,7 +1655,7 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1667 | 1655 | if (self.unresolved.count() > 0 and self.dyld_stub_binder_index == null) { |
| 1668 | 1656 | self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .{ .add_got = true }); |
| 1669 | 1657 | } |
| 1670 | if (!self.base.options.single_threaded and self.mode == .incremental) { | |
| 1658 | if (comp.config.any_non_single_threaded and self.mode == .incremental) { | |
| 1671 | 1659 | _ = try self.addUndefined("__tlv_bootstrap", .{}); |
| 1672 | 1660 | } |
| 1673 | 1661 | |
| ... | ... | @@ -1686,7 +1674,7 @@ pub fn resolveSymbols(self: *MachO) !void { |
| 1686 | 1674 | } |
| 1687 | 1675 | |
| 1688 | 1676 | fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { |
| 1689 | const gpa = self.base.allocator; | |
| 1677 | const gpa = self.base.comp.gpa; | |
| 1690 | 1678 | const sym = self.getSymbol(current); |
| 1691 | 1679 | const sym_name = self.getSymbolName(current); |
| 1692 | 1680 | |
| ... | ... | @@ -1800,7 +1788,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u32) !void { |
| 1800 | 1788 | fn resolveSymbolsInArchives(self: *MachO) !void { |
| 1801 | 1789 | if (self.archives.items.len == 0) return; |
| 1802 | 1790 | |
| 1803 | const gpa = self.base.allocator; | |
| 1791 | const gpa = self.base.comp.gpa; | |
| 1804 | 1792 | var next_sym: usize = 0; |
| 1805 | 1793 | loop: while (next_sym < self.unresolved.count()) { |
| 1806 | 1794 | const global = self.globals.items[self.unresolved.keys()[next_sym]]; |
| ... | ... | @@ -1829,7 +1817,7 @@ fn resolveSymbolsInArchives(self: *MachO) !void { |
| 1829 | 1817 | fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 1830 | 1818 | if (self.dylibs.items.len == 0) return; |
| 1831 | 1819 | |
| 1832 | const gpa = self.base.allocator; | |
| 1820 | const gpa = self.base.comp.gpa; | |
| 1833 | 1821 | var next_sym: usize = 0; |
| 1834 | 1822 | loop: while (next_sym < self.unresolved.count()) { |
| 1835 | 1823 | const global_index = self.unresolved.keys()[next_sym]; |
| ... | ... | @@ -1863,9 +1851,10 @@ fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 1863 | 1851 | } |
| 1864 | 1852 | |
| 1865 | 1853 | fn 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; | |
| 1869 | 1858 | |
| 1870 | 1859 | var next_sym: usize = 0; |
| 1871 | 1860 | while (next_sym < self.unresolved.count()) { |
| ... | ... | @@ -1899,6 +1888,7 @@ fn resolveSymbolsAtLoading(self: *MachO) !void { |
| 1899 | 1888 | } |
| 1900 | 1889 | |
| 1901 | 1890 | fn resolveBoundarySymbols(self: *MachO) !void { |
| 1891 | const gpa = self.base.comp.gpa; | |
| 1902 | 1892 | var next_sym: usize = 0; |
| 1903 | 1893 | while (next_sym < self.unresolved.count()) { |
| 1904 | 1894 | const global_index = self.unresolved.keys()[next_sym]; |
| ... | ... | @@ -1909,7 +1899,7 @@ fn resolveBoundarySymbols(self: *MachO) !void { |
| 1909 | 1899 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 1910 | 1900 | const sym = self.getSymbolPtr(sym_loc); |
| 1911 | 1901 | 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.*)), | |
| 1913 | 1903 | .n_type = macho.N_SECT | macho.N_EXT, |
| 1914 | 1904 | .n_sect = 0, |
| 1915 | 1905 | .n_desc = N_BOUNDARY, |
| ... | ... | @@ -1929,9 +1919,9 @@ fn resolveBoundarySymbols(self: *MachO) !void { |
| 1929 | 1919 | } |
| 1930 | 1920 | |
| 1931 | 1921 | pub fn deinit(self: *MachO) void { |
| 1932 | const gpa = self.base.allocator; | |
| 1922 | const gpa = self.base.comp.gpa; | |
| 1933 | 1923 | |
| 1934 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); | |
| 1924 | if (self.llvm_object) |llvm_object| llvm_object.deinit(); | |
| 1935 | 1925 | |
| 1936 | 1926 | if (self.d_sym) |*d_sym| { |
| 1937 | 1927 | d_sym.deinit(); |
| ... | ... | @@ -2024,15 +2014,10 @@ pub fn deinit(self: *MachO) void { |
| 2024 | 2014 | bindings.deinit(gpa); |
| 2025 | 2015 | } |
| 2026 | 2016 | self.bindings.deinit(gpa); |
| 2027 | ||
| 2028 | for (self.misc_errors.items) |*err| { | |
| 2029 | err.deinit(gpa); | |
| 2030 | } | |
| 2031 | self.misc_errors.deinit(gpa); | |
| 2032 | 2017 | } |
| 2033 | 2018 | |
| 2034 | 2019 | fn freeAtom(self: *MachO, atom_index: Atom.Index) void { |
| 2035 | const gpa = self.base.allocator; | |
| 2020 | const gpa = self.base.comp.gpa; | |
| 2036 | 2021 | log.debug("freeAtom {d}", .{atom_index}); |
| 2037 | 2022 | |
| 2038 | 2023 | // 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: |
| 2124 | 2109 | } |
| 2125 | 2110 | |
| 2126 | 2111 | pub 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); | |
| 2128 | 2114 | |
| 2129 | 2115 | const index = blk: { |
| 2130 | 2116 | if (self.locals_free_list.popOrNull()) |index| { |
| ... | ... | @@ -2150,7 +2136,8 @@ pub fn allocateSymbol(self: *MachO) !u32 { |
| 2150 | 2136 | } |
| 2151 | 2137 | |
| 2152 | 2138 | fn 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); | |
| 2154 | 2141 | |
| 2155 | 2142 | const index = blk: { |
| 2156 | 2143 | if (self.globals_free_list.popOrNull()) |index| { |
| ... | ... | @@ -2169,9 +2156,10 @@ fn allocateGlobal(self: *MachO) !u32 { |
| 2169 | 2156 | return index; |
| 2170 | 2157 | } |
| 2171 | 2158 | |
| 2172 | pub 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); | |
| 2159 | pub 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); | |
| 2175 | 2163 | if (self.got_section_index == null) { |
| 2176 | 2164 | self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{ |
| 2177 | 2165 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| ... | ... | @@ -2180,19 +2168,22 @@ pub fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2180 | 2168 | if (self.mode == .incremental) { |
| 2181 | 2169 | try self.writeOffsetTableEntry(got_index); |
| 2182 | 2170 | self.got_table_count_dirty = true; |
| 2183 | self.markRelocsDirtyByTarget(target); | |
| 2171 | self.markRelocsDirtyByTarget(reloc_target); | |
| 2184 | 2172 | } |
| 2185 | 2173 | } |
| 2186 | 2174 | |
| 2187 | pub 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); | |
| 2175 | pub 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); | |
| 2190 | 2181 | if (self.stubs_section_index == null) { |
| 2191 | 2182 | self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{ |
| 2192 | 2183 | .flags = macho.S_SYMBOL_STUBS | |
| 2193 | 2184 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 2194 | 2185 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2195 | .reserved2 = stubs.stubSize(self.base.options.target.cpu.arch), | |
| 2186 | .reserved2 = stubs.stubSize(cpu_arch), | |
| 2196 | 2187 | }); |
| 2197 | 2188 | self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{ |
| 2198 | 2189 | .flags = macho.S_REGULAR | |
| ... | ... | @@ -2206,13 +2197,14 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2206 | 2197 | if (self.mode == .incremental) { |
| 2207 | 2198 | try self.writeStubTableEntry(stub_index); |
| 2208 | 2199 | self.stub_table_count_dirty = true; |
| 2209 | self.markRelocsDirtyByTarget(target); | |
| 2200 | self.markRelocsDirtyByTarget(reloc_target); | |
| 2210 | 2201 | } |
| 2211 | 2202 | } |
| 2212 | 2203 | |
| 2213 | pub 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); | |
| 2204 | pub 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); | |
| 2216 | 2208 | if (self.tlv_ptr_section_index == null) { |
| 2217 | 2209 | self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{ |
| 2218 | 2210 | .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS, |
| ... | ... | @@ -2236,7 +2228,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air: |
| 2236 | 2228 | self.freeUnnamedConsts(decl_index); |
| 2237 | 2229 | Atom.freeRelocations(self, atom_index); |
| 2238 | 2230 | |
| 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); | |
| 2240 | 2233 | defer code_buffer.deinit(); |
| 2241 | 2234 | |
| 2242 | 2235 | 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: |
| 2279 | 2272 | } |
| 2280 | 2273 | |
| 2281 | 2274 | pub 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.?; | |
| 2284 | 2277 | const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index); |
| 2285 | 2278 | if (!gop.found_existing) { |
| 2286 | 2279 | gop.value_ptr.* = .{}; |
| ... | ... | @@ -2318,7 +2311,7 @@ fn lowerConst( |
| 2318 | 2311 | sect_id: u8, |
| 2319 | 2312 | src_loc: Module.SrcLoc, |
| 2320 | 2313 | ) !LowerConstResult { |
| 2321 | const gpa = self.base.allocator; | |
| 2314 | const gpa = self.base.comp.gpa; | |
| 2322 | 2315 | |
| 2323 | 2316 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 2324 | 2317 | defer code_buffer.deinit(); |
| ... | ... | @@ -2366,6 +2359,8 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 2366 | 2359 | const tracy = trace(@src()); |
| 2367 | 2360 | defer tracy.end(); |
| 2368 | 2361 | |
| 2362 | const comp = self.base.comp; | |
| 2363 | const gpa = comp.gpa; | |
| 2369 | 2364 | const decl = mod.declPtr(decl_index); |
| 2370 | 2365 | |
| 2371 | 2366 | if (decl.val.getExternFunc(mod)) |_| { |
| ... | ... | @@ -2375,14 +2370,14 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 2375 | 2370 | if (decl.isExtern(mod)) { |
| 2376 | 2371 | // TODO make this part of getGlobalSymbol |
| 2377 | 2372 | 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); | |
| 2380 | 2375 | _ = try self.addUndefined(sym_name, .{ .add_got = true }); |
| 2381 | 2376 | return; |
| 2382 | 2377 | } |
| 2383 | 2378 | |
| 2384 | 2379 | 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 | |
| 2386 | 2381 | else |
| 2387 | 2382 | false; |
| 2388 | 2383 | if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index); |
| ... | ... | @@ -2391,7 +2386,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex) |
| 2391 | 2386 | const sym_index = self.getAtom(atom_index).getSymbolIndex().?; |
| 2392 | 2387 | Atom.freeRelocations(self, atom_index); |
| 2393 | 2388 | |
| 2394 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | |
| 2389 | var code_buffer = std.ArrayList(u8).init(gpa); | |
| 2395 | 2390 | defer code_buffer.deinit(); |
| 2396 | 2391 | |
| 2397 | 2392 | var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym| |
| ... | ... | @@ -2449,8 +2444,8 @@ fn updateLazySymbolAtom( |
| 2449 | 2444 | atom_index: Atom.Index, |
| 2450 | 2445 | section_index: u8, |
| 2451 | 2446 | ) !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.?; | |
| 2454 | 2449 | |
| 2455 | 2450 | var required_alignment: Alignment = .none; |
| 2456 | 2451 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -2514,8 +2509,9 @@ fn updateLazySymbolAtom( |
| 2514 | 2509 | } |
| 2515 | 2510 | |
| 2516 | 2511 | pub 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)); | |
| 2519 | 2515 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 2520 | 2516 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 2521 | 2517 | 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 |
| 2529 | 2525 | .unused => { |
| 2530 | 2526 | const sym_index = try self.allocateSymbol(); |
| 2531 | 2527 | 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.*); | |
| 2533 | 2529 | }, |
| 2534 | 2530 | .pending_flush => return metadata.atom.*, |
| 2535 | 2531 | .flushed => {}, |
| ... | ... | @@ -2545,7 +2541,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In |
| 2545 | 2541 | } |
| 2546 | 2542 | |
| 2547 | 2543 | fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void { |
| 2548 | const mod = self.base.options.module.?; | |
| 2544 | const mod = self.base.comp.module.?; | |
| 2549 | 2545 | // Lowering a TLV on macOS involves two stages: |
| 2550 | 2546 | // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss) |
| 2551 | 2547 | // 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 |
| 2556 | 2552 | const init_sym_index = init_atom.getSymbolIndex().?; |
| 2557 | 2553 | Atom.freeRelocations(self, init_atom_index); |
| 2558 | 2554 | |
| 2559 | const gpa = self.base.allocator; | |
| 2555 | const gpa = self.base.comp.gpa; | |
| 2560 | 2556 | |
| 2561 | 2557 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 2562 | 2558 | defer code_buffer.deinit(); |
| ... | ... | @@ -2640,11 +2636,12 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: InternPo |
| 2640 | 2636 | } |
| 2641 | 2637 | |
| 2642 | 2638 | pub 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); | |
| 2644 | 2641 | if (!gop.found_existing) { |
| 2645 | 2642 | const sym_index = try self.allocateSymbol(); |
| 2646 | 2643 | 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); | |
| 2648 | 2645 | gop.value_ptr.* = .{ |
| 2649 | 2646 | .atom = atom_index, |
| 2650 | 2647 | .section = self.getDeclOutputSection(decl_index), |
| ... | ... | @@ -2655,17 +2652,17 @@ pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: InternPool.DeclIndex) !A |
| 2655 | 2652 | } |
| 2656 | 2653 | |
| 2657 | 2654 | fn 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); | |
| 2659 | 2656 | const ty = decl.ty; |
| 2660 | 2657 | const val = decl.val; |
| 2661 | const mod = self.base.options.module.?; | |
| 2658 | const mod = self.base.comp.module.?; | |
| 2662 | 2659 | 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; | |
| 2665 | 2662 | const sect_id: u8 = blk: { |
| 2666 | 2663 | // TODO finish and audit this function |
| 2667 | 2664 | if (val.isUndefDeep(mod)) { |
| 2668 | if (mode == .ReleaseFast or mode == .ReleaseSmall) { | |
| 2665 | if (optimize_mode == .ReleaseFast or optimize_mode == .ReleaseSmall) { | |
| 2669 | 2666 | @panic("TODO __DATA,__bss"); |
| 2670 | 2667 | } else { |
| 2671 | 2668 | break :blk self.data_section_index.?; |
| ... | ... | @@ -2673,7 +2670,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: InternPool.DeclIndex) u8 { |
| 2673 | 2670 | } |
| 2674 | 2671 | |
| 2675 | 2672 | if (val.getVariable(mod)) |variable| { |
| 2676 | if (variable.is_threadlocal and !single_threaded) { | |
| 2673 | if (variable.is_threadlocal and any_non_single_threaded) { | |
| 2677 | 2674 | break :blk self.thread_data_section_index.?; |
| 2678 | 2675 | } |
| 2679 | 2676 | break :blk self.data_section_index.?; |
| ... | ... | @@ -2694,8 +2691,8 @@ fn getDeclOutputSection(self: *MachO, decl_index: InternPool.DeclIndex) u8 { |
| 2694 | 2691 | } |
| 2695 | 2692 | |
| 2696 | 2693 | fn 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.?; | |
| 2699 | 2696 | const decl = mod.declPtr(decl_index); |
| 2700 | 2697 | |
| 2701 | 2698 | const required_alignment = decl.getAlignment(mod); |
| ... | ... | @@ -2782,12 +2779,10 @@ pub fn updateExports( |
| 2782 | 2779 | if (self.llvm_object) |llvm_object| |
| 2783 | 2780 | return llvm_object.updateExports(mod, exported, exports); |
| 2784 | 2781 | |
| 2785 | if (self.base.options.emit == null) return; | |
| 2786 | ||
| 2787 | 2782 | const tracy = trace(@src()); |
| 2788 | 2783 | defer tracy.end(); |
| 2789 | 2784 | |
| 2790 | const gpa = self.base.allocator; | |
| 2785 | const gpa = self.base.comp.gpa; | |
| 2791 | 2786 | |
| 2792 | 2787 | const metadata = switch (exported) { |
| 2793 | 2788 | .decl_index => |decl_index| blk: { |
| ... | ... | @@ -2912,8 +2907,8 @@ pub fn deleteDeclExport( |
| 2912 | 2907 | if (self.llvm_object) |_| return; |
| 2913 | 2908 | const metadata = self.decls.getPtr(decl_index) orelse return; |
| 2914 | 2909 | |
| 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.?; | |
| 2917 | 2912 | const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{mod.intern_pool.stringToSlice(name)}); |
| 2918 | 2913 | defer gpa.free(exp_name); |
| 2919 | 2914 | const sym_index = metadata.getExportPtr(self, exp_name) orelse return; |
| ... | ... | @@ -2941,7 +2936,7 @@ pub fn deleteDeclExport( |
| 2941 | 2936 | } |
| 2942 | 2937 | |
| 2943 | 2938 | fn freeUnnamedConsts(self: *MachO, decl_index: InternPool.DeclIndex) void { |
| 2944 | const gpa = self.base.allocator; | |
| 2939 | const gpa = self.base.comp.gpa; | |
| 2945 | 2940 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 2946 | 2941 | for (unnamed_consts.items) |atom| { |
| 2947 | 2942 | self.freeAtom(atom); |
| ... | ... | @@ -2951,7 +2946,8 @@ fn freeUnnamedConsts(self: *MachO, decl_index: InternPool.DeclIndex) void { |
| 2951 | 2946 | |
| 2952 | 2947 | pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { |
| 2953 | 2948 | 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.?; | |
| 2955 | 2951 | const decl = mod.declPtr(decl_index); |
| 2956 | 2952 | |
| 2957 | 2953 | log.debug("freeDecl {*}", .{decl}); |
| ... | ... | @@ -2960,7 +2956,7 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { |
| 2960 | 2956 | var kv = const_kv; |
| 2961 | 2957 | self.freeAtom(kv.value.atom); |
| 2962 | 2958 | self.freeUnnamedConsts(decl_index); |
| 2963 | kv.value.exports.deinit(self.base.allocator); | |
| 2959 | kv.value.exports.deinit(gpa); | |
| 2964 | 2960 | } |
| 2965 | 2961 | |
| 2966 | 2962 | if (self.d_sym) |*d_sym| { |
| ... | ... | @@ -2993,8 +2989,8 @@ pub fn lowerAnonDecl( |
| 2993 | 2989 | explicit_alignment: InternPool.Alignment, |
| 2994 | 2990 | src_loc: Module.SrcLoc, |
| 2995 | 2991 | ) !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.?; | |
| 2998 | 2994 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 2999 | 2995 | const decl_alignment = switch (explicit_alignment) { |
| 3000 | 2996 | .none => ty.abiAlignment(mod), |
| ... | ... | @@ -3057,11 +3053,18 @@ pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: li |
| 3057 | 3053 | return 0; |
| 3058 | 3054 | } |
| 3059 | 3055 | |
| 3060 | fn populateMissingMetadata(self: *MachO) !void { | |
| 3056 | const PopulateMissingMetadataOptions = struct { | |
| 3057 | symbol_count_hint: u64, | |
| 3058 | program_code_size_hint: u64, | |
| 3059 | }; | |
| 3060 | ||
| 3061 | fn populateMissingMetadata(self: *MachO, options: PopulateMissingMetadataOptions) !void { | |
| 3061 | 3062 | assert(self.mode == .incremental); |
| 3062 | 3063 | |
| 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; | |
| 3065 | 3068 | const pagezero_vmsize = self.calcPagezeroSize(); |
| 3066 | 3069 | |
| 3067 | 3070 | if (self.pagezero_segment_cmd_index == null) { |
| ... | ... | @@ -3078,7 +3081,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3078 | 3081 | if (self.header_segment_cmd_index == null) { |
| 3079 | 3082 | // The first __TEXT segment is immovable and covers MachO header and load commands. |
| 3080 | 3083 | 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; | |
| 3082 | 3085 | const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), getPageSize(cpu_arch)); |
| 3083 | 3086 | |
| 3084 | 3087 | 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 { |
| 3098 | 3101 | if (self.text_section_index == null) { |
| 3099 | 3102 | // Sadly, segments need unique string identfiers for some reason. |
| 3100 | 3103 | 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, | |
| 3102 | 3105 | .alignment = switch (cpu_arch) { |
| 3103 | 3106 | .x86_64 => 1, |
| 3104 | 3107 | .aarch64 => @sizeOf(u32), |
| ... | ... | @@ -3134,7 +3137,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3134 | 3137 | |
| 3135 | 3138 | if (self.got_section_index == null) { |
| 3136 | 3139 | 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, | |
| 3138 | 3141 | .alignment = @alignOf(u64), |
| 3139 | 3142 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 3140 | 3143 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| ... | ... | @@ -3172,7 +3175,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3172 | 3175 | self.segment_table_dirty = true; |
| 3173 | 3176 | } |
| 3174 | 3177 | |
| 3175 | if (!self.base.options.single_threaded) { | |
| 3178 | if (comp.config.any_non_single_threaded) { | |
| 3176 | 3179 | if (self.thread_vars_section_index == null) { |
| 3177 | 3180 | self.thread_vars_section_index = try self.allocateSection("__DATA2", "__thread_vars", .{ |
| 3178 | 3181 | .size = @sizeOf(u64) * 3, |
| ... | ... | @@ -3207,13 +3210,14 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3207 | 3210 | } |
| 3208 | 3211 | |
| 3209 | 3212 | fn 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; | |
| 3214 | 3218 | 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}); | |
| 3217 | 3221 | log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize}); |
| 3218 | 3222 | } |
| 3219 | 3223 | return aligned_pagezero_vmsize; |
| ... | ... | @@ -3228,7 +3232,8 @@ const InitSectionOpts = struct { |
| 3228 | 3232 | pub fn initSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: InitSectionOpts) !u8 { |
| 3229 | 3233 | log.debug("creating section '{s},{s}'", .{ segname, sectname }); |
| 3230 | 3234 | 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, .{ | |
| 3232 | 3237 | .segment_index = undefined, // Segments will be created automatically later down the pipeline |
| 3233 | 3238 | .header = .{ |
| 3234 | 3239 | .sectname = makeStaticString(sectname), |
| ... | ... | @@ -3248,8 +3253,9 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 3248 | 3253 | flags: u32 = macho.S_REGULAR, |
| 3249 | 3254 | reserved2: u32 = 0, |
| 3250 | 3255 | }) !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); | |
| 3253 | 3259 | // In incremental context, we create one section per segment pairing. This way, |
| 3254 | 3260 | // we can move the segment in raw file as we please. |
| 3255 | 3261 | 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 { |
| 3304 | 3310 | const segment = &self.segments.items[segment_index]; |
| 3305 | 3311 | const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; |
| 3306 | 3312 | 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); | |
| 3308 | 3315 | |
| 3309 | 3316 | if (needed_size > sect_capacity) { |
| 3310 | 3317 | const new_offset = self.findFreeSpace(needed_size, page_size); |
| ... | ... | @@ -3344,7 +3351,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 3344 | 3351 | } |
| 3345 | 3352 | |
| 3346 | 3353 | fn 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); | |
| 3348 | 3356 | const header = &self.sections.items(.header)[sect_id]; |
| 3349 | 3357 | const segment = self.getSegmentPtr(sect_id); |
| 3350 | 3358 | const increased_size = padToIdeal(needed_size); |
| ... | ... | @@ -3521,7 +3529,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm |
| 3521 | 3529 | |
| 3522 | 3530 | pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { |
| 3523 | 3531 | _ = lib_name; |
| 3524 | const gpa = self.base.allocator; | |
| 3532 | const gpa = self.base.comp.gpa; | |
| 3525 | 3533 | const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); |
| 3526 | 3534 | defer gpa.free(sym_name); |
| 3527 | 3535 | return self.addUndefined(sym_name, .{ .add_stub = true }); |
| ... | ... | @@ -3555,7 +3563,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void { |
| 3555 | 3563 | } |
| 3556 | 3564 | |
| 3557 | 3565 | pub 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); | |
| 3559 | 3568 | const seg = self.getLinkeditSegmentPtr(); |
| 3560 | 3569 | seg.filesize = 0; |
| 3561 | 3570 | seg.vmsize = 0; |
| ... | ... | @@ -3582,7 +3591,7 @@ pub fn writeLinkeditSegmentData(self: *MachO) !void { |
| 3582 | 3591 | } |
| 3583 | 3592 | |
| 3584 | 3593 | fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase, table: anytype) !void { |
| 3585 | const gpa = self.base.allocator; | |
| 3594 | const gpa = self.base.comp.gpa; | |
| 3586 | 3595 | const header = self.sections.items(.header)[sect_id]; |
| 3587 | 3596 | const segment_index = self.sections.items(.segment_index)[sect_id]; |
| 3588 | 3597 | const segment = self.segments.items[segment_index]; |
| ... | ... | @@ -3605,7 +3614,7 @@ fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase, |
| 3605 | 3614 | } |
| 3606 | 3615 | |
| 3607 | 3616 | fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3608 | const gpa = self.base.allocator; | |
| 3617 | const gpa = self.base.comp.gpa; | |
| 3609 | 3618 | const slice = self.sections.slice(); |
| 3610 | 3619 | |
| 3611 | 3620 | for (self.rebases.keys(), 0..) |atom_index, i| { |
| ... | ... | @@ -3642,7 +3651,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3642 | 3651 | } |
| 3643 | 3652 | |
| 3644 | 3653 | // 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; | |
| 3646 | 3656 | for (self.objects.items) |*object| { |
| 3647 | 3657 | for (object.atoms.items) |atom_index| { |
| 3648 | 3658 | const atom = self.getAtom(atom_index); |
| ... | ... | @@ -3688,14 +3698,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3688 | 3698 | }, |
| 3689 | 3699 | else => unreachable, |
| 3690 | 3700 | } |
| 3691 | const target = Atom.parseRelocTarget(self, .{ | |
| 3701 | const reloc_target = Atom.parseRelocTarget(self, .{ | |
| 3692 | 3702 | .object_id = atom.getFile().?, |
| 3693 | 3703 | .rel = rel, |
| 3694 | 3704 | .code = code, |
| 3695 | 3705 | .base_offset = ctx.base_offset, |
| 3696 | 3706 | .base_addr = ctx.base_addr, |
| 3697 | 3707 | }); |
| 3698 | const target_sym = self.getSymbol(target); | |
| 3708 | const target_sym = self.getSymbol(reloc_target); | |
| 3699 | 3709 | if (target_sym.undf()) continue; |
| 3700 | 3710 | |
| 3701 | 3711 | const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr)); |
| ... | ... | @@ -3715,7 +3725,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3715 | 3725 | } |
| 3716 | 3726 | |
| 3717 | 3727 | fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void { |
| 3718 | const gpa = self.base.allocator; | |
| 3728 | const gpa = self.base.comp.gpa; | |
| 3719 | 3729 | const header = self.sections.items(.header)[sect_id]; |
| 3720 | 3730 | const segment_index = self.sections.items(.segment_index)[sect_id]; |
| 3721 | 3731 | const segment = self.segments.items[segment_index]; |
| ... | ... | @@ -3746,7 +3756,7 @@ fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, tab |
| 3746 | 3756 | } |
| 3747 | 3757 | |
| 3748 | 3758 | fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3749 | const gpa = self.base.allocator; | |
| 3759 | const gpa = self.base.comp.gpa; | |
| 3750 | 3760 | const slice = self.sections.slice(); |
| 3751 | 3761 | |
| 3752 | 3762 | for (raw_bindings.keys(), 0..) |atom_index, i| { |
| ... | ... | @@ -3797,7 +3807,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3797 | 3807 | } |
| 3798 | 3808 | |
| 3799 | 3809 | // 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; | |
| 3801 | 3812 | for (self.objects.items) |*object| { |
| 3802 | 3813 | for (object.atoms.items) |atom_index| { |
| 3803 | 3814 | const atom = self.getAtom(atom_index); |
| ... | ... | @@ -3885,12 +3896,13 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3885 | 3896 | |
| 3886 | 3897 | fn collectLazyBindData(self: *MachO, bind: anytype) !void { |
| 3887 | 3898 | const sect_id = self.la_symbol_ptr_section_index orelse return; |
| 3899 | const gpa = self.base.comp.gpa; | |
| 3888 | 3900 | try self.collectBindDataFromTableSection(sect_id, bind, self.stub_table); |
| 3889 | try bind.finalize(self.base.allocator, self); | |
| 3901 | try bind.finalize(gpa, self); | |
| 3890 | 3902 | } |
| 3891 | 3903 | |
| 3892 | 3904 | fn collectExportData(self: *MachO, trie: *Trie) !void { |
| 3893 | const gpa = self.base.allocator; | |
| 3905 | const gpa = self.base.comp.gpa; | |
| 3894 | 3906 | |
| 3895 | 3907 | // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER. |
| 3896 | 3908 | log.debug("generating export trie", .{}); |
| ... | ... | @@ -3922,7 +3934,7 @@ fn writeDyldInfoData(self: *MachO) !void { |
| 3922 | 3934 | const tracy = trace(@src()); |
| 3923 | 3935 | defer tracy.end(); |
| 3924 | 3936 | |
| 3925 | const gpa = self.base.allocator; | |
| 3937 | const gpa = self.base.comp.gpa; | |
| 3926 | 3938 | |
| 3927 | 3939 | var rebase = Rebase{}; |
| 3928 | 3940 | defer rebase.deinit(gpa); |
| ... | ... | @@ -4015,7 +4027,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void { |
| 4015 | 4027 | |
| 4016 | 4028 | const header = self.sections.items(.header)[stub_helper_section_index]; |
| 4017 | 4029 | |
| 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; | |
| 4019 | 4032 | const preamble_size = stubs.stubHelperPreambleSize(cpu_arch); |
| 4020 | 4033 | const stub_size = stubs.stubHelperSize(cpu_arch); |
| 4021 | 4034 | const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch); |
| ... | ... | @@ -4046,7 +4059,7 @@ fn addSymbolToFunctionStarts(self: *MachO, sym_loc: SymbolWithLoc, addresses: *s |
| 4046 | 4059 | } |
| 4047 | 4060 | |
| 4048 | 4061 | fn writeFunctionStarts(self: *MachO) !void { |
| 4049 | const gpa = self.base.allocator; | |
| 4062 | const gpa = self.base.comp.gpa; | |
| 4050 | 4063 | const seg = self.segments.items[self.header_segment_cmd_index.?]; |
| 4051 | 4064 | |
| 4052 | 4065 | // We need to sort by address first |
| ... | ... | @@ -4133,7 +4146,7 @@ fn filterDataInCode( |
| 4133 | 4146 | } |
| 4134 | 4147 | |
| 4135 | 4148 | pub fn writeDataInCode(self: *MachO) !void { |
| 4136 | const gpa = self.base.allocator; | |
| 4149 | const gpa = self.base.comp.gpa; | |
| 4137 | 4150 | var out_dice = std.ArrayList(macho.data_in_code_entry).init(gpa); |
| 4138 | 4151 | defer out_dice.deinit(); |
| 4139 | 4152 | |
| ... | ... | @@ -4211,13 +4224,15 @@ fn addLocalToSymtab(self: *MachO, sym_loc: SymbolWithLoc, locals: *std.ArrayList |
| 4211 | 4224 | if (sym.n_desc == N_BOUNDARY) return; // boundary symbol, skip |
| 4212 | 4225 | if (sym.ext()) return; // an export lands in its own symtab section, skip |
| 4213 | 4226 | if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip |
| 4227 | const gpa = self.base.comp.gpa; | |
| 4214 | 4228 | 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)); | |
| 4216 | 4230 | try locals.append(out_sym); |
| 4217 | 4231 | } |
| 4218 | 4232 | |
| 4219 | 4233 | fn writeSymtab(self: *MachO) !SymtabCtx { |
| 4220 | const gpa = self.base.allocator; | |
| 4234 | const comp = self.base.comp; | |
| 4235 | const gpa = comp.gpa; | |
| 4221 | 4236 | |
| 4222 | 4237 | var locals = std.ArrayList(macho.nlist_64).init(gpa); |
| 4223 | 4238 | defer locals.deinit(); |
| ... | ... | @@ -4272,7 +4287,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx { |
| 4272 | 4287 | |
| 4273 | 4288 | // We generate stabs last in order to ensure that the strtab always has debug info |
| 4274 | 4289 | // strings trailing |
| 4275 | if (!self.base.options.strip) { | |
| 4290 | if (comp.config.debug_format != .strip) { | |
| 4276 | 4291 | for (self.objects.items) |object| { |
| 4277 | 4292 | assert(self.d_sym == null); // TODO |
| 4278 | 4293 | try self.generateSymbolStabs(object, &locals); |
| ... | ... | @@ -4322,7 +4337,7 @@ fn generateSymbolStabs( |
| 4322 | 4337 | ) !void { |
| 4323 | 4338 | log.debug("generating stabs for '{s}'", .{object.name}); |
| 4324 | 4339 | |
| 4325 | const gpa = self.base.allocator; | |
| 4340 | const gpa = self.base.comp.gpa; | |
| 4326 | 4341 | var debug_info = object.parseDwarfInfo(); |
| 4327 | 4342 | |
| 4328 | 4343 | var lookup = DwarfInfo.AbbrevLookupTable.init(gpa); |
| ... | ... | @@ -4450,7 +4465,7 @@ fn generateSymbolStabsForSymbol( |
| 4450 | 4465 | lookup: ?DwarfInfo.SubprogramLookupByName, |
| 4451 | 4466 | buf: *[4]macho.nlist_64, |
| 4452 | 4467 | ) ![]const macho.nlist_64 { |
| 4453 | const gpa = self.base.allocator; | |
| 4468 | const gpa = self.base.comp.gpa; | |
| 4454 | 4469 | const object = self.objects.items[sym_loc.getFile().?]; |
| 4455 | 4470 | const sym = self.getSymbol(sym_loc); |
| 4456 | 4471 | const sym_name = self.getSymbolName(sym_loc); |
| ... | ... | @@ -4536,7 +4551,7 @@ fn generateSymbolStabsForSymbol( |
| 4536 | 4551 | } |
| 4537 | 4552 | |
| 4538 | 4553 | pub fn writeStrtab(self: *MachO) !void { |
| 4539 | const gpa = self.base.allocator; | |
| 4554 | const gpa = self.base.comp.gpa; | |
| 4540 | 4555 | const seg = self.getLinkeditSegmentPtr(); |
| 4541 | 4556 | const offset = seg.fileoff + seg.filesize; |
| 4542 | 4557 | assert(mem.isAlignedGeneric(u64, offset, @alignOf(u64))); |
| ... | ... | @@ -4565,7 +4580,7 @@ const SymtabCtx = struct { |
| 4565 | 4580 | }; |
| 4566 | 4581 | |
| 4567 | 4582 | pub fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void { |
| 4568 | const gpa = self.base.allocator; | |
| 4583 | const gpa = self.base.comp.gpa; | |
| 4569 | 4584 | const nstubs = @as(u32, @intCast(self.stub_table.lookup.count())); |
| 4570 | 4585 | const ngot_entries = @as(u32, @intCast(self.got_table.lookup.count())); |
| 4571 | 4586 | const nindirectsyms = nstubs * 2 + ngot_entries; |
| ... | ... | @@ -4650,13 +4665,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h |
| 4650 | 4665 | } |
| 4651 | 4666 | |
| 4652 | 4667 | pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void { |
| 4668 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4653 | 4669 | const seg = self.getLinkeditSegmentPtr(); |
| 4654 | 4670 | // Code signature data has to be 16-bytes aligned for Apple tools to recognize the file |
| 4655 | 4671 | // https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L271 |
| 4656 | 4672 | const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16); |
| 4657 | 4673 | const needed_size = code_sig.estimateSize(offset); |
| 4658 | 4674 | 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)); | |
| 4660 | 4676 | log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size }); |
| 4661 | 4677 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 4662 | 4678 | // except for code signature data. |
| ... | ... | @@ -4667,11 +4683,13 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void { |
| 4667 | 4683 | } |
| 4668 | 4684 | |
| 4669 | 4685 | pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *CodeSignature) !void { |
| 4686 | const output_mode = self.base.comp.config.output_mode; | |
| 4670 | 4687 | const seg_id = self.header_segment_cmd_index.?; |
| 4671 | 4688 | const seg = self.segments.items[seg_id]; |
| 4672 | 4689 | const offset = self.codesig_cmd.dataoff; |
| 4673 | 4690 | |
| 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); | |
| 4675 | 4693 | defer buffer.deinit(); |
| 4676 | 4694 | try buffer.ensureTotalCapacityPrecise(code_sig.size()); |
| 4677 | 4695 | try code_sig.writeAdhocSignature(comp, .{ |
| ... | ... | @@ -4679,7 +4697,7 @@ pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *Cod |
| 4679 | 4697 | .exec_seg_base = seg.fileoff, |
| 4680 | 4698 | .exec_seg_limit = seg.filesize, |
| 4681 | 4699 | .file_size = offset, |
| 4682 | .output_mode = self.base.options.output_mode, | |
| 4700 | .output_mode = output_mode, | |
| 4683 | 4701 | }, buffer.writer()); |
| 4684 | 4702 | assert(buffer.items.len == code_sig.size()); |
| 4685 | 4703 | |
| ... | ... | @@ -4693,10 +4711,13 @@ pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *Cod |
| 4693 | 4711 | |
| 4694 | 4712 | /// Writes Mach-O file header. |
| 4695 | 4713 | pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 4714 | const output_mode = self.base.comp.config.output_mode; | |
| 4715 | ||
| 4696 | 4716 | var header: macho.mach_header_64 = .{}; |
| 4697 | 4717 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| 4698 | 4718 | |
| 4699 | switch (self.base.options.target.cpu.arch) { | |
| 4719 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4720 | switch (target.cpu.arch) { | |
| 4700 | 4721 | .aarch64 => { |
| 4701 | 4722 | header.cputype = macho.CPU_TYPE_ARM64; |
| 4702 | 4723 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | ... | @@ -4708,7 +4729,7 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 4708 | 4729 | else => unreachable, |
| 4709 | 4730 | } |
| 4710 | 4731 | |
| 4711 | switch (self.base.options.output_mode) { | |
| 4732 | switch (output_mode) { | |
| 4712 | 4733 | .Exe => { |
| 4713 | 4734 | header.filetype = macho.MH_EXECUTE; |
| 4714 | 4735 | }, |
| ... | ... | @@ -4817,7 +4838,7 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { |
| 4817 | 4838 | } |
| 4818 | 4839 | |
| 4819 | 4840 | pub fn addUndefined(self: *MachO, name: []const u8, flags: RelocFlags) !u32 { |
| 4820 | const gpa = self.base.allocator; | |
| 4841 | const gpa = self.base.comp.gpa; | |
| 4821 | 4842 | |
| 4822 | 4843 | const gop = try self.getOrPutGlobalPtr(name); |
| 4823 | 4844 | const global_index = self.getGlobalIndex(name).?; |
| ... | ... | @@ -4842,7 +4863,8 @@ pub fn addUndefined(self: *MachO, name: []const u8, flags: RelocFlags) !u32 { |
| 4842 | 4863 | } |
| 4843 | 4864 | |
| 4844 | 4865 | fn 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); | |
| 4846 | 4868 | if (!act_gop.found_existing) { |
| 4847 | 4869 | act_gop.value_ptr.* = .{}; |
| 4848 | 4870 | } |
| ... | ... | @@ -5022,7 +5044,7 @@ pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResul |
| 5022 | 5044 | if (self.getGlobalPtr(name)) |ptr| { |
| 5023 | 5045 | return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr }; |
| 5024 | 5046 | } |
| 5025 | const gpa = self.base.allocator; | |
| 5047 | const gpa = self.base.comp.gpa; | |
| 5026 | 5048 | const global_index = try self.allocateGlobal(); |
| 5027 | 5049 | const global_name = try gpa.dupe(u8, name); |
| 5028 | 5050 | _ = try self.resolver.put(gpa, global_name, global_index); |
| ... | ... | @@ -5060,15 +5082,16 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5060 | 5082 | } |
| 5061 | 5083 | |
| 5062 | 5084 | pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5085 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 5063 | 5086 | const index = self.stub_table.lookup.get(sym_with_loc) orelse return null; |
| 5064 | 5087 | 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; | |
| 5066 | 5089 | } |
| 5067 | 5090 | |
| 5068 | 5091 | /// Returns symbol location corresponding to the set entrypoint if any. |
| 5069 | 5092 | /// Asserts output mode is executable. |
| 5070 | 5093 | pub 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; | |
| 5072 | 5095 | const global = self.getGlobal(entry_name) orelse return null; |
| 5073 | 5096 | return global; |
| 5074 | 5097 | } |
| ... | ... | @@ -5086,11 +5109,13 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 { |
| 5086 | 5109 | }; |
| 5087 | 5110 | } |
| 5088 | 5111 | |
| 5089 | pub 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; | |
| 5112 | pub 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; | |
| 5094 | 5119 | if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) return true; |
| 5095 | 5120 | return false; |
| 5096 | 5121 | } |
| ... | ... | @@ -5171,7 +5196,9 @@ pub fn handleAndReportParseError( |
| 5171 | 5196 | err: ParseError, |
| 5172 | 5197 | ctx: *const ParseErrorCtx, |
| 5173 | 5198 | ) 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; | |
| 5175 | 5202 | switch (err) { |
| 5176 | 5203 | error.DylibAlreadyExists => {}, |
| 5177 | 5204 | error.IncompatibleDylibVersion => { |
| ... | ... | @@ -5188,7 +5215,7 @@ pub fn handleAndReportParseError( |
| 5188 | 5215 | }, |
| 5189 | 5216 | error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}), |
| 5190 | 5217 | error.InvalidTarget, error.InvalidTargetFatLibrary => { |
| 5191 | var targets_string = std.ArrayList(u8).init(self.base.allocator); | |
| 5218 | var targets_string = std.ArrayList(u8).init(gpa); | |
| 5192 | 5219 | defer targets_string.deinit(); |
| 5193 | 5220 | |
| 5194 | 5221 | if (ctx.detected_targets.items.len > 1) { |
| ... | ... | @@ -5206,7 +5233,7 @@ pub fn handleAndReportParseError( |
| 5206 | 5233 | error.InvalidTarget => try self.reportParseError( |
| 5207 | 5234 | path, |
| 5208 | 5235 | "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 }, | |
| 5210 | 5237 | ), |
| 5211 | 5238 | error.InvalidTargetFatLibrary => try self.reportParseError( |
| 5212 | 5239 | path, |
| ... | ... | @@ -5226,14 +5253,15 @@ fn reportMissingLibraryError( |
| 5226 | 5253 | comptime format: []const u8, |
| 5227 | 5254 | args: anytype, |
| 5228 | 5255 | ) 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); | |
| 5231 | 5259 | const notes = try gpa.alloc(File.ErrorMsg, checked_paths.len); |
| 5232 | 5260 | errdefer gpa.free(notes); |
| 5233 | 5261 | for (checked_paths, notes) |path, *note| { |
| 5234 | 5262 | note.* = .{ .msg = try std.fmt.allocPrint(gpa, "tried {s}", .{path}) }; |
| 5235 | 5263 | } |
| 5236 | self.misc_errors.appendAssumeCapacity(.{ | |
| 5264 | comp.link_errors.appendAssumeCapacity(.{ | |
| 5237 | 5265 | .msg = try std.fmt.allocPrint(gpa, format, args), |
| 5238 | 5266 | .notes = notes, |
| 5239 | 5267 | }); |
| ... | ... | @@ -5246,15 +5274,16 @@ fn reportDependencyError( |
| 5246 | 5274 | comptime format: []const u8, |
| 5247 | 5275 | args: anytype, |
| 5248 | 5276 | ) 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); | |
| 5251 | 5280 | var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2); |
| 5252 | 5281 | defer notes.deinit(); |
| 5253 | 5282 | if (path) |p| { |
| 5254 | 5283 | notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{p}) }); |
| 5255 | 5284 | } |
| 5256 | 5285 | notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "a dependency of {s}", .{parent}) }); |
| 5257 | self.misc_errors.appendAssumeCapacity(.{ | |
| 5286 | comp.link_errors.appendAssumeCapacity(.{ | |
| 5258 | 5287 | .msg = try std.fmt.allocPrint(gpa, format, args), |
| 5259 | 5288 | .notes = try notes.toOwnedSlice(), |
| 5260 | 5289 | }); |
| ... | ... | @@ -5266,12 +5295,13 @@ pub fn reportParseError( |
| 5266 | 5295 | comptime format: []const u8, |
| 5267 | 5296 | args: anytype, |
| 5268 | 5297 | ) 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); | |
| 5271 | 5301 | var notes = try gpa.alloc(File.ErrorMsg, 1); |
| 5272 | 5302 | errdefer gpa.free(notes); |
| 5273 | 5303 | notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{path}) }; |
| 5274 | self.misc_errors.appendAssumeCapacity(.{ | |
| 5304 | comp.link_errors.appendAssumeCapacity(.{ | |
| 5275 | 5305 | .msg = try std.fmt.allocPrint(gpa, format, args), |
| 5276 | 5306 | .notes = notes, |
| 5277 | 5307 | }); |
| ... | ... | @@ -5283,21 +5313,23 @@ pub fn reportUnresolvedBoundarySymbol( |
| 5283 | 5313 | comptime format: []const u8, |
| 5284 | 5314 | args: anytype, |
| 5285 | 5315 | ) 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); | |
| 5288 | 5319 | var notes = try gpa.alloc(File.ErrorMsg, 1); |
| 5289 | 5320 | errdefer gpa.free(notes); |
| 5290 | 5321 | notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while resolving {s}", .{sym_name}) }; |
| 5291 | self.misc_errors.appendAssumeCapacity(.{ | |
| 5322 | comp.link_errors.appendAssumeCapacity(.{ | |
| 5292 | 5323 | .msg = try std.fmt.allocPrint(gpa, format, args), |
| 5293 | 5324 | .notes = notes, |
| 5294 | 5325 | }); |
| 5295 | 5326 | } |
| 5296 | 5327 | |
| 5297 | 5328 | pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void { |
| 5298 | const gpa = self.base.allocator; | |
| 5329 | const comp = self.base.comp; | |
| 5330 | const gpa = comp.gpa; | |
| 5299 | 5331 | const count = self.unresolved.count(); |
| 5300 | try self.misc_errors.ensureUnusedCapacity(gpa, count); | |
| 5332 | try comp.link_errors.ensureUnusedCapacity(gpa, count); | |
| 5301 | 5333 | |
| 5302 | 5334 | for (self.unresolved.keys()) |global_index| { |
| 5303 | 5335 | const global = self.globals.items[global_index]; |
| ... | ... | @@ -5318,7 +5350,7 @@ pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void { |
| 5318 | 5350 | }; |
| 5319 | 5351 | err_msg.notes = try notes.toOwnedSlice(); |
| 5320 | 5352 | |
| 5321 | self.misc_errors.appendAssumeCapacity(err_msg); | |
| 5353 | comp.link_errors.appendAssumeCapacity(err_msg); | |
| 5322 | 5354 | } |
| 5323 | 5355 | } |
| 5324 | 5356 | |
| ... | ... | @@ -5327,8 +5359,9 @@ fn reportSymbolCollision( |
| 5327 | 5359 | first: SymbolWithLoc, |
| 5328 | 5360 | other: SymbolWithLoc, |
| 5329 | 5361 | ) 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); | |
| 5332 | 5365 | |
| 5333 | 5366 | var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2); |
| 5334 | 5367 | defer notes.deinit(); |
| ... | ... | @@ -5351,12 +5384,13 @@ fn reportSymbolCollision( |
| 5351 | 5384 | }) }; |
| 5352 | 5385 | err_msg.notes = try notes.toOwnedSlice(); |
| 5353 | 5386 | |
| 5354 | self.misc_errors.appendAssumeCapacity(err_msg); | |
| 5387 | comp.link_errors.appendAssumeCapacity(err_msg); | |
| 5355 | 5388 | } |
| 5356 | 5389 | |
| 5357 | 5390 | fn 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); | |
| 5360 | 5394 | |
| 5361 | 5395 | const notes = try gpa.alloc(File.ErrorMsg, 1); |
| 5362 | 5396 | errdefer gpa.free(notes); |
| ... | ... | @@ -5374,7 +5408,7 @@ fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{Ou |
| 5374 | 5408 | else |
| 5375 | 5409 | unreachable; |
| 5376 | 5410 | |
| 5377 | self.misc_errors.appendAssumeCapacity(.{ | |
| 5411 | comp.link_errors.appendAssumeCapacity(.{ | |
| 5378 | 5412 | .msg = try std.fmt.allocPrint(gpa, "unhandled symbol type: '{s}' has type {s}", .{ |
| 5379 | 5413 | self.getSymbolName(sym_with_loc), |
| 5380 | 5414 | sym_type, |
| ... | ... | @@ -5623,6 +5657,8 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index, logger: anytype) void { |
| 5623 | 5657 | } |
| 5624 | 5658 | } |
| 5625 | 5659 | |
| 5660 | const default_entry_symbol_name = "_main"; | |
| 5661 | ||
| 5626 | 5662 | pub const base_tag: File.Tag = File.Tag.macho; |
| 5627 | 5663 | pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1))); |
| 5628 | 5664 | pub 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) ! |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | 255 | pub 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; | |
| 257 | 258 | const gop = try macho_file.relocs.getOrPut(gpa, atom_index); |
| 258 | 259 | if (!gop.found_existing) { |
| 259 | 260 | gop.value_ptr.* = .{}; |
| ... | ... | @@ -269,7 +270,8 @@ pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Rel |
| 269 | 270 | } |
| 270 | 271 | |
| 271 | 272 | pub 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; | |
| 273 | 275 | const atom = macho_file.getAtom(atom_index); |
| 274 | 276 | log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, atom.getSymbolIndex() }); |
| 275 | 277 | 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 { |
| 280 | 282 | } |
| 281 | 283 | |
| 282 | 284 | pub 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; | |
| 284 | 287 | const atom = macho_file.getAtom(atom_index); |
| 285 | 288 | log.debug(" (adding binding to symbol {s} at offset 0x{x} in %{?d})", .{ |
| 286 | 289 | macho_file.getSymbolName(binding.target), |
| ... | ... | @@ -307,7 +310,8 @@ pub fn resolveRelocations( |
| 307 | 310 | } |
| 308 | 311 | |
| 309 | 312 | pub 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; | |
| 311 | 315 | var removed_relocs = macho_file.relocs.fetchOrderedRemove(atom_index); |
| 312 | 316 | if (removed_relocs) |*relocs| relocs.value.deinit(gpa); |
| 313 | 317 | 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 |
| 387 | 391 | } |
| 388 | 392 | |
| 389 | 393 | pub 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; | |
| 391 | 396 | const atom = macho_file.getAtom(atom_index); |
| 392 | 397 | assert(atom.getFile() != null); // synthetic atoms do not have relocs |
| 393 | 398 | |
| ... | ... | @@ -434,6 +439,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 434 | 439 | const tracy = trace(@src()); |
| 435 | 440 | defer tracy.end(); |
| 436 | 441 | |
| 442 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 437 | 443 | const object = &macho_file.objects.items[ctx.object_id]; |
| 438 | 444 | log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name }); |
| 439 | 445 | |
| ... | ... | @@ -447,7 +453,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 447 | 453 | else |
| 448 | 454 | mem.readInt(u32, ctx.code[rel_offset..][0..4], .little); |
| 449 | 455 | } else blk: { |
| 450 | assert(macho_file.base.options.target.cpu.arch == .x86_64); | |
| 456 | assert(target.cpu.arch == .x86_64); | |
| 451 | 457 | const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) { |
| 452 | 458 | .X86_64_RELOC_SIGNED => 0, |
| 453 | 459 | .X86_64_RELOC_SIGNED_1 => 1, |
| ... | ... | @@ -467,18 +473,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 467 | 473 | |
| 468 | 474 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 }; |
| 469 | 475 | 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()) | |
| 471 | 477 | sym_loc |
| 472 | 478 | else if (object.getGlobal(sym_index)) |global_index| |
| 473 | 479 | macho_file.globals.items[global_index] |
| 474 | 480 | else |
| 475 | 481 | sym_loc; |
| 476 | 482 | 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(), | |
| 480 | 486 | }); |
| 481 | return target; | |
| 487 | return reloc_target; | |
| 482 | 488 | } |
| 483 | 489 | |
| 484 | 490 | pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index { |
| ... | ... | @@ -599,7 +605,8 @@ pub fn resolveRelocs( |
| 599 | 605 | atom_code: []u8, |
| 600 | 606 | atom_relocs: []align(1) const macho.relocation_info, |
| 601 | 607 | ) !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; | |
| 603 | 610 | const atom = macho_file.getAtom(atom_index); |
| 604 | 611 | assert(atom.getFile() != null); // synthetic atoms do not have relocs |
| 605 | 612 | |
| ... | ... | @@ -1192,7 +1199,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca |
| 1192 | 1199 | } |
| 1193 | 1200 | |
| 1194 | 1201 | pub 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) { | |
| 1196 | 1204 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1197 | 1205 | .ARM64_RELOC_GOT_LOAD_PAGE21, |
| 1198 | 1206 | .ARM64_RELOC_GOT_LOAD_PAGEOFF12, |
| ... | ... | @@ -1211,7 +1219,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1211 | 1219 | } |
| 1212 | 1220 | |
| 1213 | 1221 | pub 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) { | |
| 1215 | 1224 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1216 | 1225 | .ARM64_RELOC_TLVP_LOAD_PAGE21, |
| 1217 | 1226 | .ARM64_RELOC_TLVP_LOAD_PAGEOFF12, |
| ... | ... | @@ -1227,7 +1236,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1227 | 1236 | } |
| 1228 | 1237 | |
| 1229 | 1238 | pub 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) { | |
| 1231 | 1241 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1232 | 1242 | .ARM64_RELOC_BRANCH26 => return true, |
| 1233 | 1243 | else => return false, |
src/link/MachO/DebugSymbols.zig+13-8| ... | ... | @@ -39,10 +39,12 @@ pub const Reloc = struct { |
| 39 | 39 | /// You must call this function *after* `MachO.populateMissingMetadata()` |
| 40 | 40 | /// has been called to get a viable debug symbols output. |
| 41 | 41 | pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void { |
| 42 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 43 | ||
| 42 | 44 | if (self.dwarf_segment_cmd_index == null) { |
| 43 | 45 | self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len)); |
| 44 | 46 | |
| 45 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 47 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 46 | 48 | const off = @as(u64, @intCast(page_size)); |
| 47 | 49 | const ideal_size: u16 = 200 + 128 + 160 + 250; |
| 48 | 50 | 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 |
| 196 | 198 | } |
| 197 | 199 | |
| 198 | 200 | pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 201 | const comp = macho_file.base.comp; | |
| 199 | 202 | // TODO This linker code currently assumes there is only 1 compilation unit |
| 200 | 203 | // 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; | |
| 203 | 205 | |
| 204 | 206 | for (self.relocs.items) |*reloc| { |
| 205 | 207 | const sym = switch (reloc.type) { |
| ... | ... | @@ -243,7 +245,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void { |
| 243 | 245 | const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?]; |
| 244 | 246 | const low_pc = text_section.addr; |
| 245 | 247 | 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); | |
| 247 | 249 | self.debug_info_header_dirty = false; |
| 248 | 250 | } |
| 249 | 251 | |
| ... | ... | @@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 332 | 334 | file_size = @max(file_size, header.offset + header.size); |
| 333 | 335 | } |
| 334 | 336 | |
| 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); | |
| 336 | 339 | const aligned_size = mem.alignForward(u64, file_size, page_size); |
| 337 | 340 | dwarf_segment.vmaddr = base_vmaddr; |
| 338 | 341 | dwarf_segment.filesize = aligned_size; |
| ... | ... | @@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype) |
| 394 | 397 | } |
| 395 | 398 | |
| 396 | 399 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 400 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 401 | ||
| 397 | 402 | var header: macho.mach_header_64 = .{}; |
| 398 | 403 | header.filetype = macho.MH_DSYM; |
| 399 | 404 | |
| 400 | switch (macho_file.base.options.target.cpu.arch) { | |
| 405 | switch (target.cpu.arch) { | |
| 401 | 406 | .aarch64 => { |
| 402 | 407 | header.cputype = macho.CPU_TYPE_ARM64; |
| 403 | 408 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | ... | @@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void { |
| 435 | 440 | try self.writeSymtab(macho_file); |
| 436 | 441 | try self.writeStrtab(); |
| 437 | 442 | |
| 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); | |
| 439 | 445 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; |
| 440 | 446 | const aligned_size = mem.alignForward(u64, seg.filesize, page_size); |
| 441 | 447 | seg.vmsize = aligned_size; |
| ... | ... | @@ -566,6 +572,5 @@ const trace = @import("../../tracy.zig").trace; |
| 566 | 572 | const Allocator = mem.Allocator; |
| 567 | 573 | const Dwarf = @import("../Dwarf.zig"); |
| 568 | 574 | const MachO = @import("../MachO.zig"); |
| 569 | const Module = @import("../../Module.zig"); | |
| 570 | 575 | const StringTable = @import("../StringTable.zig"); |
| 571 | 576 | const Type = @import("../../type.zig").Type; |
src/link/MachO/Object.zig+29-20| ... | ... | @@ -342,19 +342,23 @@ pub const SplitIntoAtomsError = error{ |
| 342 | 342 | }; |
| 343 | 343 | |
| 344 | 344 | pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIntoAtomsError!void { |
| 345 | const comp = macho_file.base.comp; | |
| 346 | const gpa = comp.gpa; | |
| 345 | 347 | log.debug("splitting object({d}, {s}) into atoms", .{ object_id, self.name }); |
| 346 | 348 | |
| 347 | 349 | try self.splitRegularSections(macho_file, object_id); |
| 348 | 350 | try self.parseEhFrameSection(macho_file, object_id); |
| 349 | 351 | try self.parseUnwindInfo(macho_file, object_id); |
| 350 | try self.parseDataInCode(macho_file.base.allocator); | |
| 352 | try self.parseDataInCode(gpa); | |
| 351 | 353 | } |
| 352 | 354 | |
| 353 | 355 | /// Splits input regular sections into Atoms. |
| 354 | 356 | /// If the Object was compiled with `MH_SUBSECTIONS_VIA_SYMBOLS`, splits section |
| 355 | 357 | /// into subsections where each subsection then represents an Atom. |
| 356 | 358 | pub 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; | |
| 358 | 362 | |
| 359 | 363 | const sections = self.getSourceSections(); |
| 360 | 364 | for (sections, 0..) |sect, id| { |
| ... | ... | @@ -448,7 +452,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) ! |
| 448 | 452 | |
| 449 | 453 | try self.parseRelocs(gpa, section.id); |
| 450 | 454 | |
| 451 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 455 | const cpu_arch = target.cpu.arch; | |
| 452 | 456 | const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1); |
| 453 | 457 | const sect_start_index = sect_sym_index + sect_loc.index; |
| 454 | 458 | |
| ... | ... | @@ -554,7 +558,8 @@ fn createAtomFromSubsection( |
| 554 | 558 | alignment: Alignment, |
| 555 | 559 | out_sect_id: u8, |
| 556 | 560 | ) !Atom.Index { |
| 557 | const gpa = macho_file.base.allocator; | |
| 561 | const comp = macho_file.base.comp; | |
| 562 | const gpa = comp.gpa; | |
| 558 | 563 | const atom_index = try macho_file.createAtom(sym_index, .{ |
| 559 | 564 | .size = size, |
| 560 | 565 | .alignment = alignment, |
| ... | ... | @@ -670,13 +675,15 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 670 | 675 | |
| 671 | 676 | log.debug("parsing __TEXT,__eh_frame section", .{}); |
| 672 | 677 | |
| 673 | const gpa = macho_file.base.allocator; | |
| 678 | const comp = macho_file.base.comp; | |
| 679 | const gpa = comp.gpa; | |
| 674 | 680 | |
| 675 | 681 | if (macho_file.eh_frame_section_index == null) { |
| 676 | 682 | macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{}); |
| 677 | 683 | } |
| 678 | 684 | |
| 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; | |
| 680 | 687 | try self.parseRelocs(gpa, sect_id); |
| 681 | 688 | const relocs = self.getRelocs(sect_id); |
| 682 | 689 | |
| ... | ... | @@ -704,7 +711,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 704 | 711 | }); |
| 705 | 712 | |
| 706 | 713 | if (record.tag == .fde) { |
| 707 | const target = blk: { | |
| 714 | const reloc_target = blk: { | |
| 708 | 715 | switch (cpu_arch) { |
| 709 | 716 | .aarch64 => { |
| 710 | 717 | 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 |
| 714 | 721 | @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED) |
| 715 | 722 | break rel; |
| 716 | 723 | } else unreachable; |
| 717 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 724 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 718 | 725 | .object_id = object_id, |
| 719 | 726 | .rel = rel, |
| 720 | 727 | .code = it.data[offset..], |
| 721 | 728 | .base_offset = @as(i32, @intCast(offset)), |
| 722 | 729 | }); |
| 723 | break :blk target; | |
| 730 | break :blk reloc_target; | |
| 724 | 731 | }, |
| 725 | 732 | .x86_64 => { |
| 726 | 733 | const target_address = record.getTargetSymbolAddress(.{ |
| ... | ... | @@ -728,16 +735,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 728 | 735 | .base_offset = offset, |
| 729 | 736 | }); |
| 730 | 737 | 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| | |
| 732 | 739 | macho_file.globals.items[global_index] |
| 733 | 740 | else |
| 734 | 741 | SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 }; |
| 735 | break :blk target; | |
| 742 | break :blk reloc_target; | |
| 736 | 743 | }, |
| 737 | 744 | else => unreachable, |
| 738 | 745 | } |
| 739 | 746 | }; |
| 740 | if (target.getFile() != object_id) { | |
| 747 | if (reloc_target.getFile() != object_id) { | |
| 741 | 748 | log.debug("FDE at offset {x} marked DEAD", .{offset}); |
| 742 | 749 | self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true; |
| 743 | 750 | } else { |
| ... | ... | @@ -746,12 +753,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 746 | 753 | // very problematic when using Zig's @export feature to re-export symbols under |
| 747 | 754 | // additional names. For that reason, we need to ensure we record aliases here |
| 748 | 755 | // 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); | |
| 750 | 757 | var i: u32 = 0; |
| 751 | 758 | while (i < aliases.len) : (i += 1) { |
| 752 | 759 | const actual_target = SymbolWithLoc{ |
| 753 | 760 | .sym_index = i + aliases.start, |
| 754 | .file = target.file, | |
| 761 | .file = reloc_target.file, | |
| 755 | 762 | }; |
| 756 | 763 | log.debug("FDE at offset {x} tracks {s}", .{ |
| 757 | 764 | offset, |
| ... | ... | @@ -765,8 +772,10 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 765 | 772 | } |
| 766 | 773 | |
| 767 | 774 | fn 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; | |
| 770 | 779 | const sect_id = self.unwind_info_sect_id orelse { |
| 771 | 780 | // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`, |
| 772 | 781 | // 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 { |
| 818 | 827 | |
| 819 | 828 | // Find function symbol that this record describes |
| 820 | 829 | 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, .{ | |
| 822 | 831 | .object_id = object_id, |
| 823 | 832 | .rel = rel, |
| 824 | 833 | .code = mem.asBytes(&record), |
| 825 | 834 | .base_offset = @as(i32, @intCast(offset)), |
| 826 | 835 | }); |
| 827 | if (target.getFile() != object_id) { | |
| 836 | if (reloc_target.getFile() != object_id) { | |
| 828 | 837 | log.debug("unwind record {d} marked DEAD", .{record_id}); |
| 829 | 838 | self.unwind_relocs_lookup[record_id].dead = true; |
| 830 | 839 | } else { |
| ... | ... | @@ -833,12 +842,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 833 | 842 | // very problematic when using Zig's @export feature to re-export symbols under |
| 834 | 843 | // additional names. For that reason, we need to ensure we record aliases here |
| 835 | 844 | // 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); | |
| 837 | 846 | var i: u32 = 0; |
| 838 | 847 | while (i < aliases.len) : (i += 1) { |
| 839 | 848 | const actual_target = SymbolWithLoc{ |
| 840 | 849 | .sym_index = i + aliases.start, |
| 841 | .file = target.file, | |
| 850 | .file = reloc_target.file, | |
| 842 | 851 | }; |
| 843 | 852 | log.debug("unwind record {d} tracks {s}", .{ |
| 844 | 853 | record_id, |
src/link/MachO/Relocation.zig+4-2| ... | ... | @@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool { |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 { |
| 61 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 61 | 62 | if (self.isStubTrampoline(macho_file)) { |
| 62 | 63 | const index = macho_file.stub_table.lookup.get(self.target) orelse return null; |
| 63 | 64 | const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?]; |
| 64 | 65 | 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); | |
| 66 | 67 | } |
| 67 | 68 | switch (self.type) { |
| 68 | 69 | .got, .got_page, .got_pageoff => { |
| ... | ... | @@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 { |
| 84 | 85 | } |
| 85 | 86 | |
| 86 | 87 | pub 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; | |
| 88 | 90 | const atom = macho_file.getAtom(atom_index); |
| 89 | 91 | const source_sym = atom.getSymbol(macho_file); |
| 90 | 92 | 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 { |
| 184 | 184 | pub fn scanRelocs(macho_file: *MachO) !void { |
| 185 | 185 | if (macho_file.unwind_info_section_index == null) return; |
| 186 | 186 | |
| 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; | |
| 188 | 189 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| 189 | 190 | const unwind_records = object.getUnwindRecords(); |
| 190 | 191 | for (object.exec_atoms.items) |atom_index| { |
| ... | ... | @@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void { |
| 196 | 197 | if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) { |
| 197 | 198 | if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| { |
| 198 | 199 | // Personality function; add GOT pointer. |
| 199 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 200 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 200 | 201 | .object_id = @as(u32, @intCast(object_id)), |
| 201 | 202 | .rel = rel, |
| 202 | 203 | .code = mem.asBytes(&record), |
| 203 | 204 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 204 | 205 | }); |
| 205 | try macho_file.addGotEntry(target); | |
| 206 | try macho_file.addGotEntry(reloc_target); | |
| 206 | 207 | } |
| 207 | 208 | } |
| 208 | 209 | } |
| ... | ... | @@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void { |
| 213 | 214 | pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 214 | 215 | if (macho_file.unwind_info_section_index == null) return; |
| 215 | 216 | |
| 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; | |
| 217 | 219 | |
| 218 | 220 | var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa); |
| 219 | 221 | defer records.deinit(); |
| ... | ... | @@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 247 | 249 | @as(u32, @intCast(object_id)), |
| 248 | 250 | record_id, |
| 249 | 251 | )) |rel| { |
| 250 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 252 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 251 | 253 | .object_id = @as(u32, @intCast(object_id)), |
| 252 | 254 | .rel = rel, |
| 253 | 255 | .code = mem.asBytes(&record), |
| 254 | 256 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 255 | 257 | }); |
| 256 | const personality_index = info.getPersonalityFunction(target) orelse inner: { | |
| 258 | const personality_index = info.getPersonalityFunction(reloc_target) orelse inner: { | |
| 257 | 259 | const personality_index = info.personalities_count; |
| 258 | info.personalities[personality_index] = target; | |
| 260 | info.personalities[personality_index] = reloc_target; | |
| 259 | 261 | info.personalities_count += 1; |
| 260 | 262 | break :inner personality_index; |
| 261 | 263 | }; |
| ... | ... | @@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 265 | 267 | } |
| 266 | 268 | |
| 267 | 269 | 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, .{ | |
| 269 | 271 | .object_id = @as(u32, @intCast(object_id)), |
| 270 | 272 | .rel = rel, |
| 271 | 273 | .code = mem.asBytes(&record), |
| 272 | 274 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 273 | 275 | }); |
| 274 | record.lsda = @as(u64, @bitCast(target)); | |
| 276 | record.lsda = @as(u64, @bitCast(reloc_target)); | |
| 275 | 277 | } |
| 276 | 278 | } |
| 277 | 279 | break :blk record; |
| ... | ... | @@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void { |
| 557 | 559 | const text_sect = macho_file.sections.items(.header)[text_sect_id]; |
| 558 | 560 | |
| 559 | 561 | 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; | |
| 561 | 564 | |
| 562 | 565 | 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).?; | |
| 565 | 568 | 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) }); | |
| 567 | 570 | } |
| 568 | 571 | |
| 569 | 572 | for (info.records.items) |*rec| { |
src/link/MachO/dead_strip.zig+39-32| ... | ... | @@ -1,7 +1,8 @@ |
| 1 | 1 | //! An algorithm for dead stripping of unreferenced Atoms. |
| 2 | 2 | |
| 3 | 3 | pub 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; | |
| 5 | 6 | |
| 6 | 7 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 7 | 8 | defer arena.deinit(); |
| ... | ... | @@ -33,7 +34,9 @@ fn addRoot(macho_file: *MachO, roots: *AtomTable, file: u32, sym_loc: SymbolWith |
| 33 | 34 | fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void { |
| 34 | 35 | log.debug("collecting roots", .{}); |
| 35 | 36 | |
| 36 | switch (macho_file.base.options.output_mode) { | |
| 37 | const comp = macho_file.base.comp; | |
| 38 | ||
| 39 | switch (comp.config.output_mode) { | |
| 37 | 40 | .Exe => { |
| 38 | 41 | // Add entrypoint as GC root |
| 39 | 42 | if (macho_file.getEntryPoint()) |global| { |
| ... | ... | @@ -60,7 +63,7 @@ fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void { |
| 60 | 63 | } |
| 61 | 64 | |
| 62 | 65 | // 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| { | |
| 64 | 67 | const global_index = macho_file.resolver.get(sym_name).?; |
| 65 | 68 | const global = macho_file.globals.items[global_index]; |
| 66 | 69 | const sym = macho_file.getSymbol(global); |
| ... | ... | @@ -118,7 +121,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void |
| 118 | 121 | |
| 119 | 122 | alive.putAssumeCapacityNoClobber(atom_index, {}); |
| 120 | 123 | |
| 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; | |
| 122 | 126 | |
| 123 | 127 | const sym = macho_file.getSymbol(atom.getSymbolWithLoc()); |
| 124 | 128 | 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 |
| 129 | 133 | const ctx = Atom.getRelocContext(macho_file, atom_index); |
| 130 | 134 | |
| 131 | 135 | for (relocs) |rel| { |
| 132 | const target = switch (cpu_arch) { | |
| 136 | const reloc_target = switch (cpu_arch) { | |
| 133 | 137 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 134 | 138 | .ARM64_RELOC_ADDEND => continue, |
| 135 | 139 | else => Atom.parseRelocTarget(macho_file, .{ |
| ... | ... | @@ -149,19 +153,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void |
| 149 | 153 | }), |
| 150 | 154 | else => unreachable, |
| 151 | 155 | }; |
| 152 | const target_sym = macho_file.getSymbol(target); | |
| 156 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 153 | 157 | |
| 154 | 158 | 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); | |
| 157 | 161 | if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue; |
| 158 | 162 | if (mem.eql(u8, "___dso_handle", target_sym_name)) continue; |
| 159 | 163 | |
| 160 | 164 | unreachable; // referenced symbol not found |
| 161 | 165 | } |
| 162 | 166 | |
| 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).?; | |
| 165 | 169 | log.debug(" following ATOM({d}, %{d}, {?d})", .{ |
| 166 | 170 | target_atom_index, |
| 167 | 171 | macho_file.getAtom(target_atom_index).sym_index, |
| ... | ... | @@ -178,7 +182,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool |
| 178 | 182 | |
| 179 | 183 | log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() }); |
| 180 | 184 | |
| 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; | |
| 182 | 187 | |
| 183 | 188 | const sym = macho_file.getSymbol(sym_loc); |
| 184 | 189 | 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 |
| 189 | 194 | const ctx = Atom.getRelocContext(macho_file, atom_index); |
| 190 | 195 | |
| 191 | 196 | for (relocs) |rel| { |
| 192 | const target = switch (cpu_arch) { | |
| 197 | const reloc_target = switch (cpu_arch) { | |
| 193 | 198 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 194 | 199 | .ARM64_RELOC_ADDEND => continue, |
| 195 | 200 | else => Atom.parseRelocTarget(macho_file, .{ |
| ... | ... | @@ -210,9 +215,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool |
| 210 | 215 | else => unreachable, |
| 211 | 216 | }; |
| 212 | 217 | |
| 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)}); | |
| 216 | 221 | continue; |
| 217 | 222 | }; |
| 218 | 223 | if (alive.contains(target_atom_index)) { |
| ... | ... | @@ -271,7 +276,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void { |
| 271 | 276 | |
| 272 | 277 | fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void { |
| 273 | 278 | 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; | |
| 275 | 281 | |
| 276 | 282 | const unwind_records = object.getUnwindRecords(); |
| 277 | 283 | |
| ... | ... | @@ -310,29 +316,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void |
| 310 | 316 | markEhFrameRecords(macho_file, object_id, atom_index, alive); |
| 311 | 317 | } else { |
| 312 | 318 | 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, .{ | |
| 314 | 320 | .object_id = object_id, |
| 315 | 321 | .rel = rel, |
| 316 | 322 | .code = mem.asBytes(&record), |
| 317 | 323 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 318 | 324 | }); |
| 319 | const target_sym = macho_file.getSymbol(target); | |
| 325 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 320 | 326 | 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).?; | |
| 323 | 329 | markLive(macho_file, target_atom_index, alive); |
| 324 | 330 | } |
| 325 | 331 | } |
| 326 | 332 | |
| 327 | 333 | 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, .{ | |
| 329 | 335 | .object_id = object_id, |
| 330 | 336 | .rel = rel, |
| 331 | 337 | .code = mem.asBytes(&record), |
| 332 | 338 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 333 | 339 | }); |
| 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).?; | |
| 336 | 342 | markLive(macho_file, target_atom_index, alive); |
| 337 | 343 | } |
| 338 | 344 | } |
| ... | ... | @@ -341,7 +347,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void |
| 341 | 347 | } |
| 342 | 348 | |
| 343 | 349 | fn 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; | |
| 345 | 352 | const object = &macho_file.objects.items[object_id]; |
| 346 | 353 | var it = object.getEhFrameRecordsIterator(); |
| 347 | 354 | 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 |
| 361 | 368 | // Mark FDE references which should include any referenced LSDA record |
| 362 | 369 | const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset); |
| 363 | 370 | for (relocs) |rel| { |
| 364 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 371 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 365 | 372 | .object_id = object_id, |
| 366 | 373 | .rel = rel, |
| 367 | 374 | .code = fde.data, |
| 368 | 375 | .base_offset = @as(i32, @intCast(fde_offset)) + 4, |
| 369 | 376 | }); |
| 370 | const target_sym = macho_file.getSymbol(target); | |
| 377 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 371 | 378 | 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 | |
| 374 | 381 | break :blk; |
| 375 | 382 | markLive(macho_file, target_atom_index, alive); |
| 376 | 383 | } |
| ... | ... | @@ -394,11 +401,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index |
| 394 | 401 | |
| 395 | 402 | // Mark CIE references which should include any referenced personalities |
| 396 | 403 | // 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); | |
| 399 | 406 | 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).?; | |
| 402 | 409 | markLive(macho_file, target_atom_index, alive); |
| 403 | 410 | } |
| 404 | 411 | } |
src/link/MachO/eh_frame.zig+26-18| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | pub 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; | |
| 3 | 4 | |
| 4 | 5 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| 5 | 6 | var cies = std.AutoHashMap(u32, void).init(gpa); |
| ... | ... | @@ -35,8 +36,10 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error |
| 35 | 36 | sect.@"align" = 3; |
| 36 | 37 | sect.size = 0; |
| 37 | 38 | |
| 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; | |
| 40 | 43 | var size: u32 = 0; |
| 41 | 44 | |
| 42 | 45 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| ... | ... | @@ -86,8 +89,10 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 86 | 89 | const seg_id = macho_file.sections.items(.segment_index)[sect_id]; |
| 87 | 90 | const seg = macho_file.segments.items[seg_id]; |
| 88 | 91 | |
| 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; | |
| 91 | 96 | |
| 92 | 97 | var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa); |
| 93 | 98 | defer { |
| ... | ... | @@ -109,11 +114,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 109 | 114 | |
| 110 | 115 | for (object.exec_atoms.items) |atom_index| { |
| 111 | 116 | 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; | |
| 114 | 119 | if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue; |
| 115 | 120 | |
| 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; | |
| 117 | 122 | const record = &unwind_info.records.items[record_id]; |
| 118 | 123 | |
| 119 | 124 | // TODO skip this check if no __compact_unwind is present |
| ... | ... | @@ -153,7 +158,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 153 | 158 | .aarch64 => {}, // relocs take care of LSDA pointers |
| 154 | 159 | .x86_64 => { |
| 155 | 160 | // 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); | |
| 157 | 162 | try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{ |
| 158 | 163 | .base_addr = sect.addr, |
| 159 | 164 | .base_offset = eh_frame_offset, |
| ... | ... | @@ -278,7 +283,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 278 | 283 | object_id: u32, |
| 279 | 284 | source_offset: u32, |
| 280 | 285 | ) ?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; | |
| 282 | 288 | const relocs = getRelocs(macho_file, object_id, source_offset); |
| 283 | 289 | for (relocs) |rel| { |
| 284 | 290 | switch (cpu_arch) { |
| ... | ... | @@ -301,13 +307,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 301 | 307 | }, |
| 302 | 308 | else => unreachable, |
| 303 | 309 | } |
| 304 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 310 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 305 | 311 | .object_id = object_id, |
| 306 | 312 | .rel = rel, |
| 307 | 313 | .code = rec.data, |
| 308 | 314 | .base_offset = @as(i32, @intCast(source_offset)) + 4, |
| 309 | 315 | }); |
| 310 | return target; | |
| 316 | return reloc_target; | |
| 311 | 317 | } |
| 312 | 318 | return null; |
| 313 | 319 | } |
| ... | ... | @@ -319,11 +325,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 319 | 325 | }) !void { |
| 320 | 326 | comptime assert(is_mutable); |
| 321 | 327 | |
| 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; | |
| 323 | 330 | const relocs = getRelocs(macho_file, object_id, ctx.source_offset); |
| 324 | 331 | |
| 325 | 332 | for (relocs) |rel| { |
| 326 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 333 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 327 | 334 | .object_id = object_id, |
| 328 | 335 | .rel = rel, |
| 329 | 336 | .code = rec.data, |
| ... | ... | @@ -340,14 +347,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 340 | 347 | // Address of the __eh_frame in the source object file |
| 341 | 348 | }, |
| 342 | 349 | .ARM64_RELOC_POINTER_TO_GOT => { |
| 343 | const target_addr = macho_file.getGotEntryAddress(target).?; | |
| 350 | const target_addr = macho_file.getGotEntryAddress(reloc_target).?; | |
| 344 | 351 | const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse |
| 345 | 352 | return error.Overflow; |
| 346 | 353 | mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little); |
| 347 | 354 | }, |
| 348 | 355 | .ARM64_RELOC_UNSIGNED => { |
| 349 | 356 | 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); | |
| 351 | 358 | const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr)); |
| 352 | 359 | mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little); |
| 353 | 360 | }, |
| ... | ... | @@ -358,7 +365,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 358 | 365 | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); |
| 359 | 366 | switch (rel_type) { |
| 360 | 367 | .X86_64_RELOC_GOT => { |
| 361 | const target_addr = macho_file.getGotEntryAddress(target).?; | |
| 368 | const target_addr = macho_file.getGotEntryAddress(reloc_target).?; | |
| 362 | 369 | const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little); |
| 363 | 370 | const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend)); |
| 364 | 371 | const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0); |
| ... | ... | @@ -374,7 +381,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 374 | 381 | |
| 375 | 382 | pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 { |
| 376 | 383 | 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; | |
| 378 | 386 | const addend = mem.readInt(u32, rec.data[0..4], .little); |
| 379 | 387 | switch (cpu_arch) { |
| 380 | 388 | .aarch64 => { |
src/link/MachO/load_commands.zig+38-31| ... | ... | @@ -1,6 +1,3 @@ |
| 1 | /// Default implicit entrypoint symbol name. | |
| 2 | pub const default_entry_point: []const u8 = "_main"; | |
| 3 | ||
| 4 | 1 | /// Default path to dyld. |
| 5 | 2 | pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; |
| 6 | 3 | |
| ... | ... | @@ -17,7 +14,9 @@ const CalcLCsSizeCtx = struct { |
| 17 | 14 | wants_function_starts: bool = true, |
| 18 | 15 | }; |
| 19 | 16 | |
| 20 | fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 { | |
| 17 | fn calcLCsSize(m: *MachO, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 { | |
| 18 | const comp = m.base.comp; | |
| 19 | const gpa = comp.gpa; | |
| 21 | 20 | var has_text_segment: bool = false; |
| 22 | 21 | var sizeofcmds: u64 = 0; |
| 23 | 22 | for (ctx.segments) |seg| { |
| ... | ... | @@ -46,15 +45,15 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 46 | 45 | false, |
| 47 | 46 | ); |
| 48 | 47 | // LC_MAIN |
| 49 | if (options.output_mode == .Exe) { | |
| 48 | if (comp.config.output_mode == .Exe) { | |
| 50 | 49 | sizeofcmds += @sizeOf(macho.entry_point_command); |
| 51 | 50 | } |
| 52 | 51 | // 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) { | |
| 54 | 53 | 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); | |
| 58 | 57 | break :blk calcInstallNameLen( |
| 59 | 58 | @sizeOf(macho.dylib_command), |
| 60 | 59 | install_name, |
| ... | ... | @@ -64,7 +63,7 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 64 | 63 | } |
| 65 | 64 | // LC_RPATH |
| 66 | 65 | { |
| 67 | var it = RpathIterator.init(gpa, options.rpath_list); | |
| 66 | var it = RpathIterator.init(gpa, m.base.rpath_list); | |
| 68 | 67 | defer it.deinit(); |
| 69 | 68 | while (try it.next()) |rpath| { |
| 70 | 69 | sizeofcmds += calcInstallNameLen( |
| ... | ... | @@ -78,7 +77,8 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx |
| 78 | 77 | sizeofcmds += @sizeOf(macho.source_version_command); |
| 79 | 78 | // LC_BUILD_VERSION or LC_VERSION_MIN_ or nothing |
| 80 | 79 | { |
| 81 | const platform = Platform.fromTarget(options.target); | |
| 80 | const target = comp.root_mod.resolved_target.result; | |
| 81 | const platform = Platform.fromTarget(target); | |
| 82 | 82 | if (platform.isBuildVersionCompatible()) { |
| 83 | 83 | // LC_BUILD_VERSION |
| 84 | 84 | 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 |
| 100 | 100 | ); |
| 101 | 101 | } |
| 102 | 102 | // LC_CODE_SIGNATURE |
| 103 | if (MachO.requiresCodeSignature(options)) { | |
| 103 | if (m.requiresCodeSignature()) { | |
| 104 | 104 | sizeofcmds += @sizeOf(macho.linkedit_data_command); |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | return @as(u32, @intCast(sizeofcmds)); | |
| 107 | return @intCast(sizeofcmds); | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | pub 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); | |
| 110 | pub fn calcMinHeaderPad(m: *MachO, ctx: CalcLCsSizeCtx) !u64 { | |
| 111 | var padding: u32 = (try calcLCsSize(m, ctx, false)) + m.headerpad_size; | |
| 112 | 112 | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); |
| 113 | 113 | |
| 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); | |
| 116 | 116 | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ |
| 117 | 117 | min_headerpad_size + @sizeOf(macho.mach_header_64), |
| 118 | 118 | }); |
| ... | ... | @@ -189,17 +189,20 @@ fn writeDylibLC(ctx: WriteDylibLCCtx, lc_writer: anytype) !void { |
| 189 | 189 | } |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | pub 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{ | |
| 192 | pub 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{ | |
| 198 | 201 | .major = 1, |
| 199 | 202 | .minor = 0, |
| 200 | 203 | .patch = 0, |
| 201 | 204 | }; |
| 202 | const compat = options.compatibility_version orelse std.SemanticVersion{ | |
| 205 | const compat = macho_file.compatibility_version orelse std.SemanticVersion{ | |
| 203 | 206 | .major = 1, |
| 204 | 207 | .minor = 0, |
| 205 | 208 | .patch = 0, |
| ... | ... | @@ -237,8 +240,11 @@ const RpathIterator = struct { |
| 237 | 240 | } |
| 238 | 241 | }; |
| 239 | 242 | |
| 240 | pub fn writeRpathLCs(gpa: Allocator, options: *const link.Options, lc_writer: anytype) !void { | |
| 241 | var it = RpathIterator.init(gpa, options.rpath_list); | |
| 243 | pub 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); | |
| 242 | 248 | defer it.deinit(); |
| 243 | 249 | |
| 244 | 250 | while (try it.next()) |rpath| { |
| ... | ... | @@ -467,16 +473,17 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion { |
| 467 | 473 | }; |
| 468 | 474 | } |
| 469 | 475 | |
| 470 | pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVersion { | |
| 476 | pub fn inferSdkVersion(macho_file: *MachO) ?std.SemanticVersion { | |
| 477 | const comp = macho_file.base.comp; | |
| 478 | const gpa = comp.gpa; | |
| 479 | ||
| 471 | 480 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 472 | 481 | defer arena_allocator.deinit(); |
| 473 | 482 | const arena = arena_allocator.allocator(); |
| 474 | 483 | |
| 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; | |
| 478 | 485 | const sdk_dir = switch (sdk_layout) { |
| 479 | .sdk => options.sysroot.?, | |
| 486 | .sdk => comp.sysroot.?, | |
| 480 | 487 | .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null, |
| 481 | 488 | }; |
| 482 | 489 | 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 { |
| 68 | 68 | const header = &macho_file.sections.items(.header)[sect_id]; |
| 69 | 69 | if (header.size == 0) return; |
| 70 | 70 | |
| 71 | const gpa = macho_file.base.allocator; | |
| 71 | const comp = macho_file.base.comp; | |
| 72 | const gpa = comp.gpa; | |
| 72 | 73 | const first_atom_index = macho_file.sections.items(.first_atom_index)[sect_id].?; |
| 73 | 74 | |
| 74 | 75 | header.size = 0; |
| ... | ... | @@ -245,7 +246,8 @@ fn scanRelocs( |
| 245 | 246 | macho_file.getSymbol(target).n_value, |
| 246 | 247 | }); |
| 247 | 248 | |
| 248 | const gpa = macho_file.base.allocator; | |
| 249 | const comp = macho_file.base.comp; | |
| 250 | const gpa = comp.gpa; | |
| 249 | 251 | const target_sym = macho_file.getSymbol(target); |
| 250 | 252 | const thunk = &macho_file.thunks.items[thunk_index]; |
| 251 | 253 |
src/link/MachO/zld.zig+121-124| ... | ... | @@ -1,31 +1,29 @@ |
| 1 | 1 | pub fn linkWithZld( |
| 2 | 2 | macho_file: *MachO, |
| 3 | comp: *Compilation, | |
| 3 | arena: Allocator, | |
| 4 | 4 | prog_node: *std.Progress.Node, |
| 5 | 5 | ) link.File.FlushError!void { |
| 6 | 6 | const tracy = trace(@src()); |
| 7 | 7 | defer tracy.end(); |
| 8 | 8 | |
| 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; | |
| 12 | 13 | |
| 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; | |
| 19 | 17 | |
| 20 | 18 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 21 | 19 | // 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); | |
| 24 | 22 | |
| 25 | 23 | 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.? }); | |
| 27 | 25 | } else { |
| 28 | break :blk macho_file.base.intermediary_basename.?; | |
| 26 | break :blk macho_file.base.zcu_object_sub_path.?; | |
| 29 | 27 | } |
| 30 | 28 | } else null; |
| 31 | 29 | |
| ... | ... | @@ -34,22 +32,24 @@ pub fn linkWithZld( |
| 34 | 32 | sub_prog_node.context.refresh(); |
| 35 | 33 | defer sub_prog_node.end(); |
| 36 | 34 | |
| 35 | const output_mode = comp.config.output_mode; | |
| 36 | const link_mode = comp.config.link_mode; | |
| 37 | 37 | 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; | |
| 44 | 42 | |
| 45 | 43 | const id_symlink_basename = "zld.id"; |
| 46 | 44 | |
| 47 | 45 | 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(); | |
| 49 | 47 | |
| 50 | 48 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 51 | 49 | |
| 52 | if (!options.disable_lld_caching) { | |
| 50 | const objects = comp.objects; | |
| 51 | ||
| 52 | if (!macho_file.base.disable_lld_caching) { | |
| 53 | 53 | man = comp.cache_parent.obtain(); |
| 54 | 54 | |
| 55 | 55 | // We are about to obtain this lock, so here we give other processes a chance first. |
| ... | ... | @@ -57,7 +57,7 @@ pub fn linkWithZld( |
| 57 | 57 | |
| 58 | 58 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 59 | 59 | |
| 60 | for (options.objects) |obj| { | |
| 60 | for (objects) |obj| { | |
| 61 | 61 | _ = try man.addFile(obj.path, null); |
| 62 | 62 | man.hash.add(obj.must_link); |
| 63 | 63 | } |
| ... | ... | @@ -68,24 +68,22 @@ pub fn linkWithZld( |
| 68 | 68 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 69 | 69 | // installation sources because they are always a product of the compiler version + target information. |
| 70 | 70 | 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); | |
| 81 | 79 | 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); | |
| 84 | 82 | } |
| 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); | |
| 89 | 87 | |
| 90 | 88 | // We don't actually care whether it's a cache hit or miss; we just |
| 91 | 89 | // need the digest and the lock. |
| ... | ... | @@ -125,13 +123,13 @@ pub fn linkWithZld( |
| 125 | 123 | }; |
| 126 | 124 | } |
| 127 | 125 | |
| 128 | if (options.output_mode == .Obj) { | |
| 126 | if (output_mode == .Obj) { | |
| 129 | 127 | // LLD's MachO driver does not support the equivalent of `-r` so we do a simple file copy |
| 130 | 128 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 131 | 129 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 132 | 130 | 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; | |
| 135 | 133 | } |
| 136 | 134 | |
| 137 | 135 | if (comp.c_object_table.count() != 0) |
| ... | ... | @@ -150,7 +148,7 @@ pub fn linkWithZld( |
| 150 | 148 | try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{}); |
| 151 | 149 | } |
| 152 | 150 | } else { |
| 153 | const sub_path = options.emit.?.sub_path; | |
| 151 | const sub_path = emit.sub_path; | |
| 154 | 152 | |
| 155 | 153 | const old_file = macho_file.base.file; // TODO is this needed at all? |
| 156 | 154 | defer macho_file.base.file = old_file; |
| ... | ... | @@ -158,7 +156,7 @@ pub fn linkWithZld( |
| 158 | 156 | const file = try directory.handle.createFile(sub_path, .{ |
| 159 | 157 | .truncate = true, |
| 160 | 158 | .read = true, |
| 161 | .mode = link.determineMode(options.*), | |
| 159 | .mode = link.File.determineMode(false, output_mode, link_mode), | |
| 162 | 160 | }); |
| 163 | 161 | defer file.close(); |
| 164 | 162 | macho_file.base.file = file; |
| ... | ... | @@ -175,8 +173,8 @@ pub fn linkWithZld( |
| 175 | 173 | |
| 176 | 174 | // Positional arguments to the linker such as object files and static archives. |
| 177 | 175 | 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); | |
| 180 | 178 | |
| 181 | 179 | for (comp.c_object_table.keys()) |key| { |
| 182 | 180 | try positionals.append(.{ .path = key.status.success.object_path }); |
| ... | ... | @@ -190,7 +188,7 @@ pub fn linkWithZld( |
| 190 | 188 | if (comp.compiler_rt_obj) |obj| try positionals.append(.{ .path = obj.full_object_path }); |
| 191 | 189 | |
| 192 | 190 | // libc++ dep |
| 193 | if (options.link_libcpp) { | |
| 191 | if (comp.config.link_libcpp) { | |
| 194 | 192 | try positionals.ensureUnusedCapacity(2); |
| 195 | 193 | positionals.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path }); |
| 196 | 194 | positionals.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path }); |
| ... | ... | @@ -199,23 +197,23 @@ pub fn linkWithZld( |
| 199 | 197 | var libs = std.StringArrayHashMap(link.SystemLib).init(arena); |
| 200 | 198 | |
| 201 | 199 | { |
| 202 | const vals = options.system_libs.values(); | |
| 200 | const vals = comp.system_libs.values(); | |
| 203 | 201 | try libs.ensureUnusedCapacity(vals.len); |
| 204 | 202 | for (vals) |v| libs.putAssumeCapacity(v.path.?, v); |
| 205 | 203 | } |
| 206 | 204 | |
| 207 | 205 | { |
| 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, .{ | |
| 210 | 208 | .needed = v.needed, |
| 211 | 209 | .weak = v.weak, |
| 212 | 210 | .path = v.path, |
| 213 | 211 | }); |
| 214 | 212 | } |
| 215 | 213 | |
| 216 | try macho_file.resolveLibSystem(arena, comp, options.lib_dirs, &libs); | |
| 214 | try macho_file.resolveLibSystem(arena, comp, &libs); | |
| 217 | 215 | |
| 218 | if (options.verbose_link) { | |
| 216 | if (comp.verbose_link) { | |
| 219 | 217 | var argv = std.ArrayList([]const u8).init(arena); |
| 220 | 218 | |
| 221 | 219 | try argv.append("zig"); |
| ... | ... | @@ -228,19 +226,19 @@ pub fn linkWithZld( |
| 228 | 226 | if (is_dyn_lib) { |
| 229 | 227 | try argv.append("-dylib"); |
| 230 | 228 | |
| 231 | if (options.install_name) |install_name| { | |
| 229 | if (macho_file.install_name) |install_name| { | |
| 232 | 230 | try argv.append("-install_name"); |
| 233 | 231 | try argv.append(install_name); |
| 234 | 232 | } |
| 235 | 233 | } |
| 236 | 234 | |
| 237 | 235 | { |
| 238 | const platform = Platform.fromTarget(options.target); | |
| 236 | const platform = Platform.fromTarget(target); | |
| 239 | 237 | try argv.append("-platform_version"); |
| 240 | 238 | try argv.append(@tagName(platform.os_tag)); |
| 241 | 239 | try argv.append(try std.fmt.allocPrint(arena, "{}", .{platform.version})); |
| 242 | 240 | |
| 243 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); | |
| 241 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(macho_file); | |
| 244 | 242 | if (sdk_version) |ver| { |
| 245 | 243 | try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor })); |
| 246 | 244 | } else { |
| ... | ... | @@ -248,44 +246,38 @@ pub fn linkWithZld( |
| 248 | 246 | } |
| 249 | 247 | } |
| 250 | 248 | |
| 251 | if (options.sysroot) |syslibroot| { | |
| 249 | if (comp.sysroot) |syslibroot| { | |
| 252 | 250 | try argv.append("-syslibroot"); |
| 253 | 251 | try argv.append(syslibroot); |
| 254 | 252 | } |
| 255 | 253 | |
| 256 | for (options.rpath_list) |rpath| { | |
| 254 | for (macho_file.base.rpath_list) |rpath| { | |
| 257 | 255 | try argv.append("-rpath"); |
| 258 | 256 | try argv.append(rpath); |
| 259 | 257 | } |
| 260 | 258 | |
| 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 | }); | |
| 270 | 263 | |
| 271 | if (options.headerpad_max_install_names) { | |
| 264 | if (macho_file.headerpad_max_install_names) { | |
| 272 | 265 | try argv.append("-headerpad_max_install_names"); |
| 273 | 266 | } |
| 274 | 267 | |
| 275 | if (gc_sections) { | |
| 268 | if (macho_file.base.gc_sections) { | |
| 276 | 269 | try argv.append("-dead_strip"); |
| 277 | 270 | } |
| 278 | 271 | |
| 279 | if (options.dead_strip_dylibs) { | |
| 272 | if (macho_file.dead_strip_dylibs) { | |
| 280 | 273 | try argv.append("-dead_strip_dylibs"); |
| 281 | 274 | } |
| 282 | 275 | |
| 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 }); | |
| 286 | 278 | } |
| 287 | 279 | |
| 288 | for (options.objects) |obj| { | |
| 280 | for (objects) |obj| { | |
| 289 | 281 | if (obj.must_link) { |
| 290 | 282 | try argv.append("-force_load"); |
| 291 | 283 | } |
| ... | ... | @@ -303,7 +295,7 @@ pub fn linkWithZld( |
| 303 | 295 | if (comp.compiler_rt_lib) |lib| try argv.append(lib.full_object_path); |
| 304 | 296 | if (comp.compiler_rt_obj) |obj| try argv.append(obj.full_object_path); |
| 305 | 297 | |
| 306 | if (options.link_libcpp) { | |
| 298 | if (comp.config.link_libcpp) { | |
| 307 | 299 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 308 | 300 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 309 | 301 | } |
| ... | ... | @@ -313,8 +305,8 @@ pub fn linkWithZld( |
| 313 | 305 | |
| 314 | 306 | try argv.append("-lSystem"); |
| 315 | 307 | |
| 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).?; | |
| 318 | 310 | const arg = if (info.needed) |
| 319 | 311 | try std.fmt.allocPrint(arena, "-needed-l{s}", .{l_name}) |
| 320 | 312 | else if (info.weak) |
| ... | ... | @@ -324,11 +316,7 @@ pub fn linkWithZld( |
| 324 | 316 | try argv.append(arg); |
| 325 | 317 | } |
| 326 | 318 | |
| 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| { | |
| 332 | 320 | const name = std.fs.path.stem(framework.path); |
| 333 | 321 | const arg = if (framework.needed) |
| 334 | 322 | try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name}) |
| ... | ... | @@ -339,11 +327,7 @@ pub fn linkWithZld( |
| 339 | 327 | try argv.append(arg); |
| 340 | 328 | } |
| 341 | 329 | |
| 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) { | |
| 347 | 331 | try argv.append("-undefined"); |
| 348 | 332 | try argv.append("dynamic_lookup"); |
| 349 | 333 | } |
| ... | ... | @@ -412,14 +396,14 @@ pub fn linkWithZld( |
| 412 | 396 | }; |
| 413 | 397 | } |
| 414 | 398 | |
| 415 | if (gc_sections) { | |
| 399 | if (macho_file.base.gc_sections) { | |
| 416 | 400 | try dead_strip.gcAtoms(macho_file); |
| 417 | 401 | } |
| 418 | 402 | |
| 419 | 403 | try macho_file.createDyldPrivateAtom(); |
| 420 | 404 | try macho_file.createTentativeDefAtoms(); |
| 421 | 405 | |
| 422 | if (macho_file.base.options.output_mode == .Exe) { | |
| 406 | if (comp.config.output_mode == .Exe) { | |
| 423 | 407 | const global = macho_file.getEntryPoint().?; |
| 424 | 408 | if (macho_file.getSymbol(global).undf()) { |
| 425 | 409 | // 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( |
| 470 | 454 | } |
| 471 | 455 | |
| 472 | 456 | 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); | |
| 474 | 458 | try writeDyldPrivateAtom(macho_file); |
| 475 | 459 | |
| 476 | 460 | if (macho_file.stubs_section_index) |_| { |
| ... | ... | @@ -511,7 +495,7 @@ pub fn linkWithZld( |
| 511 | 495 | } |
| 512 | 496 | |
| 513 | 497 | // 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: { | |
| 515 | 499 | // Preallocate space for the code signature. |
| 516 | 500 | // We need to do this at this stage so that we have the load commands with proper values |
| 517 | 501 | // written out to the file. |
| ... | ... | @@ -519,7 +503,7 @@ pub fn linkWithZld( |
| 519 | 503 | // where the code signature goes into. |
| 520 | 504 | var codesig = CodeSignature.init(MachO.getPageSize(cpu_arch)); |
| 521 | 505 | codesig.code_directory.ident = fs.path.basename(full_out_path); |
| 522 | if (options.entitlements) |path| { | |
| 506 | if (macho_file.entitlements) |path| { | |
| 523 | 507 | try codesig.addEntitlements(gpa, path); |
| 524 | 508 | } |
| 525 | 509 | try macho_file.writeCodeSignaturePadding(&codesig); |
| ... | ... | @@ -539,7 +523,7 @@ pub fn linkWithZld( |
| 539 | 523 | try lc_writer.writeStruct(macho_file.dysymtab_cmd); |
| 540 | 524 | try load_commands.writeDylinkerLC(lc_writer); |
| 541 | 525 | |
| 542 | switch (macho_file.base.options.output_mode) { | |
| 526 | switch (output_mode) { | |
| 543 | 527 | .Exe => blk: { |
| 544 | 528 | const seg_id = macho_file.header_segment_cmd_index.?; |
| 545 | 529 | const seg = macho_file.segments.items[seg_id]; |
| ... | ... | @@ -555,22 +539,22 @@ pub fn linkWithZld( |
| 555 | 539 | |
| 556 | 540 | try lc_writer.writeStruct(macho.entry_point_command{ |
| 557 | 541 | .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, | |
| 559 | 543 | }); |
| 560 | 544 | }, |
| 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); | |
| 563 | 547 | }, |
| 564 | 548 | else => {}, |
| 565 | 549 | } |
| 566 | 550 | |
| 567 | try load_commands.writeRpathLCs(gpa, &macho_file.base.options, lc_writer); | |
| 551 | try load_commands.writeRpathLCs(macho_file, lc_writer); | |
| 568 | 552 | try lc_writer.writeStruct(macho.source_version_command{ |
| 569 | 553 | .version = 0, |
| 570 | 554 | }); |
| 571 | 555 | { |
| 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); | |
| 574 | 558 | if (platform.isBuildVersionCompatible()) { |
| 575 | 559 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| 576 | 560 | } else { |
| ... | ... | @@ -598,11 +582,11 @@ pub fn linkWithZld( |
| 598 | 582 | |
| 599 | 583 | if (codesig) |*csig| { |
| 600 | 584 | 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); | |
| 602 | 586 | } |
| 603 | 587 | } |
| 604 | 588 | |
| 605 | if (!options.disable_lld_caching) { | |
| 589 | if (!macho_file.base.disable_lld_caching) { | |
| 606 | 590 | // Update the file with the digest. If it fails we can continue; it only |
| 607 | 591 | // means that the next invocation will have an unnecessary cache miss. |
| 608 | 592 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| ... | ... | @@ -621,13 +605,14 @@ pub fn linkWithZld( |
| 621 | 605 | } |
| 622 | 606 | |
| 623 | 607 | fn 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}); | |
| 631 | 616 | log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize}); |
| 632 | 617 | } |
| 633 | 618 | macho_file.pagezero_segment_cmd_index = @intCast(macho_file.segments.items.len); |
| ... | ... | @@ -695,7 +680,8 @@ fn createSegments(macho_file: *MachO) !void { |
| 695 | 680 | } |
| 696 | 681 | |
| 697 | 682 | fn writeAtoms(macho_file: *MachO) !void { |
| 698 | const gpa = macho_file.base.allocator; | |
| 683 | const comp = macho_file.base.comp; | |
| 684 | const gpa = comp.gpa; | |
| 699 | 685 | const slice = macho_file.sections.slice(); |
| 700 | 686 | |
| 701 | 687 | for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| { |
| ... | ... | @@ -768,8 +754,10 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void { |
| 768 | 754 | } |
| 769 | 755 | |
| 770 | 756 | fn 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; | |
| 773 | 761 | |
| 774 | 762 | const sect_id = macho_file.text_section_index orelse return; |
| 775 | 763 | const header = macho_file.sections.items(.header)[sect_id]; |
| ... | ... | @@ -789,7 +777,8 @@ fn writeThunks(macho_file: *MachO) !void { |
| 789 | 777 | } |
| 790 | 778 | |
| 791 | 779 | fn 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; | |
| 793 | 782 | const header = macho_file.sections.items(.header)[sect_id]; |
| 794 | 783 | const capacity = math.cast(usize, header.size) orelse return error.Overflow; |
| 795 | 784 | var buffer = try std.ArrayList(u8).initCapacity(gpa, capacity); |
| ... | ... | @@ -803,8 +792,10 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void { |
| 803 | 792 | } |
| 804 | 793 | |
| 805 | 794 | fn 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; | |
| 808 | 799 | const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?]; |
| 809 | 800 | const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?]; |
| 810 | 801 | |
| ... | ... | @@ -825,8 +816,10 @@ fn writeStubs(macho_file: *MachO) !void { |
| 825 | 816 | } |
| 826 | 817 | |
| 827 | 818 | fn 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; | |
| 830 | 823 | const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?]; |
| 831 | 824 | |
| 832 | 825 | const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow; |
| ... | ... | @@ -868,8 +861,10 @@ fn writeStubHelpers(macho_file: *MachO) !void { |
| 868 | 861 | } |
| 869 | 862 | |
| 870 | 863 | fn 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; | |
| 873 | 868 | const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?]; |
| 874 | 869 | const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?]; |
| 875 | 870 | |
| ... | ... | @@ -900,7 +895,8 @@ fn pruneAndSortSections(macho_file: *MachO) !void { |
| 900 | 895 | } |
| 901 | 896 | }; |
| 902 | 897 | |
| 903 | const gpa = macho_file.base.allocator; | |
| 898 | const comp = macho_file.base.comp; | |
| 899 | const gpa = comp.gpa; | |
| 904 | 900 | |
| 905 | 901 | var entries = try std.ArrayList(Entry).initCapacity(gpa, macho_file.sections.slice().len); |
| 906 | 902 | defer entries.deinit(); |
| ... | ... | @@ -977,11 +973,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void { |
| 977 | 973 | } |
| 978 | 974 | |
| 979 | 975 | fn calcSectionSizes(macho_file: *MachO) !void { |
| 976 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 980 | 977 | const slice = macho_file.sections.slice(); |
| 981 | 978 | for (slice.items(.header), 0..) |*header, sect_id| { |
| 982 | 979 | if (header.size == 0) continue; |
| 983 | 980 | 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; | |
| 985 | 982 | } |
| 986 | 983 | |
| 987 | 984 | var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue; |
| ... | ... | @@ -1004,7 +1001,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 1004 | 1001 | } |
| 1005 | 1002 | } |
| 1006 | 1003 | |
| 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) { | |
| 1008 | 1005 | // Create jump/branch range extenders if needed. |
| 1009 | 1006 | try thunks.createThunks(macho_file, macho_file.text_section_index.?); |
| 1010 | 1007 | } |
| ... | ... | @@ -1056,7 +1053,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 1056 | 1053 | header.@"align" = 3; |
| 1057 | 1054 | } |
| 1058 | 1055 | |
| 1059 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 1056 | const cpu_arch = target.cpu.arch; | |
| 1060 | 1057 | |
| 1061 | 1058 | if (macho_file.stubs_section_index) |sect_id| { |
| 1062 | 1059 | const header = &macho_file.sections.items(.header)[sect_id]; |
| ... | ... | @@ -1079,11 +1076,10 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 1079 | 1076 | } |
| 1080 | 1077 | |
| 1081 | 1078 | fn allocateSegments(macho_file: *MachO) !void { |
| 1082 | const gpa = macho_file.base.allocator; | |
| 1083 | 1079 | for (macho_file.segments.items, 0..) |*segment, segment_index| { |
| 1084 | 1080 | const is_text_segment = mem.eql(u8, segment.segName(), "__TEXT"); |
| 1085 | 1081 | const base_size = if (is_text_segment) |
| 1086 | try load_commands.calcMinHeaderPad(gpa, &macho_file.base.options, .{ | |
| 1082 | try load_commands.calcMinHeaderPad(macho_file, .{ | |
| 1087 | 1083 | .segments = macho_file.segments.items, |
| 1088 | 1084 | .dylibs = macho_file.dylibs.items, |
| 1089 | 1085 | .referenced_dylibs = macho_file.referenced_dylibs.keys(), |
| ... | ... | @@ -1106,6 +1102,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u |
| 1106 | 1102 | } |
| 1107 | 1103 | |
| 1108 | 1104 | fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void { |
| 1105 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 1109 | 1106 | const segment = &macho_file.segments.items[segment_index]; |
| 1110 | 1107 | |
| 1111 | 1108 | 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 |
| 1188 | 1185 | segment.vmsize = start; |
| 1189 | 1186 | } |
| 1190 | 1187 | |
| 1191 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 1188 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 1192 | 1189 | segment.filesize = mem.alignForward(u64, segment.filesize, page_size); |
| 1193 | 1190 | segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size); |
| 1194 | 1191 | } |
src/link/NvPtx.zig+48-46| ... | ... | @@ -24,46 +24,62 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 24 | 24 | |
| 25 | 25 | base: link.File, |
| 26 | 26 | llvm_object: *LlvmObject, |
| 27 | ptx_file_name: []const u8, | |
| 28 | 27 | |
| 29 | pub 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) { | |
| 28 | pub 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) { | |
| 35 | 43 | // TODO: does it also work with nvcl ? |
| 36 | 44 | .cuda => {}, |
| 37 | 45 | else => return error.PtxArchNotSupported, |
| 38 | 46 | } |
| 39 | 47 | |
| 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); | |
| 42 | 50 | nvptx.* = .{ |
| 43 | 51 | .base = .{ |
| 44 | 52 | .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, | |
| 46 | 59 | .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, | |
| 48 | 63 | }, |
| 49 | 64 | .llvm_object = llvm_object, |
| 50 | .ptx_file_name = try std.mem.join(gpa, "", &[_][]const u8{ options.root_name, ".ptx" }), | |
| 51 | 65 | }; |
| 52 | 66 | |
| 53 | 67 | return nvptx; |
| 54 | 68 | } |
| 55 | 69 | |
| 56 | pub 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); | |
| 70 | pub 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); | |
| 62 | 79 | } |
| 63 | 80 | |
| 64 | 81 | pub 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(); | |
| 67 | 83 | } |
| 68 | 84 | |
| 69 | 85 | pub fn updateFunc(self: *NvPtx, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { |
| ... | ... | @@ -80,9 +96,9 @@ pub fn updateExports( |
| 80 | 96 | exported: Module.Exported, |
| 81 | 97 | exports: []const *Module.Export, |
| 82 | 98 | ) !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) | |
| 84 | 100 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 85 | } | |
| 101 | ||
| 86 | 102 | return self.llvm_object.updateExports(module, exported, exports); |
| 87 | 103 | } |
| 88 | 104 | |
| ... | ... | @@ -90,32 +106,18 @@ pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void { |
| 90 | 106 | return self.llvm_object.freeDecl(decl_index); |
| 91 | 107 | } |
| 92 | 108 | |
| 93 | pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 94 | return self.flushModule(comp, prog_node); | |
| 109 | pub fn flush(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 110 | return self.flushModule(arena, prog_node); | |
| 95 | 111 | } |
| 96 | 112 | |
| 97 | pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 98 | if (build_options.skip_non_native) { | |
| 113 | pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 114 | if (build_options.skip_non_native) | |
| 99 | 115 | @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 | } | |
| 119 | 116 | |
| 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"); | |
| 121 | 123 | } |
src/link/Plan9.zig+170-116| ... | ... | @@ -28,7 +28,6 @@ pub const base_tag = .plan9; |
| 28 | 28 | |
| 29 | 29 | base: link.File, |
| 30 | 30 | sixtyfour_bit: bool, |
| 31 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | |
| 32 | 31 | bases: Bases, |
| 33 | 32 | |
| 34 | 33 | /// A symbol's value is just casted down when compiling |
| ... | ... | @@ -174,7 +173,7 @@ pub const Atom = struct { |
| 174 | 173 | return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } }; |
| 175 | 174 | } |
| 176 | 175 | fn getCode(self: CodePtr, plan9: *const Plan9) []u8 { |
| 177 | const mod = plan9.base.options.module.?; | |
| 176 | const mod = plan9.base.comp.module.?; | |
| 178 | 177 | return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: { |
| 179 | 178 | const decl_index = self.other.decl_index; |
| 180 | 179 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -206,7 +205,8 @@ pub const Atom = struct { |
| 206 | 205 | |
| 207 | 206 | // asserts that self.got_index != null |
| 208 | 207 | 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); | |
| 210 | 210 | const got_addr = plan9.bases.data; |
| 211 | 211 | const got_index = self.got_index.?; |
| 212 | 212 | return got_addr + got_index * ptr_bytes; |
| ... | ... | @@ -293,38 +293,51 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { |
| 293 | 293 | }; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | pub 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()) { | |
| 296 | pub 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()) { | |
| 300 | 308 | 0...32 => false, |
| 301 | 309 | 33...64 => true, |
| 302 | 310 | else => return error.UnsupportedP9Architecture, |
| 303 | 311 | }; |
| 304 | 312 | |
| 305 | const arena_allocator = std.heap.ArenaAllocator.init(gpa); | |
| 306 | ||
| 307 | const self = try gpa.create(Plan9); | |
| 313 | const self = try arena.create(Plan9); | |
| 308 | 314 | self.* = .{ |
| 309 | .path_arena = arena_allocator, | |
| 315 | .path_arena = std.heap.ArenaAllocator.init(gpa), | |
| 310 | 316 | .base = .{ |
| 311 | 317 | .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, | |
| 314 | 324 | .file = null, |
| 325 | .disable_lld_caching = options.disable_lld_caching, | |
| 326 | .build_id = options.build_id, | |
| 327 | .rpath_list = options.rpath_list, | |
| 315 | 328 | }, |
| 316 | 329 | .sixtyfour_bit = sixtyfour_bit, |
| 317 | 330 | .bases = undefined, |
| 318 | .magic = try aout.magicFromArch(self.base.options.target.cpu.arch), | |
| 331 | .magic = try aout.magicFromArch(target.cpu.arch), | |
| 319 | 332 | }; |
| 320 | 333 | // 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); | |
| 322 | 335 | return self; |
| 323 | 336 | } |
| 324 | 337 | |
| 325 | 338 | fn 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.?; | |
| 328 | 341 | const decl = mod.declPtr(decl_index); |
| 329 | 342 | const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope(mod)); |
| 330 | 343 | if (fn_map_res.found_existing) { |
| ... | ... | @@ -379,6 +392,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi |
| 379 | 392 | } |
| 380 | 393 | |
| 381 | 394 | fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !void { |
| 395 | const gpa = self.base.comp.gpa; | |
| 382 | 396 | const sep = std.fs.path.sep; |
| 383 | 397 | var it = std.mem.tokenizeScalar(u8, path, sep); |
| 384 | 398 | while (it.next()) |component| { |
| ... | ... | @@ -386,7 +400,7 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi |
| 386 | 400 | try a.writer().writeInt(u16, num, .big); |
| 387 | 401 | } else { |
| 388 | 402 | 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); | |
| 390 | 404 | try a.writer().writeInt(u16, self.file_segments_i, .big); |
| 391 | 405 | } |
| 392 | 406 | } |
| ... | ... | @@ -397,6 +411,8 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 397 | 411 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 398 | 412 | } |
| 399 | 413 | |
| 414 | const gpa = self.base.comp.gpa; | |
| 415 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 400 | 416 | const func = mod.funcInfo(func_index); |
| 401 | 417 | const decl_index = func.owner_decl; |
| 402 | 418 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -404,15 +420,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 404 | 420 | |
| 405 | 421 | const atom_idx = try self.seeDecl(decl_index); |
| 406 | 422 | |
| 407 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | |
| 423 | var code_buffer = std.ArrayList(u8).init(gpa); | |
| 408 | 424 | defer code_buffer.deinit(); |
| 409 | 425 | var dbg_info_output: DebugInfoOutput = .{ |
| 410 | .dbg_line = std.ArrayList(u8).init(self.base.allocator), | |
| 426 | .dbg_line = std.ArrayList(u8).init(gpa), | |
| 411 | 427 | .start_line = null, |
| 412 | 428 | .end_line = undefined, |
| 413 | 429 | .pcop_change_index = null, |
| 414 | 430 | // 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, | |
| 416 | 432 | }; |
| 417 | 433 | defer dbg_info_output.dbg_line.deinit(); |
| 418 | 434 | |
| ... | ... | @@ -448,14 +464,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 448 | 464 | } |
| 449 | 465 | |
| 450 | 466 | pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 { |
| 467 | const gpa = self.base.comp.gpa; | |
| 451 | 468 | _ = 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); | |
| 453 | 470 | defer code_buffer.deinit(); |
| 454 | 471 | |
| 455 | const mod = self.base.options.module.?; | |
| 472 | const mod = self.base.comp.module.?; | |
| 456 | 473 | const decl = mod.declPtr(decl_index); |
| 457 | 474 | |
| 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); | |
| 459 | 476 | if (!gop.found_existing) { |
| 460 | 477 | gop.value_ptr.* = .{}; |
| 461 | 478 | } |
| ... | ... | @@ -465,7 +482,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De |
| 465 | 482 | |
| 466 | 483 | const index = unnamed_consts.items.len; |
| 467 | 484 | // 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 }); | |
| 469 | 486 | |
| 470 | 487 | const sym_index = try self.allocateSymbolIndex(); |
| 471 | 488 | const new_atom_idx = try self.createAtom(); |
| ... | ... | @@ -498,17 +515,18 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De |
| 498 | 515 | }, |
| 499 | 516 | }; |
| 500 | 517 | // 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); | |
| 503 | 520 | const new_atom = self.getAtomPtr(new_atom_idx); |
| 504 | 521 | new_atom.* = info; |
| 505 | 522 | 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); | |
| 507 | 524 | // we return the new_atom_idx to codegen |
| 508 | 525 | return new_atom_idx; |
| 509 | 526 | } |
| 510 | 527 | |
| 511 | 528 | pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void { |
| 529 | const gpa = self.base.comp.gpa; | |
| 512 | 530 | const decl = mod.declPtr(decl_index); |
| 513 | 531 | |
| 514 | 532 | if (decl.isExtern(mod)) { |
| ... | ... | @@ -517,7 +535,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) |
| 517 | 535 | } |
| 518 | 536 | const atom_idx = try self.seeDecl(decl_index); |
| 519 | 537 | |
| 520 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | |
| 538 | var code_buffer = std.ArrayList(u8).init(gpa); | |
| 521 | 539 | defer code_buffer.deinit(); |
| 522 | 540 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 523 | 541 | // 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) |
| 535 | 553 | return; |
| 536 | 554 | }, |
| 537 | 555 | }; |
| 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); | |
| 540 | 558 | self.getAtomPtr(self.decls.get(decl_index).?.index).code = .{ .code_ptr = null, .other = .{ .decl_index = decl_index } }; |
| 541 | 559 | 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); | |
| 543 | 561 | } |
| 544 | 562 | return self.updateFinish(decl_index); |
| 545 | 563 | } |
| 546 | 564 | /// called at the end of update{Decl,Func} |
| 547 | 565 | fn 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.?; | |
| 549 | 568 | const decl = mod.declPtr(decl_index); |
| 550 | 569 | const is_fn = (decl.ty.zigTypeTag(mod) == .Fn); |
| 551 | 570 | 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 { |
| 558 | 577 | const sym: aout.Sym = .{ |
| 559 | 578 | .value = undefined, // the value of stuff gets filled in in flushModule |
| 560 | 579 | .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)), | |
| 562 | 581 | }; |
| 563 | 582 | |
| 564 | 583 | if (atom.sym_index) |s| { |
| ... | ... | @@ -571,10 +590,11 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void { |
| 571 | 590 | } |
| 572 | 591 | |
| 573 | 592 | fn allocateSymbolIndex(self: *Plan9) !usize { |
| 593 | const gpa = self.base.comp.gpa; | |
| 574 | 594 | if (self.syms_index_free_list.popOrNull()) |i| { |
| 575 | 595 | return i; |
| 576 | 596 | } else { |
| 577 | _ = try self.syms.addOne(self.base.allocator); | |
| 597 | _ = try self.syms.addOne(gpa); | |
| 578 | 598 | return self.syms.items.len - 1; |
| 579 | 599 | } |
| 580 | 600 | } |
| ... | ... | @@ -588,16 +608,18 @@ fn allocateGotIndex(self: *Plan9) usize { |
| 588 | 608 | } |
| 589 | 609 | } |
| 590 | 610 | |
| 591 | pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 592 | assert(!self.base.options.use_lld); | |
| 611 | pub 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); | |
| 593 | 615 | |
| 594 | switch (self.base.options.effectiveOutputMode()) { | |
| 616 | switch (link.File.effectiveOutputMode(use_lld, comp.config.output_mode)) { | |
| 595 | 617 | .Exe => {}, |
| 596 | 618 | // plan9 object files are totally different |
| 597 | 619 | .Obj => return error.TODOImplementPlan9Objs, |
| 598 | 620 | .Lib => return error.TODOImplementWritingLibFiles, |
| 599 | 621 | } |
| 600 | return self.flushModule(comp, prog_node); | |
| 622 | return self.flushModule(arena, prog_node); | |
| 601 | 623 | } |
| 602 | 624 | |
| 603 | 625 | pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void { |
| ... | ... | @@ -645,12 +667,17 @@ fn atomCount(self: *Plan9) usize { |
| 645 | 667 | return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count; |
| 646 | 668 | } |
| 647 | 669 | |
| 648 | pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 670 | pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 649 | 671 | if (build_options.skip_non_native and builtin.object_format != .plan9) { |
| 650 | 672 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| 651 | 673 | } |
| 652 | 674 | |
| 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 | ||
| 654 | 681 | const tracy = trace(@src()); |
| 655 | 682 | defer tracy.end(); |
| 656 | 683 | |
| ... | ... | @@ -662,7 +689,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 662 | 689 | |
| 663 | 690 | defer assert(self.hdr.entry != 0x0); |
| 664 | 691 | |
| 665 | const mod = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; | |
| 692 | const mod = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; | |
| 666 | 693 | |
| 667 | 694 | // finish up the lazy syms |
| 668 | 695 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| ... | ... | @@ -691,12 +718,12 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 691 | 718 | const atom_count = self.atomCount(); |
| 692 | 719 | assert(self.got_len == atom_count + self.got_index_free_list.items.len); |
| 693 | 720 | 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); | |
| 696 | 723 | |
| 697 | 724 | // + 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); | |
| 700 | 727 | |
| 701 | 728 | const file = self.base.file.?; |
| 702 | 729 | |
| ... | ... | @@ -709,7 +736,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 709 | 736 | var iovecs_i: usize = 1; |
| 710 | 737 | var text_i: u64 = 0; |
| 711 | 738 | |
| 712 | var linecountinfo = std.ArrayList(u8).init(self.base.allocator); | |
| 739 | var linecountinfo = std.ArrayList(u8).init(gpa); | |
| 713 | 740 | defer linecountinfo.deinit(); |
| 714 | 741 | // text |
| 715 | 742 | { |
| ... | ... | @@ -741,9 +768,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 741 | 768 | atom.offset = off; |
| 742 | 769 | 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 }); |
| 743 | 770 | 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()); | |
| 745 | 772 | } 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()); | |
| 747 | 774 | } |
| 748 | 775 | self.syms.items[atom.sym_index.?].value = off; |
| 749 | 776 | if (mod.decl_exports.get(decl_index)) |exports| { |
| ... | ... | @@ -770,9 +797,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 770 | 797 | text_i += code.len; |
| 771 | 798 | text_atom.offset = off; |
| 772 | 799 | 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()); | |
| 774 | 801 | } 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()); | |
| 776 | 803 | } |
| 777 | 804 | self.syms.items[text_atom.sym_index.?].value = off; |
| 778 | 805 | } |
| ... | ... | @@ -783,9 +810,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 783 | 810 | const val = self.getAddr(text_i, .t); |
| 784 | 811 | self.syms.items[etext_atom.sym_index.?].value = val; |
| 785 | 812 | 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()); | |
| 787 | 814 | } 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()); | |
| 789 | 816 | } |
| 790 | 817 | } |
| 791 | 818 | // global offset table is in data |
| ... | ... | @@ -807,9 +834,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 807 | 834 | data_i += code.len; |
| 808 | 835 | atom.offset = off; |
| 809 | 836 | 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()); | |
| 811 | 838 | } 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()); | |
| 813 | 840 | } |
| 814 | 841 | self.syms.items[atom.sym_index.?].value = off; |
| 815 | 842 | if (mod.decl_exports.get(decl_index)) |exports| { |
| ... | ... | @@ -830,9 +857,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 830 | 857 | data_i += code.len; |
| 831 | 858 | atom.offset = off; |
| 832 | 859 | 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()); | |
| 834 | 861 | } 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()); | |
| 836 | 863 | } |
| 837 | 864 | self.syms.items[atom.sym_index.?].value = off; |
| 838 | 865 | } |
| ... | ... | @@ -851,9 +878,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 851 | 878 | data_i += code.len; |
| 852 | 879 | atom.offset = off; |
| 853 | 880 | 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()); | |
| 855 | 882 | } 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()); | |
| 857 | 884 | } |
| 858 | 885 | self.syms.items[atom.sym_index.?].value = off; |
| 859 | 886 | } |
| ... | ... | @@ -871,9 +898,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 871 | 898 | data_i += code.len; |
| 872 | 899 | data_atom.offset = off; |
| 873 | 900 | 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()); | |
| 875 | 902 | } 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()); | |
| 877 | 904 | } |
| 878 | 905 | self.syms.items[data_atom.sym_index.?].value = off; |
| 879 | 906 | } |
| ... | ... | @@ -883,9 +910,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 883 | 910 | const val = self.getAddr(data_i, .b); |
| 884 | 911 | self.syms.items[edata_atom.sym_index.?].value = val; |
| 885 | 912 | 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()); | |
| 887 | 914 | } 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()); | |
| 889 | 916 | } |
| 890 | 917 | } |
| 891 | 918 | // 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 |
| 894 | 921 | const val = self.getAddr(data_i, .b); |
| 895 | 922 | self.syms.items[end_atom.sym_index.?].value = val; |
| 896 | 923 | 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()); | |
| 898 | 925 | } else { |
| 899 | 926 | 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()); | |
| 901 | 928 | } |
| 902 | 929 | } |
| 903 | 930 | } |
| 904 | var sym_buf = std.ArrayList(u8).init(self.base.allocator); | |
| 931 | var sym_buf = std.ArrayList(u8).init(gpa); | |
| 905 | 932 | try self.writeSyms(&sym_buf); |
| 906 | 933 | const syms = try sym_buf.toOwnedSlice(); |
| 907 | defer self.base.allocator.free(syms); | |
| 934 | defer gpa.free(syms); | |
| 908 | 935 | assert(2 + self.atomCount() - self.externCount() == iovecs_i); // we didn't write all the decls |
| 909 | 936 | iovecs[iovecs_i] = .{ .iov_base = syms.ptr, .iov_len = syms.len }; |
| 910 | 937 | iovecs_i += 1; |
| ... | ... | @@ -934,7 +961,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 934 | 961 | const source_atom = self.getAtom(source_atom_index); |
| 935 | 962 | const source_atom_symbol = self.syms.items[source_atom.sym_index.?]; |
| 936 | 963 | const code = source_atom.code.getCode(self); |
| 937 | const endian = self.base.options.target.cpu.arch.endian(); | |
| 964 | const endian = target.cpu.arch.endian(); | |
| 938 | 965 | for (kv.value_ptr.items) |reloc| { |
| 939 | 966 | const offset = reloc.offset; |
| 940 | 967 | const addend = reloc.addend; |
| ... | ... | @@ -985,6 +1012,7 @@ fn addDeclExports( |
| 985 | 1012 | decl_index: InternPool.DeclIndex, |
| 986 | 1013 | exports: []const *Module.Export, |
| 987 | 1014 | ) !void { |
| 1015 | const gpa = self.base.comp.gpa; | |
| 988 | 1016 | const metadata = self.decls.getPtr(decl_index).?; |
| 989 | 1017 | const atom = self.getAtom(metadata.index); |
| 990 | 1018 | |
| ... | ... | @@ -994,7 +1022,7 @@ fn addDeclExports( |
| 994 | 1022 | if (exp.opts.section.unwrap()) |section_name| { |
| 995 | 1023 | if (!mod.intern_pool.stringEqlSlice(section_name, ".text") and !mod.intern_pool.stringEqlSlice(section_name, ".data")) { |
| 996 | 1024 | try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create( |
| 997 | self.base.allocator, | |
| 1025 | gpa, | |
| 998 | 1026 | mod.declPtr(decl_index).srcLoc(mod), |
| 999 | 1027 | "plan9 does not support extra sections", |
| 1000 | 1028 | .{}, |
| ... | ... | @@ -1005,41 +1033,42 @@ fn addDeclExports( |
| 1005 | 1033 | const sym = .{ |
| 1006 | 1034 | .value = atom.offset.?, |
| 1007 | 1035 | .type = atom.type.toGlobal(), |
| 1008 | .name = try self.base.allocator.dupe(u8, exp_name), | |
| 1036 | .name = try gpa.dupe(u8, exp_name), | |
| 1009 | 1037 | }; |
| 1010 | 1038 | |
| 1011 | 1039 | if (metadata.getExport(self, exp_name)) |i| { |
| 1012 | 1040 | self.syms.items[i] = sym; |
| 1013 | 1041 | } 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); | |
| 1016 | 1044 | } |
| 1017 | 1045 | } |
| 1018 | 1046 | } |
| 1019 | 1047 | |
| 1020 | 1048 | pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void { |
| 1049 | const gpa = self.base.comp.gpa; | |
| 1021 | 1050 | // TODO audit the lifetimes of decls table entries. It's possible to get |
| 1022 | 1051 | // freeDecl without any updateDecl in between. |
| 1023 | 1052 | // However that is planned to change, see the TODO comment in Module.zig |
| 1024 | 1053 | // in the deleteUnusedDecl function. |
| 1025 | const mod = self.base.options.module.?; | |
| 1054 | const mod = self.base.comp.module.?; | |
| 1026 | 1055 | const decl = mod.declPtr(decl_index); |
| 1027 | 1056 | const is_fn = decl.val.isFuncBody(mod); |
| 1028 | 1057 | if (is_fn) { |
| 1029 | 1058 | const symidx_and_submap = self.fn_decl_table.get(decl.getFileScope(mod)).?; |
| 1030 | 1059 | var submap = symidx_and_submap.functions; |
| 1031 | 1060 | 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); | |
| 1034 | 1063 | } |
| 1035 | 1064 | if (submap.count() == 0) { |
| 1036 | 1065 | 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); | |
| 1039 | 1068 | } |
| 1040 | 1069 | } else { |
| 1041 | 1070 | if (self.data_decl_table.fetchSwapRemove(decl_index)) |removed_entry| { |
| 1042 | self.base.allocator.free(removed_entry.value); | |
| 1071 | gpa.free(removed_entry.value); | |
| 1043 | 1072 | } |
| 1044 | 1073 | } |
| 1045 | 1074 | if (self.decls.fetchRemove(decl_index)) |const_kv| { |
| ... | ... | @@ -1047,35 +1076,36 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void { |
| 1047 | 1076 | const atom = self.getAtom(kv.value.index); |
| 1048 | 1077 | if (atom.got_index) |i| { |
| 1049 | 1078 | // 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 {}; | |
| 1051 | 1080 | } |
| 1052 | 1081 | 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 {}; | |
| 1054 | 1083 | self.syms.items[i] = aout.Sym.undefined_symbol; |
| 1055 | 1084 | } |
| 1056 | kv.value.exports.deinit(self.base.allocator); | |
| 1085 | kv.value.exports.deinit(gpa); | |
| 1057 | 1086 | } |
| 1058 | 1087 | self.freeUnnamedConsts(decl_index); |
| 1059 | 1088 | { |
| 1060 | 1089 | const atom_index = self.decls.get(decl_index).?.index; |
| 1061 | 1090 | const relocs = self.relocs.getPtr(atom_index) orelse return; |
| 1062 | relocs.clearAndFree(self.base.allocator); | |
| 1091 | relocs.clearAndFree(gpa); | |
| 1063 | 1092 | assert(self.relocs.remove(atom_index)); |
| 1064 | 1093 | } |
| 1065 | 1094 | } |
| 1066 | 1095 | fn freeUnnamedConsts(self: *Plan9, decl_index: InternPool.DeclIndex) void { |
| 1096 | const gpa = self.base.comp.gpa; | |
| 1067 | 1097 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 1068 | 1098 | for (unnamed_consts.items) |atom_idx| { |
| 1069 | 1099 | 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); | |
| 1071 | 1101 | 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 {}; | |
| 1073 | 1103 | } |
| 1074 | unnamed_consts.clearAndFree(self.base.allocator); | |
| 1104 | unnamed_consts.clearAndFree(gpa); | |
| 1075 | 1105 | } |
| 1076 | 1106 | |
| 1077 | 1107 | fn createAtom(self: *Plan9) !Atom.Index { |
| 1078 | const gpa = self.base.allocator; | |
| 1108 | const gpa = self.base.comp.gpa; | |
| 1079 | 1109 | const index = @as(Atom.Index, @intCast(self.atoms.items.len)); |
| 1080 | 1110 | const atom = try self.atoms.addOne(gpa); |
| 1081 | 1111 | atom.* = .{ |
| ... | ... | @@ -1089,7 +1119,8 @@ fn createAtom(self: *Plan9) !Atom.Index { |
| 1089 | 1119 | } |
| 1090 | 1120 | |
| 1091 | 1121 | pub 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); | |
| 1093 | 1124 | if (!gop.found_existing) { |
| 1094 | 1125 | const index = try self.createAtom(); |
| 1095 | 1126 | self.getAtomPtr(index).got_index = self.allocateGotIndex(); |
| ... | ... | @@ -1100,7 +1131,7 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index { |
| 1100 | 1131 | } |
| 1101 | 1132 | const atom_idx = gop.value_ptr.index; |
| 1102 | 1133 | // 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.?; | |
| 1104 | 1135 | const decl = mod.declPtr(decl_index); |
| 1105 | 1136 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 1106 | 1137 | if (decl.isExtern(mod)) { |
| ... | ... | @@ -1134,7 +1165,8 @@ pub fn updateExports( |
| 1134 | 1165 | } |
| 1135 | 1166 | |
| 1136 | 1167 | pub 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.?)); | |
| 1138 | 1170 | errdefer _ = if (!gop.found_existing) self.lazy_syms.pop(); |
| 1139 | 1171 | |
| 1140 | 1172 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| ... | ... | @@ -1153,15 +1185,15 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In |
| 1153 | 1185 | _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self); |
| 1154 | 1186 | _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self); |
| 1155 | 1187 | // 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) { | |
| 1157 | 1189 | try self.updateLazySymbolAtom(sym, atom); |
| 1158 | 1190 | } |
| 1159 | 1191 | return atom; |
| 1160 | 1192 | } |
| 1161 | 1193 | |
| 1162 | 1194 | fn 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.?; | |
| 1165 | 1197 | |
| 1166 | 1198 | var required_alignment: InternPool.Alignment = .none; |
| 1167 | 1199 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -1206,8 +1238,8 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind |
| 1206 | 1238 | }, |
| 1207 | 1239 | }; |
| 1208 | 1240 | // 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); | |
| 1211 | 1243 | self.getAtomPtr(atom_index).code = .{ |
| 1212 | 1244 | .code_ptr = duped_code.ptr, |
| 1213 | 1245 | .other = .{ .code_len = duped_code.len }, |
| ... | ... | @@ -1215,13 +1247,13 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind |
| 1215 | 1247 | } |
| 1216 | 1248 | |
| 1217 | 1249 | pub fn deinit(self: *Plan9) void { |
| 1218 | const gpa = self.base.allocator; | |
| 1250 | const gpa = self.base.comp.gpa; | |
| 1219 | 1251 | { |
| 1220 | 1252 | var it = self.relocs.valueIterator(); |
| 1221 | 1253 | while (it.next()) |relocs| { |
| 1222 | relocs.deinit(self.base.allocator); | |
| 1254 | relocs.deinit(gpa); | |
| 1223 | 1255 | } |
| 1224 | self.relocs.deinit(self.base.allocator); | |
| 1256 | self.relocs.deinit(gpa); | |
| 1225 | 1257 | } |
| 1226 | 1258 | // free the unnamed consts |
| 1227 | 1259 | var it_unc = self.unnamed_const_atoms.iterator(); |
| ... | ... | @@ -1280,24 +1312,39 @@ pub fn deinit(self: *Plan9) void { |
| 1280 | 1312 | } |
| 1281 | 1313 | } |
| 1282 | 1314 | |
| 1283 | pub 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); | |
| 1315 | pub 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); | |
| 1289 | 1330 | errdefer self.base.destroy(); |
| 1290 | 1331 | |
| 1291 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ | |
| 1332 | const file = try emit.directory.handle.createFile(emit.sub_path, .{ | |
| 1292 | 1333 | .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 | ), | |
| 1294 | 1339 | }); |
| 1295 | 1340 | errdefer file.close(); |
| 1296 | 1341 | self.base.file = file; |
| 1297 | 1342 | |
| 1298 | self.bases = defaultBaseAddrs(options.target.cpu.arch); | |
| 1343 | self.bases = defaultBaseAddrs(target.cpu.arch); | |
| 1299 | 1344 | |
| 1300 | try self.syms.appendSlice(self.base.allocator, &.{ | |
| 1345 | const gpa = comp.gpa; | |
| 1346 | ||
| 1347 | try self.syms.appendSlice(gpa, &.{ | |
| 1301 | 1348 | // we include the global offset table to make it easier for debugging |
| 1302 | 1349 | .{ |
| 1303 | 1350 | .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 { |
| 1323 | 1370 | } |
| 1324 | 1371 | |
| 1325 | 1372 | pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1326 | const mod = self.base.options.module.?; | |
| 1373 | const mod = self.base.comp.module.?; | |
| 1327 | 1374 | const ip = &mod.intern_pool; |
| 1328 | 1375 | const writer = buf.writer(); |
| 1329 | 1376 | // write __GOT |
| ... | ... | @@ -1349,7 +1396,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1349 | 1396 | const atom = self.getAtom(decl_metadata.index); |
| 1350 | 1397 | const sym = self.syms.items[atom.sym_index.?]; |
| 1351 | 1398 | 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| { | |
| 1353 | 1400 | for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| { |
| 1354 | 1401 | try self.writeSym(writer, self.syms.items[exp_i]); |
| 1355 | 1402 | }; |
| ... | ... | @@ -1396,7 +1443,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { |
| 1396 | 1443 | const atom = self.getAtom(decl_metadata.index); |
| 1397 | 1444 | const sym = self.syms.items[atom.sym_index.?]; |
| 1398 | 1445 | 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| { | |
| 1400 | 1447 | for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| { |
| 1401 | 1448 | const s = self.syms.items[exp_i]; |
| 1402 | 1449 | if (mem.eql(u8, s.name, "_start")) |
| ... | ... | @@ -1439,7 +1486,7 @@ pub fn getDeclVAddr( |
| 1439 | 1486 | decl_index: InternPool.DeclIndex, |
| 1440 | 1487 | reloc_info: link.File.RelocInfo, |
| 1441 | 1488 | ) !u64 { |
| 1442 | const mod = self.base.options.module.?; | |
| 1489 | const mod = self.base.comp.module.?; | |
| 1443 | 1490 | const decl = mod.declPtr(decl_index); |
| 1444 | 1491 | log.debug("getDeclVAddr for {s}", .{mod.intern_pool.stringToSlice(decl.name)}); |
| 1445 | 1492 | if (decl.isExtern(mod)) { |
| ... | ... | @@ -1480,7 +1527,13 @@ pub fn getDeclVAddr( |
| 1480 | 1527 | return undefined; |
| 1481 | 1528 | } |
| 1482 | 1529 | |
| 1483 | pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1530 | pub 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; | |
| 1484 | 1537 | // This is basically the same as lowerUnnamedConst. |
| 1485 | 1538 | // example: |
| 1486 | 1539 | // 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 |
| 1490 | 1543 | // be used by more than one function, however, its address is being used so we need |
| 1491 | 1544 | // to put it in some location. |
| 1492 | 1545 | // ... |
| 1493 | const gpa = self.base.allocator; | |
| 1546 | const gpa = self.base.comp.gpa; | |
| 1494 | 1547 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 1495 | const mod = self.base.options.module.?; | |
| 1548 | const mod = self.base.comp.module.?; | |
| 1496 | 1549 | if (!gop.found_existing) { |
| 1497 | 1550 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1498 | 1551 | const val = Value.fromInterned(decl_val); |
| ... | ... | @@ -1538,11 +1591,12 @@ pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: li |
| 1538 | 1591 | } |
| 1539 | 1592 | |
| 1540 | 1593 | pub 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); | |
| 1542 | 1596 | if (!gop.found_existing) { |
| 1543 | 1597 | gop.value_ptr.* = .{}; |
| 1544 | 1598 | } |
| 1545 | try gop.value_ptr.append(self.base.allocator, reloc); | |
| 1599 | try gop.value_ptr.append(gpa, reloc); | |
| 1546 | 1600 | } |
| 1547 | 1601 | |
| 1548 | 1602 | pub fn getAtom(self: *const Plan9, index: Atom.Index) Atom { |
src/link/SpirV.zig+62-34| ... | ... | @@ -24,7 +24,6 @@ const SpirV = @This(); |
| 24 | 24 | |
| 25 | 25 | const std = @import("std"); |
| 26 | 26 | const Allocator = std.mem.Allocator; |
| 27 | const ArenaAllocator = std.heap.ArenaAllocator; | |
| 28 | 27 | const assert = std.debug.assert; |
| 29 | 28 | const log = std.log.scoped(.link); |
| 30 | 29 | |
| ... | ... | @@ -47,48 +46,73 @@ base: link.File, |
| 47 | 46 | |
| 48 | 47 | object: codegen.Object, |
| 49 | 48 | |
| 50 | pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV { | |
| 51 | const self = try gpa.create(SpirV); | |
| 49 | pub const base_tag: link.File.Tag = .spirv; | |
| 50 | ||
| 51 | pub 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); | |
| 52 | 61 | self.* = .{ |
| 53 | 62 | .base = .{ |
| 54 | 63 | .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, | |
| 56 | 70 | .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, | |
| 58 | 74 | }, |
| 59 | 75 | .object = codegen.Object.init(gpa), |
| 60 | 76 | }; |
| 61 | 77 | errdefer self.deinit(); |
| 62 | 78 | |
| 63 | // TODO: Figure out where to put all of these | |
| 64 | switch (options.target.cpu.arch) { | |
| 79 | switch (target.cpu.arch) { | |
| 65 | 80 | .spirv32, .spirv64 => {}, |
| 66 | else => return error.TODOArchNotSupported, | |
| 81 | else => unreachable, // Caught by Compilation.Config.resolve. | |
| 67 | 82 | } |
| 68 | 83 | |
| 69 | switch (options.target.os.tag) { | |
| 84 | switch (target.os.tag) { | |
| 70 | 85 | .opencl, .glsl450, .vulkan => {}, |
| 71 | else => return error.TODOOsNotSupported, | |
| 86 | else => unreachable, // Caught by Compilation.Config.resolve. | |
| 72 | 87 | } |
| 73 | 88 | |
| 74 | if (options.target.abi != .none) { | |
| 75 | return error.TODOAbiNotSupported; | |
| 76 | } | |
| 89 | assert(target.abi != .none); // Caught by Compilation.Config.resolve. | |
| 77 | 90 | |
| 78 | 91 | return self; |
| 79 | 92 | } |
| 80 | 93 | |
| 81 | pub 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); | |
| 94 | pub 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); | |
| 88 | 109 | errdefer spirv.base.destroy(); |
| 89 | 110 | |
| 90 | 111 | // 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 | }); | |
| 92 | 116 | spirv.base.file = file; |
| 93 | 117 | return spirv; |
| 94 | 118 | } |
| ... | ... | @@ -149,19 +173,17 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void { |
| 149 | 173 | _ = decl_index; |
| 150 | 174 | } |
| 151 | 175 | |
| 152 | pub 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 | } | |
| 176 | pub fn flush(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 177 | return self.flushModule(arena, prog_node); | |
| 158 | 178 | } |
| 159 | 179 | |
| 160 | pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 180 | pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 161 | 181 | if (build_options.skip_non_native) { |
| 162 | 182 | @panic("Attempted to compile for architecture that was disabled by build configuration"); |
| 163 | 183 | } |
| 164 | 184 | |
| 185 | _ = arena; // Has the same lifetime as the call to Compilation.update. | |
| 186 | ||
| 165 | 187 | const tracy = trace(@src()); |
| 166 | 188 | defer tracy.end(); |
| 167 | 189 | |
| ... | ... | @@ -171,7 +193,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 171 | 193 | |
| 172 | 194 | const spv = &self.object.spv; |
| 173 | 195 | |
| 196 | const comp = self.base.comp; | |
| 197 | const gpa = comp.gpa; | |
| 174 | 198 | const target = comp.getTarget(); |
| 199 | ||
| 175 | 200 | try writeCapabilities(spv, target); |
| 176 | 201 | try writeMemoryModel(spv, target); |
| 177 | 202 | |
| ... | ... | @@ -183,7 +208,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 183 | 208 | defer error_info.deinit(); |
| 184 | 209 | |
| 185 | 210 | try error_info.appendSlice("zig_errors"); |
| 186 | const module = self.base.options.module.?; | |
| 211 | const module = self.base.comp.module.?; | |
| 187 | 212 | for (module.global_error_set.keys()) |name_nts| { |
| 188 | 213 | const name = module.intern_pool.stringToSlice(name_nts); |
| 189 | 214 | // 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 |
| 191 | 216 | // name if it contains no strange characters is nice for debugging. URI encoding fits the bill. |
| 192 | 217 | // We're using : as separator, which is a reserved character. |
| 193 | 218 | |
| 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); | |
| 196 | 221 | try error_info.writer().print(":{s}", .{escaped_name}); |
| 197 | 222 | } |
| 198 | try spv.sections.debug_strings.emit(spv.gpa, .OpSourceExtension, .{ | |
| 223 | try spv.sections.debug_strings.emit(gpa, .OpSourceExtension, .{ | |
| 199 | 224 | .extension = error_info.items, |
| 200 | 225 | }); |
| 201 | 226 | |
| ... | ... | @@ -203,6 +228,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 203 | 228 | } |
| 204 | 229 | |
| 205 | 230 | fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { |
| 231 | const gpa = spv.gpa; | |
| 206 | 232 | // TODO: Integrate with a hypothetical feature system |
| 207 | 233 | const caps: []const spec.Capability = switch (target.os.tag) { |
| 208 | 234 | .opencl => &.{ .Kernel, .Addresses, .Int8, .Int16, .Int64, .Float64, .Float16, .GenericPointer }, |
| ... | ... | @@ -212,13 +238,15 @@ fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { |
| 212 | 238 | }; |
| 213 | 239 | |
| 214 | 240 | for (caps) |cap| { |
| 215 | try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{ | |
| 241 | try spv.sections.capabilities.emit(gpa, .OpCapability, .{ | |
| 216 | 242 | .capability = cap, |
| 217 | 243 | }); |
| 218 | 244 | } |
| 219 | 245 | } |
| 220 | 246 | |
| 221 | 247 | fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { |
| 248 | const gpa = spv.gpa; | |
| 249 | ||
| 222 | 250 | const addressing_model = switch (target.os.tag) { |
| 223 | 251 | .opencl => switch (target.cpu.arch) { |
| 224 | 252 | .spirv32 => spec.AddressingModel.Physical32, |
| ... | ... | @@ -237,7 +265,7 @@ fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { |
| 237 | 265 | }; |
| 238 | 266 | |
| 239 | 267 | // TODO: Put this in a proper section. |
| 240 | try spv.sections.extensions.emit(spv.gpa, .OpMemoryModel, .{ | |
| 268 | try spv.sections.extensions.emit(gpa, .OpMemoryModel, .{ | |
| 241 | 269 | .addressing_model = addressing_model, |
| 242 | 270 | .memory_model = memory_model, |
| 243 | 271 | }); |
src/link/Wasm.zig+609-460| ... | ... | @@ -37,6 +37,12 @@ pub const Relocation = types.Relocation; |
| 37 | 37 | pub const base_tag: link.File.Tag = .wasm; |
| 38 | 38 | |
| 39 | 39 | base: link.File, |
| 40 | entry_name: ?[]const u8, | |
| 41 | import_symbols: bool, | |
| 42 | export_symbol_names: []const []const u8, | |
| 43 | global_base: ?u64, | |
| 44 | initial_memory: ?u64, | |
| 45 | max_memory: ?u64, | |
| 40 | 46 | /// Output name of the file |
| 41 | 47 | name: []const u8, |
| 42 | 48 | /// 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) = .{}, |
| 191 | 197 | /// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index. |
| 192 | 198 | anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, |
| 193 | 199 | |
| 200 | import_table: bool, | |
| 201 | export_table: bool, | |
| 202 | ||
| 194 | 203 | pub const Alignment = types.Alignment; |
| 195 | 204 | |
| 196 | 205 | pub const Segment = struct { |
| ... | ... | @@ -363,63 +372,126 @@ pub const StringTable = struct { |
| 363 | 372 | } |
| 364 | 373 | }; |
| 365 | 374 | |
| 366 | pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm { | |
| 367 | assert(options.target.ofmt == .wasm); | |
| 375 | pub 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 | } | |
| 368 | 385 | |
| 369 | if (options.use_llvm and options.use_lld) { | |
| 370 | return createEmpty(allocator, options); | |
| 386 | pub 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); | |
| 371 | 446 | } |
| 447 | errdefer wasm.base.destroy(); | |
| 372 | 448 | |
| 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; | |
| 384 | 452 | } |
| 385 | 453 | |
| 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, .{ | |
| 388 | 460 | .truncate = true, |
| 389 | 461 | .read = true, |
| 390 | 462 | .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) | |
| 392 | 464 | fs.File.default_mode | 0b001_000_000 |
| 393 | 465 | else |
| 394 | 466 | fs.File.default_mode |
| 395 | 467 | else |
| 396 | 468 | 0, |
| 397 | 469 | }); |
| 398 | wasm_bin.base.file = file; | |
| 399 | wasm_bin.name = sub_path; | |
| 470 | wasm.base.file = file; | |
| 471 | wasm.name = sub_path; | |
| 400 | 472 | |
| 401 | 473 | // create stack pointer symbol |
| 402 | 474 | { |
| 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); | |
| 405 | 477 | // For object files we will import the stack pointer symbol |
| 406 | if (options.output_mode == .Obj) { | |
| 478 | if (output_mode == .Obj) { | |
| 407 | 479 | 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, | |
| 412 | 484 | loc, |
| 413 | 485 | .{ |
| 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), | |
| 415 | 487 | .name = symbol.name, |
| 416 | 488 | .kind = .{ .global = .{ .valtype = .i32, .mutable = true } }, |
| 417 | 489 | }, |
| 418 | 490 | ); |
| 419 | 491 | } 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); | |
| 421 | 493 | 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); | |
| 423 | 495 | global.* = .{ |
| 424 | 496 | .global_type = .{ |
| 425 | 497 | .valtype = .i32, |
| ... | ... | @@ -432,25 +504,25 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 432 | 504 | |
| 433 | 505 | // create indirect function pointer symbol |
| 434 | 506 | { |
| 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); | |
| 437 | 509 | const table: std.wasm.Table = .{ |
| 438 | 510 | .limits = .{ .flags = 0, .min = 0, .max = undefined }, // will be overwritten during `mapFunctionTable` |
| 439 | 511 | .reftype = .funcref, |
| 440 | 512 | }; |
| 441 | if (options.output_mode == .Obj or options.import_table) { | |
| 513 | if (output_mode == .Obj or options.import_table) { | |
| 442 | 514 | 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), | |
| 447 | 519 | .name = symbol.name, |
| 448 | 520 | .kind = .{ .table = table }, |
| 449 | 521 | }); |
| 450 | 522 | } 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) { | |
| 454 | 526 | symbol.setFlag(.WASM_SYM_EXPORTED); |
| 455 | 527 | } else { |
| 456 | 528 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| ... | ... | @@ -460,8 +532,8 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 460 | 532 | |
| 461 | 533 | // create __wasm_call_ctors |
| 462 | 534 | { |
| 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); | |
| 465 | 537 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 466 | 538 | // we do not know the function index until after we merged all sections. |
| 467 | 539 | // 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 |
| 469 | 541 | } |
| 470 | 542 | |
| 471 | 543 | // shared-memory symbols for TLS support |
| 472 | if (wasm_bin.base.options.shared_memory) { | |
| 544 | if (shared_memory) { | |
| 473 | 545 | { |
| 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); | |
| 476 | 548 | 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, .{ | |
| 479 | 551 | .global_type = .{ .valtype = .i32, .mutable = true }, |
| 480 | 552 | .init = .{ .i32_const = undefined }, |
| 481 | 553 | }); |
| 482 | 554 | } |
| 483 | 555 | { |
| 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); | |
| 486 | 558 | 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, .{ | |
| 489 | 561 | .global_type = .{ .valtype = .i32, .mutable = false }, |
| 490 | 562 | .init = .{ .i32_const = undefined }, |
| 491 | 563 | }); |
| 492 | 564 | } |
| 493 | 565 | { |
| 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); | |
| 496 | 568 | 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, .{ | |
| 499 | 571 | .global_type = .{ .valtype = .i32, .mutable = false }, |
| 500 | 572 | .init = .{ .i32_const = undefined }, |
| 501 | 573 | }); |
| 502 | 574 | } |
| 503 | 575 | { |
| 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); | |
| 506 | 578 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 507 | 579 | } |
| 508 | 580 | } |
| 509 | 581 | |
| 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 | ||
| 518 | pub 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 | } | |
| 534 | 582 | return wasm; |
| 535 | 583 | } |
| 536 | 584 | |
| 537 | 585 | /// For a given name, creates a new global synthetic symbol. |
| 538 | 586 | /// Leaves index undefined and the default flags (0). |
| 539 | 587 | fn 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); | |
| 541 | 590 | return wasm.createSyntheticSymbolOffset(name_offset, tag); |
| 542 | 591 | } |
| 543 | 592 | |
| 544 | 593 | fn createSyntheticSymbolOffset(wasm: *Wasm, name_offset: u32, tag: Symbol.Tag) !SymbolLoc { |
| 545 | 594 | const sym_index = @as(u32, @intCast(wasm.symbols.items.len)); |
| 546 | 595 | 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, .{ | |
| 548 | 598 | .name = name_offset, |
| 549 | 599 | .flags = 0, |
| 550 | 600 | .tag = tag, |
| 551 | 601 | .index = undefined, |
| 552 | 602 | .virtual_address = undefined, |
| 553 | 603 | }); |
| 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); | |
| 556 | 606 | return loc; |
| 557 | 607 | } |
| 558 | 608 | |
| ... | ... | @@ -589,12 +639,13 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool { |
| 589 | 639 | const file = try fs.cwd().openFile(path, .{}); |
| 590 | 640 | errdefer file.close(); |
| 591 | 641 | |
| 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) { | |
| 593 | 644 | error.InvalidMagicByte, error.NotObjectFile => return false, |
| 594 | 645 | else => |e| return e, |
| 595 | 646 | }; |
| 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); | |
| 598 | 649 | return true; |
| 599 | 650 | } |
| 600 | 651 | |
| ... | ... | @@ -602,27 +653,29 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool { |
| 602 | 653 | /// When the index was not found, a new `Atom` will be created, and its index will be returned. |
| 603 | 654 | /// The newly created Atom is empty with default fields as specified by `Atom.empty`. |
| 604 | 655 | pub 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); | |
| 606 | 658 | if (!gop.found_existing) { |
| 607 | 659 | const atom_index = try wasm.createAtom(); |
| 608 | 660 | gop.value_ptr.* = atom_index; |
| 609 | 661 | const atom = wasm.getAtom(atom_index); |
| 610 | 662 | const symbol = atom.symbolLoc().getSymbol(wasm); |
| 611 | const mod = wasm.base.options.module.?; | |
| 663 | const mod = wasm.base.comp.module.?; | |
| 612 | 664 | const decl = mod.declPtr(decl_index); |
| 613 | 665 | 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); | |
| 615 | 667 | } |
| 616 | 668 | return gop.value_ptr.*; |
| 617 | 669 | } |
| 618 | 670 | |
| 619 | 671 | /// Creates a new empty `Atom` and returns its `Atom.Index` |
| 620 | 672 | fn 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); | |
| 623 | 676 | atom.* = Atom.empty; |
| 624 | 677 | 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); | |
| 626 | 679 | |
| 627 | 680 | return index; |
| 628 | 681 | } |
| ... | ... | @@ -644,6 +697,8 @@ pub inline fn getAtomPtr(wasm: *Wasm, index: Atom.Index) *Atom { |
| 644 | 697 | /// When false, it will only link with object files that contain symbols that |
| 645 | 698 | /// are referenced by other object files or Zig code. |
| 646 | 699 | fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool { |
| 700 | const gpa = wasm.base.comp.gpa; | |
| 701 | ||
| 647 | 702 | const file = try fs.cwd().openFile(path, .{}); |
| 648 | 703 | errdefer file.close(); |
| 649 | 704 | |
| ... | ... | @@ -651,25 +706,25 @@ fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool { |
| 651 | 706 | .file = file, |
| 652 | 707 | .name = path, |
| 653 | 708 | }; |
| 654 | archive.parse(wasm.base.allocator) catch |err| switch (err) { | |
| 709 | archive.parse(gpa) catch |err| switch (err) { | |
| 655 | 710 | error.EndOfStream, error.NotArchive => { |
| 656 | archive.deinit(wasm.base.allocator); | |
| 711 | archive.deinit(gpa); | |
| 657 | 712 | return false; |
| 658 | 713 | }, |
| 659 | 714 | else => |e| return e, |
| 660 | 715 | }; |
| 661 | 716 | |
| 662 | 717 | 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); | |
| 665 | 720 | return true; |
| 666 | 721 | } |
| 667 | defer archive.deinit(wasm.base.allocator); | |
| 722 | defer archive.deinit(gpa); | |
| 668 | 723 | |
| 669 | 724 | // In this case we must force link all embedded object files within the archive |
| 670 | 725 | // We loop over all symbols, and then group them by offset as the offset |
| 671 | 726 | // 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); | |
| 673 | 728 | defer offsets.deinit(); |
| 674 | 729 | for (archive.toc.values()) |symbol_offsets| { |
| 675 | 730 | for (symbol_offsets.items) |sym_offset| { |
| ... | ... | @@ -678,8 +733,8 @@ fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool { |
| 678 | 733 | } |
| 679 | 734 | |
| 680 | 735 | 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); | |
| 683 | 738 | } |
| 684 | 739 | |
| 685 | 740 | return true; |
| ... | ... | @@ -695,6 +750,7 @@ fn requiresTLSReloc(wasm: *const Wasm) bool { |
| 695 | 750 | } |
| 696 | 751 | |
| 697 | 752 | fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 753 | const gpa = wasm.base.comp.gpa; | |
| 698 | 754 | const object: Object = wasm.objects.items[object_index]; |
| 699 | 755 | log.debug("Resolving symbols in object: '{s}'", .{object.name}); |
| 700 | 756 | |
| ... | ... | @@ -708,7 +764,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 708 | 764 | if (mem.eql(u8, sym_name, "__indirect_function_table")) { |
| 709 | 765 | continue; |
| 710 | 766 | } |
| 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); | |
| 712 | 768 | |
| 713 | 769 | if (symbol.isLocal()) { |
| 714 | 770 | if (symbol.isUndefined()) { |
| ... | ... | @@ -716,17 +772,17 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 716 | 772 | log.err(" symbol '{s}' defined in '{s}'", .{ sym_name, object.name }); |
| 717 | 773 | return error.UndefinedLocal; |
| 718 | 774 | } |
| 719 | try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, location, {}); | |
| 775 | try wasm.resolved_symbols.putNoClobber(gpa, location, {}); | |
| 720 | 776 | continue; |
| 721 | 777 | } |
| 722 | 778 | |
| 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); | |
| 724 | 780 | if (!maybe_existing.found_existing) { |
| 725 | 781 | maybe_existing.value_ptr.* = location; |
| 726 | try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, location, {}); | |
| 782 | try wasm.resolved_symbols.putNoClobber(gpa, location, {}); | |
| 727 | 783 | |
| 728 | 784 | 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); | |
| 730 | 786 | } |
| 731 | 787 | continue; |
| 732 | 788 | } |
| ... | ... | @@ -753,7 +809,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 753 | 809 | return error.SymbolCollision; |
| 754 | 810 | } |
| 755 | 811 | |
| 756 | try wasm.discarded.put(wasm.base.allocator, location, existing_loc); | |
| 812 | try wasm.discarded.put(gpa, location, existing_loc); | |
| 757 | 813 | continue; // Do not overwrite defined symbols with undefined symbols |
| 758 | 814 | } |
| 759 | 815 | |
| ... | ... | @@ -791,7 +847,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 791 | 847 | } |
| 792 | 848 | |
| 793 | 849 | // 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); | |
| 795 | 851 | continue; |
| 796 | 852 | } |
| 797 | 853 | |
| ... | ... | @@ -822,7 +878,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 822 | 878 | // symbol is weak and the new one isn't, in which case we *do* overwrite it. |
| 823 | 879 | if (existing_sym.isWeak() and symbol.isWeak()) blk: { |
| 824 | 880 | 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); | |
| 826 | 882 | continue; |
| 827 | 883 | } |
| 828 | 884 | |
| ... | ... | @@ -830,10 +886,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 830 | 886 | log.debug("Overwriting symbol '{s}'", .{sym_name}); |
| 831 | 887 | log.debug(" old definition in '{s}'", .{existing_file_path}); |
| 832 | 888 | 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); | |
| 834 | 890 | 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, {}); | |
| 837 | 893 | assert(wasm.resolved_symbols.swapRemove(existing_loc)); |
| 838 | 894 | if (existing_sym.isUndefined()) { |
| 839 | 895 | _ = wasm.undefs.swapRemove(sym_name_index); |
| ... | ... | @@ -842,6 +898,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void { |
| 842 | 898 | } |
| 843 | 899 | |
| 844 | 900 | fn resolveSymbolsInArchives(wasm: *Wasm) !void { |
| 901 | const gpa = wasm.base.comp.gpa; | |
| 845 | 902 | if (wasm.archives.items.len == 0) return; |
| 846 | 903 | |
| 847 | 904 | log.debug("Resolving symbols in archives", .{}); |
| ... | ... | @@ -860,9 +917,9 @@ fn resolveSymbolsInArchives(wasm: *Wasm) !void { |
| 860 | 917 | // Symbol is found in unparsed object file within current archive. |
| 861 | 918 | // Parse object and and resolve symbols again before we check remaining |
| 862 | 919 | // 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); | |
| 866 | 923 | try wasm.resolveSymbolsInObject(object_file_index); |
| 867 | 924 | |
| 868 | 925 | // continue loop for any remaining undefined symbols that still exist |
| ... | ... | @@ -880,6 +937,11 @@ fn writeI32Const(writer: anytype, val: u32) !void { |
| 880 | 937 | } |
| 881 | 938 | |
| 882 | 939 | fn 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 | ||
| 883 | 945 | // Passive segments are used to avoid memory being reinitialized on each |
| 884 | 946 | // thread's instantiation. These passive segments are initialized and |
| 885 | 947 | // dropped in __wasm_init_memory, which is registered as the start function |
| ... | ... | @@ -889,21 +951,21 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 889 | 951 | return; |
| 890 | 952 | } |
| 891 | 953 | |
| 892 | const flag_address: u32 = if (wasm.base.options.shared_memory) address: { | |
| 954 | const flag_address: u32 = if (shared_memory) address: { | |
| 893 | 955 | // when we have passive initialization segments and shared memory |
| 894 | 956 | // `setupMemory` will create this symbol and set its virtual address. |
| 895 | 957 | const loc = wasm.findGlobalSymbol("__wasm_init_memory_flag").?; |
| 896 | 958 | break :address loc.getSymbol(wasm).virtual_address; |
| 897 | 959 | } else 0; |
| 898 | 960 | |
| 899 | var function_body = std.ArrayList(u8).init(wasm.base.allocator); | |
| 961 | var function_body = std.ArrayList(u8).init(gpa); | |
| 900 | 962 | defer function_body.deinit(); |
| 901 | 963 | const writer = function_body.writer(); |
| 902 | 964 | |
| 903 | 965 | // we have 0 locals |
| 904 | 966 | try leb.writeULEB128(writer, @as(u32, 0)); |
| 905 | 967 | |
| 906 | if (wasm.base.options.shared_memory) { | |
| 968 | if (shared_memory) { | |
| 907 | 969 | // destination blocks |
| 908 | 970 | // based on values we jump to corresponding label |
| 909 | 971 | try writer.writeByte(std.wasm.opcode(.block)); // $drop |
| ... | ... | @@ -937,14 +999,14 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 937 | 999 | var segment_index: u32 = 0; |
| 938 | 1000 | while (it.next()) |entry| : (segment_index += 1) { |
| 939 | 1001 | 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.*)) { | |
| 941 | 1003 | // For passive BSS segments we can simple issue a memory.fill(0). |
| 942 | 1004 | // For non-BSS segments we do a memory.init. Both these |
| 943 | 1005 | // instructions take as their first argument the destination |
| 944 | 1006 | // address. |
| 945 | 1007 | try writeI32Const(writer, segment.offset); |
| 946 | 1008 | |
| 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")) { | |
| 948 | 1010 | // When we initialize the TLS segment we also set the `__tls_base` |
| 949 | 1011 | // global. This allows the runtime to use this static copy of the |
| 950 | 1012 | // TLS data for the first/main thread. |
| ... | ... | @@ -969,7 +1031,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 969 | 1031 | } |
| 970 | 1032 | } |
| 971 | 1033 | |
| 972 | if (wasm.base.options.shared_memory) { | |
| 1034 | if (shared_memory) { | |
| 973 | 1035 | // we set the init memory flag to value '2' |
| 974 | 1036 | try writeI32Const(writer, flag_address); |
| 975 | 1037 | try writeI32Const(writer, 2); |
| ... | ... | @@ -1012,12 +1074,12 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 1012 | 1074 | while (it.next()) |entry| : (segment_index += 1) { |
| 1013 | 1075 | const name = entry.key_ptr.*; |
| 1014 | 1076 | 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 | |
| 1016 | 1078 | !std.mem.eql(u8, name, ".bss")) |
| 1017 | 1079 | { |
| 1018 | 1080 | // The TLS region should not be dropped since its is needed |
| 1019 | 1081 | // 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")) { | |
| 1021 | 1083 | continue; |
| 1022 | 1084 | } |
| 1023 | 1085 | |
| ... | ... | @@ -1040,14 +1102,18 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void { |
| 1040 | 1102 | /// Constructs a synthetic function that performs runtime relocations for |
| 1041 | 1103 | /// TLS symbols. This function is called by `__wasm_init_tls`. |
| 1042 | 1104 | fn setupTLSRelocationsFunction(wasm: *Wasm) !void { |
| 1105 | const comp = wasm.base.comp; | |
| 1106 | const gpa = comp.gpa; | |
| 1107 | const shared_memory = comp.config.shared_memory; | |
| 1108 | ||
| 1043 | 1109 | // When we have TLS GOT entries and shared memory is enabled, |
| 1044 | 1110 | // 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()) { | |
| 1046 | 1112 | return; |
| 1047 | 1113 | } |
| 1048 | 1114 | |
| 1049 | 1115 | // 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); | |
| 1051 | 1117 | defer function_body.deinit(); |
| 1052 | 1118 | const writer = function_body.writer(); |
| 1053 | 1119 | |
| ... | ... | @@ -1086,7 +1152,10 @@ fn validateFeatures( |
| 1086 | 1152 | to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool, |
| 1087 | 1153 | emit_features_count: *u32, |
| 1088 | 1154 | ) !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; | |
| 1090 | 1159 | const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects. |
| 1091 | 1160 | const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len; |
| 1092 | 1161 | |
| ... | ... | @@ -1156,7 +1225,7 @@ fn validateFeatures( |
| 1156 | 1225 | return error.InvalidFeatureSet; |
| 1157 | 1226 | } |
| 1158 | 1227 | |
| 1159 | if (wasm.base.options.shared_memory) { | |
| 1228 | if (shared_memory) { | |
| 1160 | 1229 | const disallowed_feature = disallowed[@intFromEnum(types.Feature.Tag.shared_mem)]; |
| 1161 | 1230 | if (@as(u1, @truncate(disallowed_feature)) != 0) { |
| 1162 | 1231 | log.err( |
| ... | ... | @@ -1221,10 +1290,14 @@ fn validateFeatures( |
| 1221 | 1290 | /// if one or multiple undefined references exist. When none exist, the symbol will |
| 1222 | 1291 | /// not be created, ensuring we don't unneccesarily emit unreferenced symbols. |
| 1223 | 1292 | fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1293 | const comp = wasm.base.comp; | |
| 1294 | const gpa = comp.gpa; | |
| 1295 | const shared_memory = comp.config.shared_memory; | |
| 1296 | ||
| 1224 | 1297 | if (wasm.string_table.getOffset("__heap_base")) |name_offset| { |
| 1225 | 1298 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| 1226 | 1299 | 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); | |
| 1228 | 1301 | _ = wasm.resolved_symbols.swapRemove(loc); // we don't want to emit this symbol, only use it for relocations. |
| 1229 | 1302 | } |
| 1230 | 1303 | } |
| ... | ... | @@ -1232,21 +1305,21 @@ fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1232 | 1305 | if (wasm.string_table.getOffset("__heap_end")) |name_offset| { |
| 1233 | 1306 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| 1234 | 1307 | 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); | |
| 1236 | 1309 | _ = wasm.resolved_symbols.swapRemove(loc); |
| 1237 | 1310 | } |
| 1238 | 1311 | } |
| 1239 | 1312 | |
| 1240 | if (!wasm.base.options.shared_memory) { | |
| 1313 | if (!shared_memory) { | |
| 1241 | 1314 | if (wasm.string_table.getOffset("__tls_base")) |name_offset| { |
| 1242 | 1315 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| 1243 | 1316 | 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); | |
| 1245 | 1318 | _ = wasm.resolved_symbols.swapRemove(kv.value); |
| 1246 | 1319 | const symbol = loc.getSymbol(wasm); |
| 1247 | 1320 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 1248 | 1321 | 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, .{ | |
| 1250 | 1323 | .global_type = .{ .valtype = .i32, .mutable = true }, |
| 1251 | 1324 | .init = .{ .i32_const = undefined }, |
| 1252 | 1325 | }); |
| ... | ... | @@ -1256,7 +1329,7 @@ fn resolveLazySymbols(wasm: *Wasm) !void { |
| 1256 | 1329 | if (wasm.string_table.getOffset("__zig_errors_len")) |name_offset| { |
| 1257 | 1330 | if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| { |
| 1258 | 1331 | 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); | |
| 1260 | 1333 | _ = wasm.resolved_symbols.swapRemove(kv.value); |
| 1261 | 1334 | } |
| 1262 | 1335 | } |
| ... | ... | @@ -1270,8 +1343,9 @@ pub fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc { |
| 1270 | 1343 | } |
| 1271 | 1344 | |
| 1272 | 1345 | fn 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; | |
| 1275 | 1349 | |
| 1276 | 1350 | var found_undefined_symbols = false; |
| 1277 | 1351 | for (wasm.undefs.values()) |undef| { |
| ... | ... | @@ -1292,8 +1366,8 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void { |
| 1292 | 1366 | } |
| 1293 | 1367 | |
| 1294 | 1368 | pub 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(); | |
| 1297 | 1371 | |
| 1298 | 1372 | for (wasm.func_types.items) |*func_type| { |
| 1299 | 1373 | func_type.deinit(gpa); |
| ... | ... | @@ -1378,7 +1452,9 @@ pub fn deinit(wasm: *Wasm) void { |
| 1378 | 1452 | /// Allocates a new symbol and returns its index. |
| 1379 | 1453 | /// Will re-use slots when a symbol was freed at an earlier stage. |
| 1380 | 1454 | pub 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); | |
| 1382 | 1458 | const symbol: Symbol = .{ |
| 1383 | 1459 | .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls |
| 1384 | 1460 | .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL), |
| ... | ... | @@ -1404,6 +1480,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: |
| 1404 | 1480 | const tracy = trace(@src()); |
| 1405 | 1481 | defer tracy.end(); |
| 1406 | 1482 | |
| 1483 | const gpa = wasm.base.comp.gpa; | |
| 1407 | 1484 | const func = mod.funcInfo(func_index); |
| 1408 | 1485 | const decl_index = func.owner_decl; |
| 1409 | 1486 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -1414,7 +1491,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: |
| 1414 | 1491 | // var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null; |
| 1415 | 1492 | // defer if (decl_state) |*ds| ds.deinit(); |
| 1416 | 1493 | |
| 1417 | var code_writer = std.ArrayList(u8).init(wasm.base.allocator); | |
| 1494 | var code_writer = std.ArrayList(u8).init(gpa); | |
| 1418 | 1495 | defer code_writer.deinit(); |
| 1419 | 1496 | // const result = try codegen.generateFunction( |
| 1420 | 1497 | // &wasm.base, |
| ... | ... | @@ -1477,6 +1554,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) ! |
| 1477 | 1554 | return; |
| 1478 | 1555 | } |
| 1479 | 1556 | |
| 1557 | const gpa = wasm.base.comp.gpa; | |
| 1480 | 1558 | const atom_index = try wasm.getOrCreateAtomForDecl(decl_index); |
| 1481 | 1559 | const atom = wasm.getAtomPtr(atom_index); |
| 1482 | 1560 | atom.clear(); |
| ... | ... | @@ -1489,7 +1567,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) ! |
| 1489 | 1567 | } |
| 1490 | 1568 | const val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 1491 | 1569 | |
| 1492 | var code_writer = std.ArrayList(u8).init(wasm.base.allocator); | |
| 1570 | var code_writer = std.ArrayList(u8).init(gpa); | |
| 1493 | 1571 | defer code_writer.deinit(); |
| 1494 | 1572 | |
| 1495 | 1573 | const res = try codegen.generateSymbol( |
| ... | ... | @@ -1528,16 +1606,17 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.De |
| 1528 | 1606 | } |
| 1529 | 1607 | |
| 1530 | 1608 | fn 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.?; | |
| 1532 | 1611 | const decl = mod.declPtr(decl_index); |
| 1533 | 1612 | const atom_index = wasm.decls.get(decl_index).?; |
| 1534 | 1613 | const atom = wasm.getAtomPtr(atom_index); |
| 1535 | 1614 | const symbol = &wasm.symbols.items[atom.sym_index]; |
| 1536 | 1615 | 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); | |
| 1538 | 1617 | 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(), {}); | |
| 1541 | 1620 | |
| 1542 | 1621 | atom.size = @intCast(code.len); |
| 1543 | 1622 | if (code.len == 0) return; |
| ... | ... | @@ -1591,7 +1670,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type { |
| 1591 | 1670 | /// Returns the symbol index of the local |
| 1592 | 1671 | /// The given `decl` is the parent decl whom owns the constant. |
| 1593 | 1672 | pub 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.?; | |
| 1595 | 1675 | assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions |
| 1596 | 1676 | const decl = mod.declPtr(decl_index); |
| 1597 | 1677 | |
| ... | ... | @@ -1599,14 +1679,14 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec |
| 1599 | 1679 | const parent_atom = wasm.getAtom(parent_atom_index); |
| 1600 | 1680 | const local_index = parent_atom.locals.items.len; |
| 1601 | 1681 | 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}", .{ | |
| 1603 | 1683 | fqn, local_index, |
| 1604 | 1684 | }); |
| 1605 | defer wasm.base.allocator.free(name); | |
| 1685 | defer gpa.free(name); | |
| 1606 | 1686 | |
| 1607 | 1687 | switch (try wasm.lowerConst(name, tv, decl.srcLoc(mod))) { |
| 1608 | 1688 | .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); | |
| 1610 | 1690 | return wasm.getAtom(atom_index).getSymbolIndex().?; |
| 1611 | 1691 | }, |
| 1612 | 1692 | .fail => |em| { |
| ... | ... | @@ -1623,24 +1703,25 @@ const LowerConstResult = union(enum) { |
| 1623 | 1703 | }; |
| 1624 | 1704 | |
| 1625 | 1705 | fn 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.?; | |
| 1627 | 1708 | |
| 1628 | 1709 | // Create and initialize a new local symbol and atom |
| 1629 | 1710 | 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); | |
| 1631 | 1712 | defer value_bytes.deinit(); |
| 1632 | 1713 | |
| 1633 | 1714 | const code = code: { |
| 1634 | 1715 | const atom = wasm.getAtomPtr(atom_index); |
| 1635 | 1716 | atom.alignment = tv.ty.abiAlignment(mod); |
| 1636 | 1717 | 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), | |
| 1638 | 1719 | .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL), |
| 1639 | 1720 | .tag = .data, |
| 1640 | 1721 | .index = undefined, |
| 1641 | 1722 | .virtual_address = undefined, |
| 1642 | 1723 | }; |
| 1643 | try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {}); | |
| 1724 | try wasm.resolved_symbols.putNoClobber(gpa, atom.symbolLoc(), {}); | |
| 1644 | 1725 | |
| 1645 | 1726 | const result = try codegen.generateSymbol( |
| 1646 | 1727 | &wasm.base, |
| ... | ... | @@ -1663,7 +1744,7 @@ fn lowerConst(wasm: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.Src |
| 1663 | 1744 | |
| 1664 | 1745 | const atom = wasm.getAtomPtr(atom_index); |
| 1665 | 1746 | atom.size = @intCast(code.len); |
| 1666 | try atom.code.appendSlice(wasm.base.allocator, code); | |
| 1747 | try atom.code.appendSlice(gpa, code); | |
| 1667 | 1748 | return .{ .ok = atom_index }; |
| 1668 | 1749 | } |
| 1669 | 1750 | |
| ... | ... | @@ -1673,8 +1754,9 @@ fn lowerConst(wasm: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.Src |
| 1673 | 1754 | /// and then returns the index to it. |
| 1674 | 1755 | pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 { |
| 1675 | 1756 | _ = 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); | |
| 1678 | 1760 | if (gop.found_existing) { |
| 1679 | 1761 | return gop.value_ptr.*.index; |
| 1680 | 1762 | } |
| ... | ... | @@ -1691,14 +1773,14 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u3 |
| 1691 | 1773 | |
| 1692 | 1774 | const sym_index = if (wasm.symbols_free_list.popOrNull()) |index| index else blk: { |
| 1693 | 1775 | const index: u32 = @intCast(wasm.symbols.items.len); |
| 1694 | try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1); | |
| 1776 | try wasm.symbols.ensureUnusedCapacity(gpa, 1); | |
| 1695 | 1777 | wasm.symbols.items.len += 1; |
| 1696 | 1778 | break :blk index; |
| 1697 | 1779 | }; |
| 1698 | 1780 | wasm.symbols.items[sym_index] = symbol; |
| 1699 | 1781 | 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.*); | |
| 1702 | 1784 | return sym_index; |
| 1703 | 1785 | } |
| 1704 | 1786 | |
| ... | ... | @@ -1709,7 +1791,9 @@ pub fn getDeclVAddr( |
| 1709 | 1791 | decl_index: InternPool.DeclIndex, |
| 1710 | 1792 | reloc_info: link.File.RelocInfo, |
| 1711 | 1793 | ) !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.?; | |
| 1713 | 1797 | const decl = mod.declPtr(decl_index); |
| 1714 | 1798 | |
| 1715 | 1799 | const target_atom_index = try wasm.getOrCreateAtomForDecl(decl_index); |
| ... | ... | @@ -1718,24 +1802,24 @@ pub fn getDeclVAddr( |
| 1718 | 1802 | assert(reloc_info.parent_atom_index != 0); |
| 1719 | 1803 | const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; |
| 1720 | 1804 | 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; | |
| 1722 | 1806 | if (decl.ty.zigTypeTag(mod) == .Fn) { |
| 1723 | 1807 | assert(reloc_info.addend == 0); // addend not allowed for function relocations |
| 1724 | 1808 | // We found a function pointer, so add it to our table, |
| 1725 | 1809 | // as function pointers are not allowed to be stored inside the data section. |
| 1726 | 1810 | // They are instead stored in a function table which are called by index. |
| 1727 | 1811 | try wasm.addTableFunction(target_symbol_index); |
| 1728 | try atom.relocs.append(wasm.base.allocator, .{ | |
| 1812 | try atom.relocs.append(gpa, .{ | |
| 1729 | 1813 | .index = target_symbol_index, |
| 1730 | .offset = @as(u32, @intCast(reloc_info.offset)), | |
| 1814 | .offset = @intCast(reloc_info.offset), | |
| 1731 | 1815 | .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64, |
| 1732 | 1816 | }); |
| 1733 | 1817 | } else { |
| 1734 | try atom.relocs.append(wasm.base.allocator, .{ | |
| 1818 | try atom.relocs.append(gpa, .{ | |
| 1735 | 1819 | .index = target_symbol_index, |
| 1736 | .offset = @as(u32, @intCast(reloc_info.offset)), | |
| 1820 | .offset = @intCast(reloc_info.offset), | |
| 1737 | 1821 | .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), | |
| 1739 | 1823 | }); |
| 1740 | 1824 | } |
| 1741 | 1825 | // we do not know the final address at this point, |
| ... | ... | @@ -1751,9 +1835,10 @@ pub fn lowerAnonDecl( |
| 1751 | 1835 | explicit_alignment: Alignment, |
| 1752 | 1836 | src_loc: Module.SrcLoc, |
| 1753 | 1837 | ) !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); | |
| 1755 | 1840 | if (!gop.found_existing) { |
| 1756 | const mod = wasm.base.options.module.?; | |
| 1841 | const mod = wasm.base.comp.module.?; | |
| 1757 | 1842 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1758 | 1843 | const tv: TypedValue = .{ .ty = ty, .val = Value.fromInterned(decl_val) }; |
| 1759 | 1844 | var name_buf: [32]u8 = undefined; |
| ... | ... | @@ -1779,13 +1864,15 @@ pub fn lowerAnonDecl( |
| 1779 | 1864 | } |
| 1780 | 1865 | |
| 1781 | 1866 | pub 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; | |
| 1782 | 1869 | const atom_index = wasm.anon_decls.get(decl_val).?; |
| 1783 | 1870 | const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?; |
| 1784 | 1871 | |
| 1785 | 1872 | const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; |
| 1786 | 1873 | 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.?; | |
| 1789 | 1876 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1790 | 1877 | if (ty.zigTypeTag(mod) == .Fn) { |
| 1791 | 1878 | 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 |
| 1793 | 1880 | // as function pointers are not allowed to be stored inside the data section. |
| 1794 | 1881 | // They are instead stored in a function table which are called by index. |
| 1795 | 1882 | try wasm.addTableFunction(target_symbol_index); |
| 1796 | try parent_atom.relocs.append(wasm.base.allocator, .{ | |
| 1883 | try parent_atom.relocs.append(gpa, .{ | |
| 1797 | 1884 | .index = target_symbol_index, |
| 1798 | .offset = @as(u32, @intCast(reloc_info.offset)), | |
| 1885 | .offset = @intCast(reloc_info.offset), | |
| 1799 | 1886 | .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64, |
| 1800 | 1887 | }); |
| 1801 | 1888 | } else { |
| 1802 | try parent_atom.relocs.append(wasm.base.allocator, .{ | |
| 1889 | try parent_atom.relocs.append(gpa, .{ | |
| 1803 | 1890 | .index = target_symbol_index, |
| 1804 | .offset = @as(u32, @intCast(reloc_info.offset)), | |
| 1891 | .offset = @intCast(reloc_info.offset), | |
| 1805 | 1892 | .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), | |
| 1807 | 1894 | }); |
| 1808 | 1895 | } |
| 1809 | 1896 | |
| ... | ... | @@ -1814,7 +1901,12 @@ pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: lin |
| 1814 | 1901 | return target_symbol_index; |
| 1815 | 1902 | } |
| 1816 | 1903 | |
| 1817 | pub fn deleteDeclExport(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { | |
| 1904 | pub fn deleteDeclExport( | |
| 1905 | wasm: *Wasm, | |
| 1906 | decl_index: InternPool.DeclIndex, | |
| 1907 | name: InternPool.NullTerminatedString, | |
| 1908 | ) void { | |
| 1909 | _ = name; | |
| 1818 | 1910 | if (wasm.llvm_object) |_| return; |
| 1819 | 1911 | const atom_index = wasm.decls.get(decl_index) orelse return; |
| 1820 | 1912 | const sym_index = wasm.getAtom(atom_index).sym_index; |
| ... | ... | @@ -1840,8 +1932,6 @@ pub fn updateExports( |
| 1840 | 1932 | } |
| 1841 | 1933 | if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports); |
| 1842 | 1934 | |
| 1843 | if (wasm.base.options.emit == null) return; | |
| 1844 | ||
| 1845 | 1935 | const decl_index = switch (exported) { |
| 1846 | 1936 | .decl_index => |i| i, |
| 1847 | 1937 | .value => |val| { |
| ... | ... | @@ -1880,7 +1970,7 @@ pub fn updateExports( |
| 1880 | 1970 | }; |
| 1881 | 1971 | const exported_atom_index = try wasm.getOrCreateAtomForDecl(exported_decl_index); |
| 1882 | 1972 | 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)); | |
| 1884 | 1974 | const sym_loc = exported_atom.symbolLoc(); |
| 1885 | 1975 | const symbol = sym_loc.getSymbol(wasm); |
| 1886 | 1976 | symbol.setGlobal(true); |
| ... | ... | @@ -1915,7 +2005,7 @@ pub fn updateExports( |
| 1915 | 2005 | |
| 1916 | 2006 | if (!existing_sym.isUndefined()) blk: { |
| 1917 | 2007 | 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); | |
| 1919 | 2009 | continue; // to-be-exported symbol is weak, so we keep the existing symbol |
| 1920 | 2010 | } |
| 1921 | 2011 | |
| ... | ... | @@ -1939,18 +2029,18 @@ pub fn updateExports( |
| 1939 | 2029 | } |
| 1940 | 2030 | |
| 1941 | 2031 | // 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); | |
| 1943 | 2033 | _ = wasm.imports.remove(existing_loc); |
| 1944 | 2034 | _ = wasm.undefs.swapRemove(existing_sym.name); |
| 1945 | 2035 | } |
| 1946 | 2036 | |
| 1947 | 2037 | // Ensure the symbol will be exported using the given name |
| 1948 | 2038 | 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); | |
| 1950 | 2040 | } |
| 1951 | 2041 | |
| 1952 | 2042 | try wasm.globals.put( |
| 1953 | wasm.base.allocator, | |
| 2043 | gpa, | |
| 1954 | 2044 | export_name, |
| 1955 | 2045 | sym_loc, |
| 1956 | 2046 | ); |
| ... | ... | @@ -1959,18 +2049,19 @@ pub fn updateExports( |
| 1959 | 2049 | |
| 1960 | 2050 | pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { |
| 1961 | 2051 | 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.?; | |
| 1963 | 2054 | const decl = mod.declPtr(decl_index); |
| 1964 | 2055 | const atom_index = wasm.decls.get(decl_index).?; |
| 1965 | 2056 | 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 {}; | |
| 1967 | 2058 | _ = wasm.decls.remove(decl_index); |
| 1968 | 2059 | wasm.symbols.items[atom.sym_index].tag = .dead; |
| 1969 | 2060 | for (atom.locals.items) |local_atom_index| { |
| 1970 | 2061 | const local_atom = wasm.getAtom(local_atom_index); |
| 1971 | 2062 | const local_symbol = &wasm.symbols.items[local_atom.sym_index]; |
| 1972 | 2063 | 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 {}; | |
| 1974 | 2065 | assert(wasm.resolved_symbols.swapRemove(local_atom.symbolLoc())); |
| 1975 | 2066 | assert(wasm.symbol_atom.remove(local_atom.symbolLoc())); |
| 1976 | 2067 | } |
| ... | ... | @@ -1999,8 +2090,9 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { |
| 1999 | 2090 | |
| 2000 | 2091 | /// Appends a new entry to the indirect function table |
| 2001 | 2092 | pub 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); | |
| 2004 | 2096 | } |
| 2005 | 2097 | |
| 2006 | 2098 | /// Assigns indexes to all indirect functions. |
| ... | ... | @@ -2019,7 +2111,7 @@ fn mapFunctionTable(wasm: *Wasm) void { |
| 2019 | 2111 | } |
| 2020 | 2112 | } |
| 2021 | 2113 | |
| 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) { | |
| 2023 | 2115 | const sym_loc = wasm.findGlobalSymbol("__indirect_function_table").?; |
| 2024 | 2116 | const import = wasm.imports.getPtr(sym_loc).?; |
| 2025 | 2117 | import.kind.table.limits.min = index - 1; // we start at index 1. |
| ... | ... | @@ -2048,6 +2140,7 @@ pub fn addOrUpdateImport( |
| 2048 | 2140 | /// is asserted instead. |
| 2049 | 2141 | type_index: ?u32, |
| 2050 | 2142 | ) !void { |
| 2143 | const gpa = wasm.base.comp.gpa; | |
| 2051 | 2144 | assert(symbol_index != 0); |
| 2052 | 2145 | // For the import name, we use the decl's name, rather than the fully qualified name |
| 2053 | 2146 | // 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( |
| 2055 | 2148 | const mangle_name = lib_name != null and |
| 2056 | 2149 | !std.mem.eql(u8, lib_name.?, "c"); |
| 2057 | 2150 | 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.? }); | |
| 2059 | 2152 | } else name; |
| 2060 | defer if (mangle_name) wasm.base.allocator.free(full_name); | |
| 2153 | defer if (mangle_name) gpa.free(full_name); | |
| 2061 | 2154 | |
| 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); | |
| 2063 | 2156 | const symbol: *Symbol = &wasm.symbols.items[symbol_index]; |
| 2064 | 2157 | symbol.setUndefined(true); |
| 2065 | 2158 | symbol.setGlobal(true); |
| ... | ... | @@ -2068,12 +2161,12 @@ pub fn addOrUpdateImport( |
| 2068 | 2161 | // we specified a specific name for the symbol that does not match the import name |
| 2069 | 2162 | symbol.setFlag(.WASM_SYM_EXPLICIT_NAME); |
| 2070 | 2163 | } |
| 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); | |
| 2072 | 2165 | if (!global_gop.found_existing) { |
| 2073 | 2166 | const loc: SymbolLoc = .{ .file = null, .index = symbol_index }; |
| 2074 | 2167 | 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); | |
| 2077 | 2170 | } else if (global_gop.value_ptr.*.index != symbol_index) { |
| 2078 | 2171 | // We are not updating a symbol, but found an existing global |
| 2079 | 2172 | // symbol with the same name. This means we always favor the |
| ... | ... | @@ -2081,21 +2174,21 @@ pub fn addOrUpdateImport( |
| 2081 | 2174 | // We can also skip storing the import as we will not output |
| 2082 | 2175 | // this symbol. |
| 2083 | 2176 | return wasm.discarded.put( |
| 2084 | wasm.base.allocator, | |
| 2177 | gpa, | |
| 2085 | 2178 | .{ .file = null, .index = symbol_index }, |
| 2086 | 2179 | global_gop.value_ptr.*, |
| 2087 | 2180 | ); |
| 2088 | 2181 | } |
| 2089 | 2182 | |
| 2090 | 2183 | 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 }); | |
| 2092 | 2185 | const module_name = if (lib_name) |l_name| blk: { |
| 2093 | 2186 | break :blk l_name; |
| 2094 | 2187 | } else wasm.host_name; |
| 2095 | 2188 | if (!gop.found_existing) { |
| 2096 | 2189 | 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), | |
| 2099 | 2192 | .kind = .{ .function = ty_index }, |
| 2100 | 2193 | }; |
| 2101 | 2194 | } |
| ... | ... | @@ -2132,10 +2225,13 @@ const Kind = union(enum) { |
| 2132 | 2225 | |
| 2133 | 2226 | /// Parses an Atom and inserts its metadata into the corresponding sections. |
| 2134 | 2227 | fn 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; | |
| 2135 | 2232 | const atom = wasm.getAtomPtr(atom_index); |
| 2136 | 2233 | 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; | |
| 2139 | 2235 | |
| 2140 | 2236 | if (symbol.isDead() and do_garbage_collect) { |
| 2141 | 2237 | // Prevent unreferenced symbols from being parsed. |
| ... | ... | @@ -2147,7 +2243,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2147 | 2243 | const index: u32 = @intCast(wasm.functions.count() + wasm.imported_functions_count); |
| 2148 | 2244 | const type_index = wasm.atom_types.get(atom_index).?; |
| 2149 | 2245 | try wasm.functions.putNoClobber( |
| 2150 | wasm.base.allocator, | |
| 2246 | gpa, | |
| 2151 | 2247 | .{ .file = null, .index = index }, |
| 2152 | 2248 | .{ .func = .{ .type_index = type_index }, .sym_index = atom.sym_index }, |
| 2153 | 2249 | ); |
| ... | ... | @@ -2156,7 +2252,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2156 | 2252 | |
| 2157 | 2253 | if (wasm.code_section_index == null) { |
| 2158 | 2254 | wasm.code_section_index = @intCast(wasm.segments.items.len); |
| 2159 | try wasm.segments.append(wasm.base.allocator, .{ | |
| 2255 | try wasm.segments.append(gpa, .{ | |
| 2160 | 2256 | .alignment = atom.alignment, |
| 2161 | 2257 | .size = atom.size, |
| 2162 | 2258 | .offset = 0, |
| ... | ... | @@ -2167,11 +2263,11 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2167 | 2263 | break :result wasm.code_section_index.?; |
| 2168 | 2264 | }, |
| 2169 | 2265 | .data => result: { |
| 2170 | const segment_name = try std.mem.concat(wasm.base.allocator, u8, &.{ | |
| 2266 | const segment_name = try std.mem.concat(gpa, u8, &.{ | |
| 2171 | 2267 | kind.segmentName(), |
| 2172 | 2268 | wasm.string_table.get(symbol.name), |
| 2173 | 2269 | }); |
| 2174 | errdefer wasm.base.allocator.free(segment_name); | |
| 2270 | errdefer gpa.free(segment_name); | |
| 2175 | 2271 | const segment_info: types.Segment = .{ |
| 2176 | 2272 | .name = segment_name, |
| 2177 | 2273 | .alignment = atom.alignment, |
| ... | ... | @@ -2183,27 +2279,27 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2183 | 2279 | // we set the entire region of it to zeroes. |
| 2184 | 2280 | // We do not have to do this when exporting the memory (the default) because the runtime |
| 2185 | 2281 | // 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) { | |
| 2187 | 2283 | @memset(atom.code.items, 0); |
| 2188 | 2284 | } |
| 2189 | 2285 | |
| 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)); | |
| 2192 | 2288 | if (gop.found_existing) { |
| 2193 | 2289 | const index = gop.value_ptr.*; |
| 2194 | 2290 | wasm.segments.items[index].size += atom.size; |
| 2195 | 2291 | |
| 2196 | 2292 | symbol.index = @intCast(wasm.segment_info.getIndex(index).?); |
| 2197 | 2293 | // segment info already exists, so free its memory |
| 2198 | wasm.base.allocator.free(segment_name); | |
| 2294 | gpa.free(segment_name); | |
| 2199 | 2295 | break :result index; |
| 2200 | 2296 | } else { |
| 2201 | 2297 | const index: u32 = @intCast(wasm.segments.items.len); |
| 2202 | 2298 | var flags: u32 = 0; |
| 2203 | if (wasm.base.options.shared_memory) { | |
| 2299 | if (shared_memory) { | |
| 2204 | 2300 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); |
| 2205 | 2301 | } |
| 2206 | try wasm.segments.append(wasm.base.allocator, .{ | |
| 2302 | try wasm.segments.append(gpa, .{ | |
| 2207 | 2303 | .alignment = atom.alignment, |
| 2208 | 2304 | .size = 0, |
| 2209 | 2305 | .offset = 0, |
| ... | ... | @@ -2212,7 +2308,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2212 | 2308 | gop.value_ptr.* = index; |
| 2213 | 2309 | |
| 2214 | 2310 | 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); | |
| 2216 | 2312 | symbol.index = info_index; |
| 2217 | 2313 | break :result index; |
| 2218 | 2314 | } |
| ... | ... | @@ -2228,6 +2324,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void { |
| 2228 | 2324 | /// From a given index, append the given `Atom` at the back of the linked list. |
| 2229 | 2325 | /// Simply inserts it into the map of atoms when it doesn't exist yet. |
| 2230 | 2326 | pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void { |
| 2327 | const gpa = wasm.base.comp.gpa; | |
| 2231 | 2328 | const atom = wasm.getAtomPtr(atom_index); |
| 2232 | 2329 | if (wasm.atoms.getPtr(index)) |last_index_ptr| { |
| 2233 | 2330 | const last = wasm.getAtomPtr(last_index_ptr.*); |
| ... | ... | @@ -2235,7 +2332,7 @@ pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void |
| 2235 | 2332 | atom.prev = last_index_ptr.*; |
| 2236 | 2333 | last_index_ptr.* = atom_index; |
| 2237 | 2334 | } else { |
| 2238 | try wasm.atoms.putNoClobber(wasm.base.allocator, index, atom_index); | |
| 2335 | try wasm.atoms.putNoClobber(gpa, index, atom_index); | |
| 2239 | 2336 | } |
| 2240 | 2337 | } |
| 2241 | 2338 | |
| ... | ... | @@ -2344,7 +2441,7 @@ fn allocateVirtualAddresses(wasm: *Wasm) void { |
| 2344 | 2441 | }; |
| 2345 | 2442 | |
| 2346 | 2443 | 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; | |
| 2348 | 2445 | const segment_info = if (atom.file) |object_index| blk: { |
| 2349 | 2446 | break :blk wasm.objects.items[object_index].segment_info; |
| 2350 | 2447 | } else wasm.segment_info.values(); |
| ... | ... | @@ -2363,12 +2460,13 @@ fn allocateVirtualAddresses(wasm: *Wasm) void { |
| 2363 | 2460 | } |
| 2364 | 2461 | |
| 2365 | 2462 | fn sortDataSegments(wasm: *Wasm) !void { |
| 2463 | const gpa = wasm.base.comp.gpa; | |
| 2366 | 2464 | 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); | |
| 2369 | 2467 | |
| 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); | |
| 2372 | 2470 | |
| 2373 | 2471 | const SortContext = struct { |
| 2374 | 2472 | fn sort(_: void, lhs: []const u8, rhs: []const u8) bool { |
| ... | ... | @@ -2388,7 +2486,7 @@ fn sortDataSegments(wasm: *Wasm) !void { |
| 2388 | 2486 | const segment_index = wasm.data_segments.get(key).?; |
| 2389 | 2487 | new_mapping.putAssumeCapacity(key, segment_index); |
| 2390 | 2488 | } |
| 2391 | wasm.data_segments.deinit(wasm.base.allocator); | |
| 2489 | wasm.data_segments.deinit(gpa); | |
| 2392 | 2490 | wasm.data_segments = new_mapping; |
| 2393 | 2491 | } |
| 2394 | 2492 | |
| ... | ... | @@ -2401,8 +2499,9 @@ fn sortDataSegments(wasm: *Wasm) !void { |
| 2401 | 2499 | /// original functions and their types. We need to know the type to verify it doesn't |
| 2402 | 2500 | /// contain any parameters. |
| 2403 | 2501 | fn setupInitFunctions(wasm: *Wasm) !void { |
| 2502 | const gpa = wasm.base.comp.gpa; | |
| 2404 | 2503 | 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); | |
| 2406 | 2505 | for (object.init_funcs) |init_func| { |
| 2407 | 2506 | const symbol = object.symtable[init_func.symbol_index]; |
| 2408 | 2507 | const ty: std.wasm.Type = if (symbol.isUndefined()) ty: { |
| ... | ... | @@ -2439,9 +2538,10 @@ fn setupInitFunctions(wasm: *Wasm) !void { |
| 2439 | 2538 | /// Generates an atom containing the global error set' size. |
| 2440 | 2539 | /// This will only be generated if the symbol exists. |
| 2441 | 2540 | fn setupErrorsLen(wasm: *Wasm) !void { |
| 2541 | const gpa = wasm.base.comp.gpa; | |
| 2442 | 2542 | const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return; |
| 2443 | 2543 | |
| 2444 | const errors_len = wasm.base.options.module.?.global_error_set.count(); | |
| 2544 | const errors_len = wasm.base.comp.module.?.global_error_set.count(); | |
| 2445 | 2545 | // overwrite existing atom if it already exists (maybe the error set has increased) |
| 2446 | 2546 | // if not, allcoate a new atom. |
| 2447 | 2547 | const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: { |
| ... | ... | @@ -2456,19 +2556,19 @@ fn setupErrorsLen(wasm: *Wasm) !void { |
| 2456 | 2556 | prev_atom.next = atom.next; |
| 2457 | 2557 | atom.prev = null; |
| 2458 | 2558 | } |
| 2459 | atom.deinit(wasm.base.allocator); | |
| 2559 | atom.deinit(gpa); | |
| 2460 | 2560 | break :blk index; |
| 2461 | 2561 | } else new_atom: { |
| 2462 | 2562 | 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); | |
| 2465 | 2565 | break :new_atom atom_index; |
| 2466 | 2566 | }; |
| 2467 | 2567 | const atom = wasm.getAtomPtr(atom_index); |
| 2468 | 2568 | atom.* = Atom.empty; |
| 2469 | 2569 | atom.sym_index = loc.index; |
| 2470 | 2570 | 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); | |
| 2472 | 2572 | |
| 2473 | 2573 | try wasm.parseAtom(atom_index, .{ .data = .read_only }); |
| 2474 | 2574 | } |
| ... | ... | @@ -2480,16 +2580,17 @@ fn setupErrorsLen(wasm: *Wasm) !void { |
| 2480 | 2580 | /// references to the function stored in the symbol have been finalized so we end |
| 2481 | 2581 | /// up calling the resolved function. |
| 2482 | 2582 | fn initializeCallCtorsFunction(wasm: *Wasm) !void { |
| 2583 | const gpa = wasm.base.comp.gpa; | |
| 2483 | 2584 | // No code to emit, so also no ctors to call |
| 2484 | 2585 | if (wasm.code_section_index == null) { |
| 2485 | 2586 | // Make sure to remove it from the resolved symbols so we do not emit |
| 2486 | 2587 | // it within any section. TODO: Remove this once we implement garbage collection. |
| 2487 | 2588 | const loc = wasm.findGlobalSymbol("__wasm_call_ctors").?; |
| 2488 | std.debug.assert(wasm.resolved_symbols.swapRemove(loc)); | |
| 2589 | assert(wasm.resolved_symbols.swapRemove(loc)); | |
| 2489 | 2590 | return; |
| 2490 | 2591 | } |
| 2491 | 2592 | |
| 2492 | var function_body = std.ArrayList(u8).init(wasm.base.allocator); | |
| 2593 | var function_body = std.ArrayList(u8).init(gpa); | |
| 2493 | 2594 | defer function_body.deinit(); |
| 2494 | 2595 | const writer = function_body.writer(); |
| 2495 | 2596 | |
| ... | ... | @@ -2531,6 +2632,7 @@ fn createSyntheticFunction( |
| 2531 | 2632 | func_ty: std.wasm.Type, |
| 2532 | 2633 | function_body: *std.ArrayList(u8), |
| 2533 | 2634 | ) !void { |
| 2635 | const gpa = wasm.base.comp.gpa; | |
| 2534 | 2636 | const loc = wasm.findGlobalSymbol(symbol_name) orelse |
| 2535 | 2637 | try wasm.createSyntheticSymbol(symbol_name, .function); |
| 2536 | 2638 | const symbol = loc.getSymbol(wasm); |
| ... | ... | @@ -2541,7 +2643,7 @@ fn createSyntheticFunction( |
| 2541 | 2643 | // create function with above type |
| 2542 | 2644 | const func_index = wasm.imported_functions_count + @as(u32, @intCast(wasm.functions.count())); |
| 2543 | 2645 | try wasm.functions.putNoClobber( |
| 2544 | wasm.base.allocator, | |
| 2646 | gpa, | |
| 2545 | 2647 | .{ .file = null, .index = func_index }, |
| 2546 | 2648 | .{ .func = .{ .type_index = ty_index }, .sym_index = loc.index }, |
| 2547 | 2649 | ); |
| ... | ... | @@ -2549,7 +2651,7 @@ fn createSyntheticFunction( |
| 2549 | 2651 | |
| 2550 | 2652 | // create the atom that will be output into the final binary |
| 2551 | 2653 | 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); | |
| 2553 | 2655 | atom.* = .{ |
| 2554 | 2656 | .size = @as(u32, @intCast(function_body.items.len)), |
| 2555 | 2657 | .offset = 0, |
| ... | ... | @@ -2562,7 +2664,7 @@ fn createSyntheticFunction( |
| 2562 | 2664 | .original_offset = 0, |
| 2563 | 2665 | }; |
| 2564 | 2666 | 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); | |
| 2566 | 2668 | |
| 2567 | 2669 | // `allocateAtoms` has already been called, set the atom's offset manually. |
| 2568 | 2670 | // This is fine to do manually as we insert the atom at the very end. |
| ... | ... | @@ -2582,10 +2684,11 @@ pub fn createFunction( |
| 2582 | 2684 | function_body: *std.ArrayList(u8), |
| 2583 | 2685 | relocations: *std.ArrayList(Relocation), |
| 2584 | 2686 | ) !u32 { |
| 2687 | const gpa = wasm.base.comp.gpa; | |
| 2585 | 2688 | const loc = try wasm.createSyntheticSymbol(symbol_name, .function); |
| 2586 | 2689 | |
| 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); | |
| 2589 | 2692 | atom.* = .{ |
| 2590 | 2693 | .size = @intCast(function_body.items.len), |
| 2591 | 2694 | .offset = 0, |
| ... | ... | @@ -2607,9 +2710,9 @@ pub fn createFunction( |
| 2607 | 2710 | break :idx index; |
| 2608 | 2711 | }; |
| 2609 | 2712 | 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); | |
| 2613 | 2716 | |
| 2614 | 2717 | return loc.index; |
| 2615 | 2718 | } |
| ... | ... | @@ -2622,9 +2725,13 @@ fn setupStartSection(wasm: *Wasm) !void { |
| 2622 | 2725 | } |
| 2623 | 2726 | |
| 2624 | 2727 | fn 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; | |
| 2626 | 2733 | |
| 2627 | var function_body = std.ArrayList(u8).init(wasm.base.allocator); | |
| 2734 | var function_body = std.ArrayList(u8).init(gpa); | |
| 2628 | 2735 | defer function_body.deinit(); |
| 2629 | 2736 | const writer = function_body.writer(); |
| 2630 | 2737 | |
| ... | ... | @@ -2684,6 +2791,7 @@ fn initializeTLSFunction(wasm: *Wasm) !void { |
| 2684 | 2791 | } |
| 2685 | 2792 | |
| 2686 | 2793 | fn setupImports(wasm: *Wasm) !void { |
| 2794 | const gpa = wasm.base.comp.gpa; | |
| 2687 | 2795 | log.debug("Merging imports", .{}); |
| 2688 | 2796 | var discarded_it = wasm.discarded.keyIterator(); |
| 2689 | 2797 | while (discarded_it.next()) |discarded| { |
| ... | ... | @@ -2718,12 +2826,12 @@ fn setupImports(wasm: *Wasm) !void { |
| 2718 | 2826 | // We copy the import to a new import to ensure the names contain references |
| 2719 | 2827 | // to the internal string table, rather than of the object file. |
| 2720 | 2828 | 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)), | |
| 2723 | 2831 | .kind = import.kind, |
| 2724 | 2832 | }; |
| 2725 | 2833 | // 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); | |
| 2727 | 2835 | } |
| 2728 | 2836 | |
| 2729 | 2837 | // Assign all indexes of the imports to their representing symbols |
| ... | ... | @@ -2764,7 +2872,9 @@ fn setupImports(wasm: *Wasm) !void { |
| 2764 | 2872 | /// Takes the global, function and table section from each linked object file |
| 2765 | 2873 | /// and merges it into a single section for each. |
| 2766 | 2874 | fn 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); | |
| 2768 | 2878 | defer removed_duplicates.deinit(); |
| 2769 | 2879 | |
| 2770 | 2880 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| ... | ... | @@ -2791,7 +2901,7 @@ fn mergeSections(wasm: *Wasm) !void { |
| 2791 | 2901 | switch (symbol.tag) { |
| 2792 | 2902 | .function => { |
| 2793 | 2903 | const gop = try wasm.functions.getOrPut( |
| 2794 | wasm.base.allocator, | |
| 2904 | gpa, | |
| 2795 | 2905 | .{ .file = sym_loc.file, .index = symbol.index }, |
| 2796 | 2906 | ); |
| 2797 | 2907 | if (gop.found_existing) { |
| ... | ... | @@ -2800,7 +2910,7 @@ fn mergeSections(wasm: *Wasm) !void { |
| 2800 | 2910 | // we only emit a single function, instead of duplicates. |
| 2801 | 2911 | symbol.unmark(); |
| 2802 | 2912 | try wasm.discarded.putNoClobber( |
| 2803 | wasm.base.allocator, | |
| 2913 | gpa, | |
| 2804 | 2914 | sym_loc, |
| 2805 | 2915 | .{ .file = gop.key_ptr.*.file, .index = gop.value_ptr.*.sym_index }, |
| 2806 | 2916 | ); |
| ... | ... | @@ -2813,12 +2923,12 @@ fn mergeSections(wasm: *Wasm) !void { |
| 2813 | 2923 | .global => { |
| 2814 | 2924 | const original_global = object.globals[index]; |
| 2815 | 2925 | 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); | |
| 2817 | 2927 | }, |
| 2818 | 2928 | .table => { |
| 2819 | 2929 | const original_table = object.tables[index]; |
| 2820 | 2930 | 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); | |
| 2822 | 2932 | }, |
| 2823 | 2933 | else => unreachable, |
| 2824 | 2934 | } |
| ... | ... | @@ -2838,10 +2948,11 @@ fn mergeSections(wasm: *Wasm) !void { |
| 2838 | 2948 | /// 'types' section, while assigning the type index to the representing |
| 2839 | 2949 | /// section (import, export, function). |
| 2840 | 2950 | fn mergeTypes(wasm: *Wasm) !void { |
| 2951 | const gpa = wasm.base.comp.gpa; | |
| 2841 | 2952 | // A map to track which functions have already had their |
| 2842 | 2953 | // type inserted. If we do this for the same function multiple times, |
| 2843 | 2954 | // 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); | |
| 2845 | 2956 | try dirty.ensureUnusedCapacity(@as(u32, @intCast(wasm.functions.count()))); |
| 2846 | 2957 | defer dirty.deinit(); |
| 2847 | 2958 | |
| ... | ... | @@ -2873,10 +2984,12 @@ fn mergeTypes(wasm: *Wasm) !void { |
| 2873 | 2984 | } |
| 2874 | 2985 | |
| 2875 | 2986 | fn 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; | |
| 2877 | 2990 | log.debug("Building exports from symbols", .{}); |
| 2878 | 2991 | |
| 2879 | const force_exp_names = wasm.base.options.export_symbol_names; | |
| 2992 | const force_exp_names = wasm.export_symbol_names; | |
| 2880 | 2993 | if (force_exp_names.len > 0) { |
| 2881 | 2994 | var failed_exports = false; |
| 2882 | 2995 | |
| ... | ... | @@ -2898,16 +3011,16 @@ fn setupExports(wasm: *Wasm) !void { |
| 2898 | 3011 | |
| 2899 | 3012 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 2900 | 3013 | const symbol = sym_loc.getSymbol(wasm); |
| 2901 | if (!symbol.isExported(wasm.base.options.rdynamic)) continue; | |
| 3014 | if (!symbol.isExported(comp.config.rdynamic)) continue; | |
| 2902 | 3015 | |
| 2903 | 3016 | const sym_name = sym_loc.getName(wasm); |
| 2904 | 3017 | const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: { |
| 2905 | 3018 | 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); | |
| 2907 | 3020 | }; |
| 2908 | 3021 | const exp: types.Export = if (symbol.tag == .data) exp: { |
| 2909 | 3022 | 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, .{ | |
| 2911 | 3024 | .global_type = .{ .valtype = .i32, .mutable = false }, |
| 2912 | 3025 | .init = .{ .i32_const = @as(i32, @intCast(symbol.virtual_address)) }, |
| 2913 | 3026 | }); |
| ... | ... | @@ -2926,15 +3039,16 @@ fn setupExports(wasm: *Wasm) !void { |
| 2926 | 3039 | wasm.string_table.get(exp.name), |
| 2927 | 3040 | exp.index, |
| 2928 | 3041 | }); |
| 2929 | try wasm.exports.append(wasm.base.allocator, exp); | |
| 3042 | try wasm.exports.append(gpa, exp); | |
| 2930 | 3043 | } |
| 2931 | 3044 | |
| 2932 | 3045 | log.debug("Completed building exports. Total count: ({d})", .{wasm.exports.items.len}); |
| 2933 | 3046 | } |
| 2934 | 3047 | |
| 2935 | 3048 | fn setupStart(wasm: *Wasm) !void { |
| 3049 | const comp = wasm.base.comp; | |
| 2936 | 3050 | // 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; | |
| 2938 | 3052 | |
| 2939 | 3053 | const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse { |
| 2940 | 3054 | log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name}); |
| ... | ... | @@ -2948,33 +3062,33 @@ fn setupStart(wasm: *Wasm) !void { |
| 2948 | 3062 | } |
| 2949 | 3063 | |
| 2950 | 3064 | // 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) { | |
| 2952 | 3066 | symbol.setFlag(.WASM_SYM_EXPORTED); |
| 2953 | 3067 | } |
| 2954 | 3068 | } |
| 2955 | 3069 | |
| 2956 | 3070 | /// Sets up the memory section of the wasm module, as well as the stack. |
| 2957 | 3071 | fn setupMemory(wasm: *Wasm) !void { |
| 3072 | const comp = wasm.base.comp; | |
| 3073 | const shared_memory = comp.config.shared_memory; | |
| 2958 | 3074 | log.debug("Setting up memory layout", .{}); |
| 2959 | 3075 | 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; | |
| 2962 | 3076 | const stack_alignment: Alignment = .@"16"; // wasm's stack alignment as specified by tool-convention |
| 2963 | 3077 | const heap_alignment: Alignment = .@"16"; // wasm's heap alignment as specified by tool-convention |
| 2964 | 3078 | |
| 2965 | 3079 | // Always place the stack at the start by default |
| 2966 | 3080 | // unless the user specified the global-base flag |
| 2967 | 3081 | 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: { | |
| 2969 | 3083 | place_stack_first = false; |
| 2970 | 3084 | break :blk base; |
| 2971 | 3085 | } else 0; |
| 2972 | 3086 | |
| 2973 | const is_obj = wasm.base.options.output_mode == .Obj; | |
| 3087 | const is_obj = comp.config.output_mode == .Obj; | |
| 2974 | 3088 | |
| 2975 | 3089 | if (place_stack_first and !is_obj) { |
| 2976 | 3090 | memory_ptr = stack_alignment.forward(memory_ptr); |
| 2977 | memory_ptr += stack_size; | |
| 3091 | memory_ptr += wasm.base.stack_size; | |
| 2978 | 3092 | // We always put the stack pointer global at index 0 |
| 2979 | 3093 | wasm.wasm_globals.items[0].init.i32_const = @as(i32, @bitCast(@as(u32, @intCast(memory_ptr)))); |
| 2980 | 3094 | } |
| ... | ... | @@ -2997,7 +3111,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 2997 | 3111 | } |
| 2998 | 3112 | if (wasm.findGlobalSymbol("__tls_base")) |loc| { |
| 2999 | 3113 | 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) | |
| 3001 | 3115 | @as(i32, 0) |
| 3002 | 3116 | else |
| 3003 | 3117 | @as(i32, @intCast(memory_ptr)); |
| ... | ... | @@ -3010,7 +3124,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3010 | 3124 | } |
| 3011 | 3125 | |
| 3012 | 3126 | // 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()) { | |
| 3014 | 3128 | // align to pointer size |
| 3015 | 3129 | memory_ptr = mem.alignForward(u64, memory_ptr, 4); |
| 3016 | 3130 | const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data); |
| ... | ... | @@ -3021,7 +3135,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3021 | 3135 | |
| 3022 | 3136 | if (!place_stack_first and !is_obj) { |
| 3023 | 3137 | memory_ptr = stack_alignment.forward(memory_ptr); |
| 3024 | memory_ptr += stack_size; | |
| 3138 | memory_ptr += wasm.base.stack_size; | |
| 3025 | 3139 | wasm.wasm_globals.items[0].init.i32_const = @as(i32, @bitCast(@as(u32, @intCast(memory_ptr)))); |
| 3026 | 3140 | } |
| 3027 | 3141 | |
| ... | ... | @@ -3036,7 +3150,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3036 | 3150 | // For now we only support wasm32 by setting the maximum allowed memory size 2^32-1 |
| 3037 | 3151 | const max_memory_allowed: u64 = (1 << 32) - 1; |
| 3038 | 3152 | |
| 3039 | if (wasm.base.options.initial_memory) |initial_memory| { | |
| 3153 | if (wasm.initial_memory) |initial_memory| { | |
| 3040 | 3154 | if (!std.mem.isAlignedGeneric(u64, initial_memory, page_size)) { |
| 3041 | 3155 | log.err("Initial memory must be {d}-byte aligned", .{page_size}); |
| 3042 | 3156 | return error.MissAlignment; |
| ... | ... | @@ -3062,7 +3176,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3062 | 3176 | symbol.virtual_address = @as(u32, @intCast(memory_ptr)); |
| 3063 | 3177 | } |
| 3064 | 3178 | |
| 3065 | if (wasm.base.options.max_memory) |max_memory| { | |
| 3179 | if (wasm.max_memory) |max_memory| { | |
| 3066 | 3180 | if (!std.mem.isAlignedGeneric(u64, max_memory, page_size)) { |
| 3067 | 3181 | log.err("Maximum memory must be {d}-byte aligned", .{page_size}); |
| 3068 | 3182 | return error.MissAlignment; |
| ... | ... | @@ -3077,7 +3191,7 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3077 | 3191 | } |
| 3078 | 3192 | wasm.memories.limits.max = @as(u32, @intCast(max_memory / page_size)); |
| 3079 | 3193 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX); |
| 3080 | if (wasm.base.options.shared_memory) { | |
| 3194 | if (shared_memory) { | |
| 3081 | 3195 | wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED); |
| 3082 | 3196 | } |
| 3083 | 3197 | log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max}); |
| ... | ... | @@ -3088,29 +3202,32 @@ fn setupMemory(wasm: *Wasm) !void { |
| 3088 | 3202 | /// index of the segment within the final data section. When the segment does not yet |
| 3089 | 3203 | /// exist, a new one will be initialized and appended. The new index will be returned in that case. |
| 3090 | 3204 | pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u32 { |
| 3205 | const comp = wasm.base.comp; | |
| 3206 | const gpa = comp.gpa; | |
| 3091 | 3207 | const object: Object = wasm.objects.items[object_index]; |
| 3092 | 3208 | 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; | |
| 3094 | 3211 | |
| 3095 | 3212 | switch (symbol.tag) { |
| 3096 | 3213 | .data => { |
| 3097 | 3214 | 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)); | |
| 3100 | 3217 | if (!result.found_existing) { |
| 3101 | 3218 | result.value_ptr.* = index; |
| 3102 | 3219 | var flags: u32 = 0; |
| 3103 | if (wasm.base.options.shared_memory) { | |
| 3220 | if (shared_memory) { | |
| 3104 | 3221 | flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE); |
| 3105 | 3222 | } |
| 3106 | try wasm.segments.append(wasm.base.allocator, .{ | |
| 3223 | try wasm.segments.append(gpa, .{ | |
| 3107 | 3224 | .alignment = .@"1", |
| 3108 | 3225 | .size = 0, |
| 3109 | 3226 | .offset = 0, |
| 3110 | 3227 | .flags = flags, |
| 3111 | 3228 | }); |
| 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), | |
| 3114 | 3231 | .alignment = segment_info.alignment, |
| 3115 | 3232 | .flags = segment_info.flags, |
| 3116 | 3233 | }); |
| ... | ... | @@ -3183,7 +3300,8 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3 |
| 3183 | 3300 | |
| 3184 | 3301 | /// Appends a new segment with default field values |
| 3185 | 3302 | fn 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, .{ | |
| 3187 | 3305 | .alignment = .@"1", |
| 3188 | 3306 | .size = 0, |
| 3189 | 3307 | .offset = 0, |
| ... | ... | @@ -3203,14 +3321,15 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { |
| 3203 | 3321 | // and then return said symbol's index. The final table will be populated |
| 3204 | 3322 | // during `flush` when we know all possible error names. |
| 3205 | 3323 | |
| 3324 | const gpa = wasm.base.comp.gpa; | |
| 3206 | 3325 | const atom_index = try wasm.createAtom(); |
| 3207 | 3326 | const atom = wasm.getAtomPtr(atom_index); |
| 3208 | 3327 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 3209 | const mod = wasm.base.options.module.?; | |
| 3328 | const mod = wasm.base.comp.module.?; | |
| 3210 | 3329 | atom.alignment = slice_ty.abiAlignment(mod); |
| 3211 | 3330 | const sym_index = atom.sym_index; |
| 3212 | 3331 | |
| 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"); | |
| 3214 | 3333 | const symbol = &wasm.symbols.items[sym_index]; |
| 3215 | 3334 | symbol.* = .{ |
| 3216 | 3335 | .name = sym_name, |
| ... | ... | @@ -3222,7 +3341,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { |
| 3222 | 3341 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 3223 | 3342 | symbol.mark(); |
| 3224 | 3343 | |
| 3225 | try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {}); | |
| 3344 | try wasm.resolved_symbols.put(gpa, atom.symbolLoc(), {}); | |
| 3226 | 3345 | |
| 3227 | 3346 | log.debug("Error name table was created with symbol index: ({d})", .{sym_index}); |
| 3228 | 3347 | wasm.error_table_symbol = sym_index; |
| ... | ... | @@ -3234,6 +3353,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { |
| 3234 | 3353 | /// This creates a table that consists of pointers and length to each error name. |
| 3235 | 3354 | /// The table is what is being pointed to within the runtime bodies that are generated. |
| 3236 | 3355 | fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3356 | const gpa = wasm.base.comp.gpa; | |
| 3237 | 3357 | const symbol_index = wasm.error_table_symbol orelse return; |
| 3238 | 3358 | const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = symbol_index }).?; |
| 3239 | 3359 | |
| ... | ... | @@ -3243,7 +3363,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3243 | 3363 | const names_atom_index = try wasm.createAtom(); |
| 3244 | 3364 | const names_atom = wasm.getAtomPtr(names_atom_index); |
| 3245 | 3365 | 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"); | |
| 3247 | 3367 | const names_symbol = &wasm.symbols.items[names_atom.sym_index]; |
| 3248 | 3368 | names_symbol.* = .{ |
| 3249 | 3369 | .name = sym_name, |
| ... | ... | @@ -3259,7 +3379,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3259 | 3379 | |
| 3260 | 3380 | // Addend for each relocation to the table |
| 3261 | 3381 | var addend: u32 = 0; |
| 3262 | const mod = wasm.base.options.module.?; | |
| 3382 | const mod = wasm.base.comp.module.?; | |
| 3263 | 3383 | for (mod.global_error_set.keys()) |error_name_nts| { |
| 3264 | 3384 | const atom = wasm.getAtomPtr(atom_index); |
| 3265 | 3385 | |
| ... | ... | @@ -3269,10 +3389,10 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3269 | 3389 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 3270 | 3390 | const offset = @as(u32, @intCast(atom.code.items.len)); |
| 3271 | 3391 | // 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); | |
| 3274 | 3394 | // create relocation to the error name |
| 3275 | try atom.relocs.append(wasm.base.allocator, .{ | |
| 3395 | try atom.relocs.append(gpa, .{ | |
| 3276 | 3396 | .index = names_atom.sym_index, |
| 3277 | 3397 | .relocation_type = .R_WASM_MEMORY_ADDR_I32, |
| 3278 | 3398 | .offset = offset, |
| ... | ... | @@ -3282,7 +3402,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3282 | 3402 | addend += len; |
| 3283 | 3403 | |
| 3284 | 3404 | // 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); | |
| 3286 | 3406 | names_atom.code.appendSliceAssumeCapacity(error_name); |
| 3287 | 3407 | names_atom.code.appendAssumeCapacity(0); |
| 3288 | 3408 | |
| ... | ... | @@ -3291,8 +3411,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3291 | 3411 | names_atom.size = addend; |
| 3292 | 3412 | |
| 3293 | 3413 | 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); | |
| 3296 | 3416 | |
| 3297 | 3417 | // link the atoms with the rest of the binary so they can be allocated |
| 3298 | 3418 | // and relocations will be performed. |
| ... | ... | @@ -3304,7 +3424,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 3304 | 3424 | /// This initializes the index, appends a new segment, |
| 3305 | 3425 | /// and finally, creates a managed `Atom`. |
| 3306 | 3426 | pub 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); | |
| 3308 | 3429 | index.* = new_index; |
| 3309 | 3430 | try wasm.appendDummySegment(); |
| 3310 | 3431 | |
| ... | ... | @@ -3312,7 +3433,7 @@ pub fn createDebugSectionForIndex(wasm: *Wasm, index: *?u32, name: []const u8) ! |
| 3312 | 3433 | const atom = wasm.getAtomPtr(atom_index); |
| 3313 | 3434 | wasm.symbols.items[atom.sym_index] = .{ |
| 3314 | 3435 | .tag = .section, |
| 3315 | .name = try wasm.string_table.put(wasm.base.allocator, name), | |
| 3436 | .name = try wasm.string_table.put(gpa, name), | |
| 3316 | 3437 | .index = 0, |
| 3317 | 3438 | .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL), |
| 3318 | 3439 | }; |
| ... | ... | @@ -3322,8 +3443,10 @@ pub fn createDebugSectionForIndex(wasm: *Wasm, index: *?u32, name: []const u8) ! |
| 3322 | 3443 | } |
| 3323 | 3444 | |
| 3324 | 3445 | fn resetState(wasm: *Wasm) void { |
| 3446 | const gpa = wasm.base.comp.gpa; | |
| 3447 | ||
| 3325 | 3448 | for (wasm.segment_info.values()) |segment_info| { |
| 3326 | wasm.base.allocator.free(segment_info.name); | |
| 3449 | gpa.free(segment_info.name); | |
| 3327 | 3450 | } |
| 3328 | 3451 | |
| 3329 | 3452 | var atom_it = wasm.decls.valueIterator(); |
| ... | ... | @@ -3357,49 +3480,44 @@ fn resetState(wasm: *Wasm) void { |
| 3357 | 3480 | wasm.debug_pubtypes_index = null; |
| 3358 | 3481 | } |
| 3359 | 3482 | |
| 3360 | pub 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 | } | |
| 3483 | pub 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; | |
| 3367 | 3487 | |
| 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); | |
| 3372 | 3492 | } else { |
| 3373 | return wasm.flushModule(comp, prog_node); | |
| 3493 | return wasm.flushModule(arena, prog_node); | |
| 3374 | 3494 | } |
| 3375 | 3495 | } |
| 3376 | 3496 | |
| 3377 | 3497 | /// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary. |
| 3378 | fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 3498 | fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 3379 | 3499 | const tracy = trace(@src()); |
| 3380 | 3500 | defer tracy.end(); |
| 3381 | 3501 | |
| 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; | |
| 3384 | 3505 | |
| 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; | |
| 3392 | 3510 | |
| 3393 | 3511 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 3394 | 3512 | // 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); | |
| 3398 | 3516 | |
| 3399 | 3517 | 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.? }); | |
| 3401 | 3519 | } else { |
| 3402 | break :blk wasm.base.intermediary_basename.?; | |
| 3520 | break :blk wasm.base.zcu_object_sub_path.?; | |
| 3403 | 3521 | } |
| 3404 | 3522 | } else null; |
| 3405 | 3523 | |
| ... | ... | @@ -3416,12 +3534,14 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3416 | 3534 | const id_symlink_basename = "zld.id"; |
| 3417 | 3535 | |
| 3418 | 3536 | var man: Cache.Manifest = undefined; |
| 3419 | defer if (!options.disable_lld_caching) man.deinit(); | |
| 3537 | defer if (!wasm.base.disable_lld_caching) man.deinit(); | |
| 3420 | 3538 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 3421 | 3539 | |
| 3540 | const objects = comp.objects; | |
| 3541 | ||
| 3422 | 3542 | // NOTE: The following section must be maintained to be equal |
| 3423 | 3543 | // as the section defined in `linkWithLLD` |
| 3424 | if (!options.disable_lld_caching) { | |
| 3544 | if (!wasm.base.disable_lld_caching) { | |
| 3425 | 3545 | man = comp.cache_parent.obtain(); |
| 3426 | 3546 | |
| 3427 | 3547 | // 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 |
| 3429 | 3549 | |
| 3430 | 3550 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 3431 | 3551 | |
| 3432 | for (options.objects) |obj| { | |
| 3552 | for (objects) |obj| { | |
| 3433 | 3553 | _ = try man.addFile(obj.path, null); |
| 3434 | 3554 | man.hash.add(obj.must_link); |
| 3435 | 3555 | } |
| ... | ... | @@ -3438,19 +3558,19 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3438 | 3558 | } |
| 3439 | 3559 | try man.addOptionalFile(module_obj_path); |
| 3440 | 3560 | 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); | |
| 3452 | 3572 | // 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| { | |
| 3454 | 3574 | man.hash.addBytes(symbol_name); |
| 3455 | 3575 | } |
| 3456 | 3576 | |
| ... | ... | @@ -3485,30 +3605,36 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3485 | 3605 | |
| 3486 | 3606 | // Positional arguments to the linker such as object files and static archives. |
| 3487 | 3607 | 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; | |
| 3489 | 3616 | |
| 3490 | 3617 | // 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); | |
| 3494 | 3621 | 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| { | |
| 3497 | 3623 | try positionals.append(try comp.get_libc_crt_file( |
| 3498 | 3624 | arena, |
| 3499 | 3625 | wasi_libc.emulatedLibCRFileLibName(crt_file), |
| 3500 | 3626 | )); |
| 3501 | 3627 | } |
| 3502 | 3628 | |
| 3503 | if (wasm.base.options.link_libc) { | |
| 3629 | if (link_libc) { | |
| 3504 | 3630 | try positionals.append(try comp.get_libc_crt_file( |
| 3505 | 3631 | arena, |
| 3506 | wasi_libc.execModelCrtFileFullName(wasm.base.options.wasi_exec_model), | |
| 3632 | wasi_libc.execModelCrtFileFullName(wasi_exec_model), | |
| 3507 | 3633 | )); |
| 3508 | 3634 | try positionals.append(try comp.get_libc_crt_file(arena, "libc.a")); |
| 3509 | 3635 | } |
| 3510 | 3636 | |
| 3511 | if (wasm.base.options.link_libcpp) { | |
| 3637 | if (link_libcpp) { | |
| 3512 | 3638 | try positionals.append(comp.libcxx_static_lib.?.full_object_path); |
| 3513 | 3639 | try positionals.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 3514 | 3640 | } |
| ... | ... | @@ -3519,7 +3645,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3519 | 3645 | try positionals.append(path); |
| 3520 | 3646 | } |
| 3521 | 3647 | |
| 3522 | for (options.objects) |object| { | |
| 3648 | for (objects) |object| { | |
| 3523 | 3649 | try positionals.append(object.path); |
| 3524 | 3650 | } |
| 3525 | 3651 | |
| ... | ... | @@ -3562,7 +3688,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 3562 | 3688 | try wasm.setupExports(); |
| 3563 | 3689 | try wasm.writeToFile(enabled_features, emit_features_count, arena); |
| 3564 | 3690 | |
| 3565 | if (!wasm.base.options.disable_lld_caching) { | |
| 3691 | if (!wasm.base.disable_lld_caching) { | |
| 3566 | 3692 | // Update the file with the digest. If it fails we can continue; it only |
| 3567 | 3693 | // means that the next invocation will have an unnecessary cache miss. |
| 3568 | 3694 | 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 |
| 3578 | 3704 | } |
| 3579 | 3705 | } |
| 3580 | 3706 | |
| 3581 | pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 3707 | pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void { | |
| 3582 | 3708 | const tracy = trace(@src()); |
| 3583 | 3709 | defer tracy.end(); |
| 3584 | 3710 | |
| 3711 | const comp = wasm.base.comp; | |
| 3712 | ||
| 3585 | 3713 | 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; | |
| 3587 | 3716 | } |
| 3588 | 3717 | |
| 3589 | 3718 | 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 |
| 3593 | 3722 | // ensure the error names table is populated when an error name is referenced |
| 3594 | 3723 | try wasm.populateErrorNameTable(); |
| 3595 | 3724 | |
| 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; | |
| 3600 | 3726 | |
| 3601 | 3727 | // Positional arguments to the linker such as object files and static archives. |
| 3602 | 3728 | var positionals = std.ArrayList([]const u8).init(arena); |
| 3603 | try positionals.ensureUnusedCapacity(wasm.base.options.objects.len); | |
| 3729 | try positionals.ensureUnusedCapacity(objects.len); | |
| 3604 | 3730 | |
| 3605 | for (wasm.base.options.objects) |object| { | |
| 3731 | for (objects) |object| { | |
| 3606 | 3732 | positionals.appendAssumeCapacity(object.path); |
| 3607 | 3733 | } |
| 3608 | 3734 | |
| ... | ... | @@ -3634,7 +3760,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3634 | 3760 | try wasm.markReferences(); |
| 3635 | 3761 | try wasm.setupErrorsLen(); |
| 3636 | 3762 | try wasm.setupImports(); |
| 3637 | if (wasm.base.options.module) |mod| { | |
| 3763 | if (comp.module) |mod| { | |
| 3638 | 3764 | var decl_it = wasm.decls.iterator(); |
| 3639 | 3765 | while (decl_it.next()) |entry| { |
| 3640 | 3766 | const decl = mod.declPtr(entry.key_ptr.*); |
| ... | ... | @@ -3649,8 +3775,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 3649 | 3775 | } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) { |
| 3650 | 3776 | // for safe build modes, we store the atom in the data segment, |
| 3651 | 3777 | // 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 | }; | |
| 3654 | 3784 | try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized }); |
| 3655 | 3785 | } else { |
| 3656 | 3786 | // 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 |
| 3685 | 3815 | } |
| 3686 | 3816 | |
| 3687 | 3817 | if (wasm.dwarf) |*dwarf| { |
| 3688 | try dwarf.flushModule(wasm.base.options.module.?); | |
| 3818 | try dwarf.flushModule(comp.module.?); | |
| 3689 | 3819 | } |
| 3690 | 3820 | } |
| 3691 | 3821 | |
| ... | ... | @@ -3711,6 +3841,14 @@ fn writeToFile( |
| 3711 | 3841 | feature_count: u32, |
| 3712 | 3842 | arena: Allocator, |
| 3713 | 3843 | ) !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 | ||
| 3714 | 3852 | // Size of each section header |
| 3715 | 3853 | const header_size = 5 + 1; |
| 3716 | 3854 | // The amount of sections that will be written |
| ... | ... | @@ -3719,9 +3857,9 @@ fn writeToFile( |
| 3719 | 3857 | var code_section_index: ?u32 = null; |
| 3720 | 3858 | // Index of the data section. Used to tell relocation table where the section lives. |
| 3721 | 3859 | 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); | |
| 3723 | 3861 | |
| 3724 | var binary_bytes = std.ArrayList(u8).init(wasm.base.allocator); | |
| 3862 | var binary_bytes = std.ArrayList(u8).init(gpa); | |
| 3725 | 3863 | defer binary_bytes.deinit(); |
| 3726 | 3864 | const binary_writer = binary_bytes.writer(); |
| 3727 | 3865 | |
| ... | ... | @@ -3759,8 +3897,6 @@ fn writeToFile( |
| 3759 | 3897 | } |
| 3760 | 3898 | |
| 3761 | 3899 | // Import section |
| 3762 | const import_memory = wasm.base.options.import_memory or is_obj; | |
| 3763 | const export_memory = wasm.base.options.export_memory; | |
| 3764 | 3900 | if (wasm.imports.count() != 0 or import_memory) { |
| 3765 | 3901 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 3766 | 3902 | |
| ... | ... | @@ -3774,8 +3910,8 @@ fn writeToFile( |
| 3774 | 3910 | if (import_memory) { |
| 3775 | 3911 | const mem_name = if (is_obj) "__linear_memory" else "memory"; |
| 3776 | 3912 | 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), | |
| 3779 | 3915 | .kind = .{ .memory = wasm.memories.limits }, |
| 3780 | 3916 | }; |
| 3781 | 3917 | try wasm.emitImport(binary_writer, mem_imp); |
| ... | ... | @@ -3937,7 +4073,7 @@ fn writeToFile( |
| 3937 | 4073 | |
| 3938 | 4074 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| 3939 | 4075 | 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) { | |
| 3941 | 4077 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 3942 | 4078 | try writeVecSectionHeader( |
| 3943 | 4079 | binary_bytes.items, |
| ... | ... | @@ -3955,7 +4091,7 @@ fn writeToFile( |
| 3955 | 4091 | var atom_index = wasm.atoms.get(code_index).?; |
| 3956 | 4092 | |
| 3957 | 4093 | // 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()); | |
| 3959 | 4095 | defer sorted_atoms.deinit(); |
| 3960 | 4096 | |
| 3961 | 4097 | while (true) { |
| ... | ... | @@ -3966,7 +4102,7 @@ fn writeToFile( |
| 3966 | 4102 | sorted_atoms.appendAssumeCapacity(atom); // found more code atoms than functions |
| 3967 | 4103 | atom_index = atom.prev orelse break; |
| 3968 | 4104 | } |
| 3969 | std.debug.assert(wasm.functions.count() == sorted_atoms.items.len); | |
| 4105 | assert(wasm.functions.count() == sorted_atoms.items.len); | |
| 3970 | 4106 | |
| 3971 | 4107 | const atom_sort_fn = struct { |
| 3972 | 4108 | fn sort(ctx: *const Wasm, lhs: *const Atom, rhs: *const Atom) bool { |
| ... | ... | @@ -4079,14 +4215,14 @@ fn writeToFile( |
| 4079 | 4215 | if (data_section_index) |data_index| { |
| 4080 | 4216 | try wasm.emitDataRelocations(&binary_bytes, data_index, symbol_table); |
| 4081 | 4217 | } |
| 4082 | } else if (!wasm.base.options.strip) { | |
| 4218 | } else if (comp.config.debug_format != .strip) { | |
| 4083 | 4219 | try wasm.emitNameSection(&binary_bytes, arena); |
| 4084 | 4220 | } |
| 4085 | 4221 | |
| 4086 | if (!wasm.base.options.strip) { | |
| 4222 | if (comp.config.debug_format != .strip) { | |
| 4087 | 4223 | // The build id must be computed on the main sections only, |
| 4088 | 4224 | // so we have to do it now, before the debug sections. |
| 4089 | switch (wasm.base.options.build_id) { | |
| 4225 | switch (wasm.base.build_id) { | |
| 4090 | 4226 | .none => {}, |
| 4091 | 4227 | .fast => { |
| 4092 | 4228 | var id: [16]u8 = undefined; |
| ... | ... | @@ -4112,7 +4248,7 @@ fn writeToFile( |
| 4112 | 4248 | } |
| 4113 | 4249 | |
| 4114 | 4250 | // if (wasm.dwarf) |*dwarf| { |
| 4115 | // const mod = wasm.base.options.module.?; | |
| 4251 | // const mod = comp.module.?; | |
| 4116 | 4252 | // try dwarf.writeDbgAbbrev(); |
| 4117 | 4253 | // // for debug info and ranges, the address is always 0, |
| 4118 | 4254 | // // as locations are always offsets relative to 'code' section. |
| ... | ... | @@ -4121,7 +4257,7 @@ fn writeToFile( |
| 4121 | 4257 | // try dwarf.writeDbgLineHeader(); |
| 4122 | 4258 | // } |
| 4123 | 4259 | |
| 4124 | var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator); | |
| 4260 | var debug_bytes = std.ArrayList(u8).init(gpa); | |
| 4125 | 4261 | defer debug_bytes.deinit(); |
| 4126 | 4262 | |
| 4127 | 4263 | const DebugSection = struct { |
| ... | ... | @@ -4299,6 +4435,8 @@ fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []con |
| 4299 | 4435 | } |
| 4300 | 4436 | |
| 4301 | 4437 | fn 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; | |
| 4302 | 4440 | const Name = struct { |
| 4303 | 4441 | index: u32, |
| 4304 | 4442 | name: []const u8, |
| ... | ... | @@ -4337,7 +4475,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem |
| 4337 | 4475 | for (wasm.data_segments.keys()) |key| { |
| 4338 | 4476 | // bss section is not emitted when this condition holds true, so we also |
| 4339 | 4477 | // 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; | |
| 4341 | 4479 | segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key }); |
| 4342 | 4480 | data_segment_index += 1; |
| 4343 | 4481 | } |
| ... | ... | @@ -4362,8 +4500,10 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem |
| 4362 | 4500 | } |
| 4363 | 4501 | |
| 4364 | 4502 | fn emitNameSubsection(wasm: *Wasm, section_id: std.wasm.NameSubsection, names: anytype, writer: anytype) !void { |
| 4503 | const gpa = wasm.base.comp.gpa; | |
| 4504 | ||
| 4365 | 4505 | // 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); | |
| 4367 | 4507 | defer section_list.deinit(); |
| 4368 | 4508 | const sub_writer = section_list.writer(); |
| 4369 | 4509 | |
| ... | ... | @@ -4441,26 +4581,30 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void { |
| 4441 | 4581 | } |
| 4442 | 4582 | } |
| 4443 | 4583 | |
| 4444 | fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void { | |
| 4584 | fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !void { | |
| 4445 | 4585 | const tracy = trace(@src()); |
| 4446 | 4586 | defer tracy.end(); |
| 4447 | 4587 | |
| 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; | |
| 4451 | 4593 | |
| 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}); | |
| 4454 | 4598 | |
| 4455 | 4599 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 4456 | 4600 | // 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); | |
| 4459 | 4603 | |
| 4460 | 4604 | 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.? }); | |
| 4462 | 4606 | } else { |
| 4463 | break :blk wasm.base.intermediary_basename.?; | |
| 4607 | break :blk wasm.base.zcu_object_sub_path.?; | |
| 4464 | 4608 | } |
| 4465 | 4609 | } else null; |
| 4466 | 4610 | |
| ... | ... | @@ -4469,23 +4613,21 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4469 | 4613 | sub_prog_node.context.refresh(); |
| 4470 | 4614 | defer sub_prog_node.end(); |
| 4471 | 4615 | |
| 4472 | const is_obj = wasm.base.options.output_mode == .Obj; | |
| 4616 | const is_obj = comp.config.output_mode == .Obj; | |
| 4473 | 4617 | const compiler_rt_path: ?[]const u8 = blk: { |
| 4474 | 4618 | if (comp.compiler_rt_lib) |lib| break :blk lib.full_object_path; |
| 4475 | 4619 | if (comp.compiler_rt_obj) |obj| break :blk obj.full_object_path; |
| 4476 | 4620 | break :blk null; |
| 4477 | 4621 | }; |
| 4478 | 4622 | |
| 4479 | const target = wasm.base.options.target; | |
| 4480 | ||
| 4481 | 4623 | const id_symlink_basename = "lld.id"; |
| 4482 | 4624 | |
| 4483 | 4625 | 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(); | |
| 4485 | 4627 | |
| 4486 | 4628 | var digest: [Cache.hex_digest_len]u8 = undefined; |
| 4487 | 4629 | |
| 4488 | if (!wasm.base.options.disable_lld_caching) { | |
| 4630 | if (!wasm.base.disable_lld_caching) { | |
| 4489 | 4631 | man = comp.cache_parent.obtain(); |
| 4490 | 4632 | |
| 4491 | 4633 | // 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) ! |
| 4493 | 4635 | |
| 4494 | 4636 | comptime assert(Compilation.link_hash_implementation_version == 10); |
| 4495 | 4637 | |
| 4496 | for (wasm.base.options.objects) |obj| { | |
| 4638 | for (comp.objects) |obj| { | |
| 4497 | 4639 | _ = try man.addFile(obj.path, null); |
| 4498 | 4640 | man.hash.add(obj.must_link); |
| 4499 | 4641 | } |
| ... | ... | @@ -4502,20 +4644,20 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4502 | 4644 | } |
| 4503 | 4645 | try man.addOptionalFile(module_obj_path); |
| 4504 | 4646 | 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); | |
| 4517 | 4659 | // 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| { | |
| 4519 | 4661 | man.hash.addBytes(symbol_name); |
| 4520 | 4662 | } |
| 4521 | 4663 | |
| ... | ... | @@ -4553,8 +4695,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4553 | 4695 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 4554 | 4696 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 4555 | 4697 | 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; | |
| 4558 | 4700 | |
| 4559 | 4701 | if (comp.c_object_table.count() != 0) |
| 4560 | 4702 | 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) ! |
| 4573 | 4715 | } |
| 4574 | 4716 | } else { |
| 4575 | 4717 | // 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); | |
| 4577 | 4719 | defer argv.deinit(); |
| 4578 | 4720 | // We will invoke ourselves as a child process to gain access to LLD. |
| 4579 | 4721 | // 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) ! |
| 4582 | 4724 | try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); |
| 4583 | 4725 | try argv.append("--error-limit=0"); |
| 4584 | 4726 | |
| 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) { | |
| 4587 | 4729 | .Debug => {}, |
| 4588 | 4730 | .ReleaseSmall => try argv.append("-O2"), |
| 4589 | 4731 | .ReleaseFast, .ReleaseSafe => try argv.append("-O3"), |
| 4590 | 4732 | } |
| 4591 | 4733 | } |
| 4592 | 4734 | |
| 4593 | if (wasm.base.options.import_memory) { | |
| 4735 | if (import_memory) { | |
| 4594 | 4736 | try argv.append("--import-memory"); |
| 4595 | 4737 | } |
| 4596 | 4738 | |
| 4597 | if (wasm.base.options.export_memory) { | |
| 4739 | if (export_memory) { | |
| 4598 | 4740 | try argv.append("--export-memory"); |
| 4599 | 4741 | } |
| 4600 | 4742 | |
| 4601 | if (wasm.base.options.import_table) { | |
| 4602 | assert(!wasm.base.options.export_table); | |
| 4743 | if (wasm.import_table) { | |
| 4744 | assert(!wasm.export_table); | |
| 4603 | 4745 | try argv.append("--import-table"); |
| 4604 | 4746 | } |
| 4605 | 4747 | |
| 4606 | if (wasm.base.options.export_table) { | |
| 4607 | assert(!wasm.base.options.import_table); | |
| 4748 | if (wasm.export_table) { | |
| 4749 | assert(!wasm.import_table); | |
| 4608 | 4750 | try argv.append("--export-table"); |
| 4609 | 4751 | } |
| 4610 | 4752 | |
| 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"); | |
| 4617 | 4757 | } |
| 4618 | 4758 | |
| 4619 | if (wasm.base.options.strip) { | |
| 4759 | if (comp.config.debug_format == .strip) { | |
| 4620 | 4760 | try argv.append("-s"); |
| 4621 | 4761 | } |
| 4622 | 4762 | |
| 4623 | if (wasm.base.options.initial_memory) |initial_memory| { | |
| 4763 | if (wasm.initial_memory) |initial_memory| { | |
| 4624 | 4764 | const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory}); |
| 4625 | 4765 | try argv.append(arg); |
| 4626 | 4766 | } |
| 4627 | 4767 | |
| 4628 | if (wasm.base.options.max_memory) |max_memory| { | |
| 4768 | if (wasm.max_memory) |max_memory| { | |
| 4629 | 4769 | const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory}); |
| 4630 | 4770 | try argv.append(arg); |
| 4631 | 4771 | } |
| 4632 | 4772 | |
| 4633 | if (wasm.base.options.shared_memory) { | |
| 4773 | if (shared_memory) { | |
| 4634 | 4774 | try argv.append("--shared-memory"); |
| 4635 | 4775 | } |
| 4636 | 4776 | |
| 4637 | if (wasm.base.options.global_base) |global_base| { | |
| 4777 | if (wasm.global_base) |global_base| { | |
| 4638 | 4778 | const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base}); |
| 4639 | 4779 | try argv.append(arg); |
| 4640 | 4780 | } else { |
| ... | ... | @@ -4646,42 +4786,39 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4646 | 4786 | } |
| 4647 | 4787 | |
| 4648 | 4788 | // 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| { | |
| 4650 | 4790 | const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}); |
| 4651 | 4791 | try argv.append(arg); |
| 4652 | 4792 | } |
| 4653 | 4793 | |
| 4654 | if (wasm.base.options.rdynamic) { | |
| 4794 | if (comp.config.rdynamic) { | |
| 4655 | 4795 | try argv.append("--export-dynamic"); |
| 4656 | 4796 | } |
| 4657 | 4797 | |
| 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 }); | |
| 4661 | 4800 | } else { |
| 4662 | 4801 | try argv.append("--no-entry"); |
| 4663 | 4802 | } |
| 4664 | 4803 | |
| 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 | }); | |
| 4671 | 4808 | |
| 4672 | if (wasm.base.options.import_symbols) { | |
| 4809 | if (wasm.import_symbols) { | |
| 4673 | 4810 | try argv.append("--allow-undefined"); |
| 4674 | 4811 | } |
| 4675 | 4812 | |
| 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) { | |
| 4677 | 4814 | try argv.append("--shared"); |
| 4678 | 4815 | } |
| 4679 | if (wasm.base.options.pie) { | |
| 4816 | if (comp.config.pie) { | |
| 4680 | 4817 | try argv.append("--pie"); |
| 4681 | 4818 | } |
| 4682 | 4819 | |
| 4683 | 4820 | // XXX - TODO: add when wasm-ld supports --build-id. |
| 4684 | // if (wasm.base.options.build_id) { | |
| 4821 | // if (wasm.base.build_id) { | |
| 4685 | 4822 | // try argv.append("--build-id=tree"); |
| 4686 | 4823 | // } |
| 4687 | 4824 | |
| ... | ... | @@ -4692,26 +4829,25 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4692 | 4829 | } |
| 4693 | 4830 | |
| 4694 | 4831 | 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); | |
| 4697 | 4834 | 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| { | |
| 4700 | 4836 | try argv.append(try comp.get_libc_crt_file( |
| 4701 | 4837 | arena, |
| 4702 | 4838 | wasi_libc.emulatedLibCRFileLibName(crt_file), |
| 4703 | 4839 | )); |
| 4704 | 4840 | } |
| 4705 | 4841 | |
| 4706 | if (wasm.base.options.link_libc) { | |
| 4842 | if (comp.config.link_libc) { | |
| 4707 | 4843 | try argv.append(try comp.get_libc_crt_file( |
| 4708 | 4844 | arena, |
| 4709 | wasi_libc.execModelCrtFileFullName(wasm.base.options.wasi_exec_model), | |
| 4845 | wasi_libc.execModelCrtFileFullName(comp.config.wasi_exec_model), | |
| 4710 | 4846 | )); |
| 4711 | 4847 | try argv.append(try comp.get_libc_crt_file(arena, "libc.a")); |
| 4712 | 4848 | } |
| 4713 | 4849 | |
| 4714 | if (wasm.base.options.link_libcpp) { | |
| 4850 | if (comp.config.link_libcpp) { | |
| 4715 | 4851 | try argv.append(comp.libcxx_static_lib.?.full_object_path); |
| 4716 | 4852 | try argv.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 4717 | 4853 | } |
| ... | ... | @@ -4720,7 +4856,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4720 | 4856 | |
| 4721 | 4857 | // Positional arguments to the linker such as object files. |
| 4722 | 4858 | var whole_archive = false; |
| 4723 | for (wasm.base.options.objects) |obj| { | |
| 4859 | for (comp.objects) |obj| { | |
| 4724 | 4860 | if (obj.must_link and !whole_archive) { |
| 4725 | 4861 | try argv.append("-whole-archive"); |
| 4726 | 4862 | whole_archive = true; |
| ... | ... | @@ -4742,9 +4878,9 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4742 | 4878 | try argv.append(p); |
| 4743 | 4879 | } |
| 4744 | 4880 | |
| 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) | |
| 4748 | 4884 | { |
| 4749 | 4885 | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 4750 | 4886 | } |
| ... | ... | @@ -4753,7 +4889,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4753 | 4889 | try argv.append(p); |
| 4754 | 4890 | } |
| 4755 | 4891 | |
| 4756 | if (wasm.base.options.verbose_link) { | |
| 4892 | if (comp.verbose_link) { | |
| 4757 | 4893 | // Skip over our own name so that the LLD linker name is the first argv item. |
| 4758 | 4894 | Compilation.dump_argv(argv.items[1..]); |
| 4759 | 4895 | } |
| ... | ... | @@ -4828,7 +4964,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4828 | 4964 | // it, and then can react to that in the same way as trying to run an ELF file |
| 4829 | 4965 | // from a foreign CPU architecture. |
| 4830 | 4966 | if (fs.has_executable_bit and target.os.tag == .wasi and |
| 4831 | wasm.base.options.output_mode == .Exe) | |
| 4967 | comp.config.output_mode == .Exe) | |
| 4832 | 4968 | { |
| 4833 | 4969 | // TODO: what's our strategy for reporting linker errors from this function? |
| 4834 | 4970 | // 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) ! |
| 4838 | 4974 | } |
| 4839 | 4975 | } |
| 4840 | 4976 | |
| 4841 | if (!wasm.base.options.disable_lld_caching) { | |
| 4977 | if (!wasm.base.disable_lld_caching) { | |
| 4842 | 4978 | // Update the file with the digest. If it fails we can continue; it only |
| 4843 | 4979 | // means that the next invocation will have an unnecessary cache miss. |
| 4844 | 4980 | Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| { |
| ... | ... | @@ -5089,10 +5225,13 @@ fn emitDataRelocations( |
| 5089 | 5225 | } |
| 5090 | 5226 | |
| 5091 | 5227 | fn hasPassiveInitializationSegments(wasm: *const Wasm) bool { |
| 5228 | const comp = wasm.base.comp; | |
| 5229 | const import_memory = comp.config.import_memory; | |
| 5230 | ||
| 5092 | 5231 | var it = wasm.data_segments.iterator(); |
| 5093 | 5232 | while (it.next()) |entry| { |
| 5094 | 5233 | 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.*)) { | |
| 5096 | 5235 | return true; |
| 5097 | 5236 | } |
| 5098 | 5237 | } |
| ... | ... | @@ -5113,14 +5252,15 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 { |
| 5113 | 5252 | if (wasm.getTypeIndex(func_type)) |index| { |
| 5114 | 5253 | return index; |
| 5115 | 5254 | } |
| 5255 | const gpa = wasm.base.comp.gpa; | |
| 5116 | 5256 | |
| 5117 | 5257 | // 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, .{ | |
| 5124 | 5264 | .params = params, |
| 5125 | 5265 | .returns = returns, |
| 5126 | 5266 | }); |
| ... | ... | @@ -5131,9 +5271,10 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 { |
| 5131 | 5271 | /// Asserts declaration has an associated `Atom`. |
| 5132 | 5272 | /// Returns the index into the list of types. |
| 5133 | 5273 | pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 { |
| 5274 | const gpa = wasm.base.comp.gpa; | |
| 5134 | 5275 | const atom_index = wasm.decls.get(decl_index).?; |
| 5135 | 5276 | 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); | |
| 5137 | 5278 | return index; |
| 5138 | 5279 | } |
| 5139 | 5280 | |
| ... | ... | @@ -5142,19 +5283,20 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s |
| 5142 | 5283 | fn markReferences(wasm: *Wasm) !void { |
| 5143 | 5284 | const tracy = trace(@src()); |
| 5144 | 5285 | 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; | |
| 5147 | 5289 | |
| 5148 | 5290 | for (wasm.resolved_symbols.keys()) |sym_loc| { |
| 5149 | 5291 | 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) { | |
| 5151 | 5293 | try wasm.mark(sym_loc); |
| 5152 | 5294 | continue; |
| 5153 | 5295 | } |
| 5154 | 5296 | |
| 5155 | 5297 | // Debug sections may require to be parsed and marked when it contains |
| 5156 | 5298 | // 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) { | |
| 5158 | 5300 | const file = sym_loc.file orelse continue; // Incremental debug info is done independently |
| 5159 | 5301 | const object = &wasm.objects.items[file]; |
| 5160 | 5302 | const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm); |
| ... | ... | @@ -5200,3 +5342,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void { |
| 5200 | 5342 | try wasm.mark(target_loc.finalLoc(wasm)); |
| 5201 | 5343 | } |
| 5202 | 5344 | } |
| 5345 | ||
| 5346 | fn 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 { |
| 883 | 883 | |
| 884 | 884 | /// Parses an object file into atoms, for code and data sections |
| 885 | 885 | pub 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; | |
| 886 | 888 | const symbol = &object.symtable[symbol_index]; |
| 887 | 889 | const relocatable_data: RelocatableData = switch (symbol.tag) { |
| 888 | 890 | .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 |
| 900 | 902 | }; |
| 901 | 903 | const final_index = try wasm.getMatchingSegment(object_index, symbol_index); |
| 902 | 904 | 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); | |
| 904 | 906 | atom.* = Atom.empty; |
| 905 | 907 | try wasm.appendAtomAtIndex(final_index, atom_index); |
| 906 | 908 | |
| ... | ... | @@ -910,7 +912,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 910 | 912 | atom.alignment = relocatable_data.getAlignment(object); |
| 911 | 913 | atom.code = std.ArrayListUnmanaged(u8).fromOwnedSlice(relocatable_data.data[0..relocatable_data.size]); |
| 912 | 914 | 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); | |
| 914 | 916 | const segment: *Wasm.Segment = &wasm.segments.items[final_index]; |
| 915 | 917 | if (relocatable_data.type == .data) { //code section and custom sections are 1-byte aligned |
| 916 | 918 | segment.alignment = segment.alignment.max(atom.alignment); |
| ... | ... | @@ -927,7 +929,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 927 | 929 | .R_WASM_TABLE_INDEX_SLEB, |
| 928 | 930 | .R_WASM_TABLE_INDEX_SLEB64, |
| 929 | 931 | => { |
| 930 | try wasm.function_table.put(wasm.base.allocator, .{ | |
| 932 | try wasm.function_table.put(gpa, .{ | |
| 931 | 933 | .file = object_index, |
| 932 | 934 | .index = reloc.index, |
| 933 | 935 | }, 0); |
| ... | ... | @@ -938,7 +940,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 938 | 940 | const sym = object.symtable[reloc.index]; |
| 939 | 941 | if (sym.tag != .global) { |
| 940 | 942 | try wasm.got_symbols.append( |
| 941 | wasm.base.allocator, | |
| 943 | gpa, | |
| 942 | 944 | .{ .file = object_index, .index = reloc.index }, |
| 943 | 945 | ); |
| 944 | 946 | } |
src/main.zig+1582-1315| ... | ... | @@ -21,7 +21,6 @@ const introspect = @import("introspect.zig"); |
| 21 | 21 | const EnvVar = introspect.EnvVar; |
| 22 | 22 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 23 | 23 | const wasi_libc = @import("wasi_libc.zig"); |
| 24 | const BuildId = std.Build.CompileStep.BuildId; | |
| 25 | 24 | const Cache = std.Build.Cache; |
| 26 | 25 | const target_util = @import("target.zig"); |
| 27 | 26 | const crash_report = @import("crash_report.zig"); |
| ... | ... | @@ -88,13 +87,15 @@ const normal_usage = |
| 88 | 87 | \\ fetch Copy a package into global cache and print its hash |
| 89 | 88 | \\ init Initialize a Zig package in the current directory |
| 90 | 89 | \\ |
| 91 | \\ ast-check Look for simple compile errors in any set of files | |
| 92 | 90 | \\ build-exe Create executable from source or object files |
| 93 | 91 | \\ build-lib Create library from source or object files |
| 94 | 92 | \\ build-obj Create object from source or object files |
| 95 | \\ fmt Reformat Zig source into canonical form | |
| 93 | \\ test Perform unit testing | |
| 96 | 94 | \\ 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 | |
| 98 | 99 | \\ translate-c Convert C code to Zig code |
| 99 | 100 | \\ |
| 100 | 101 | \\ ar Use Zig as a drop-in archiver |
| ... | ... | @@ -270,8 +271,6 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 270 | 271 | } |
| 271 | 272 | } |
| 272 | 273 | |
| 273 | defer log_scopes.deinit(gpa); | |
| 274 | ||
| 275 | 274 | const cmd = args[1]; |
| 276 | 275 | const cmd_args = args[2..]; |
| 277 | 276 | if (mem.eql(u8, cmd, "build-exe")) { |
| ... | ... | @@ -322,13 +321,14 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 322 | 321 | } else if (mem.eql(u8, cmd, "init")) { |
| 323 | 322 | return cmdInit(gpa, arena, cmd_args); |
| 324 | 323 | } else if (mem.eql(u8, cmd, "targets")) { |
| 325 | const info = try detectNativeTargetInfo(.{}); | |
| 324 | const host = resolveTargetQueryOrFatal(.{}); | |
| 326 | 325 | 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); | |
| 328 | 327 | } else if (mem.eql(u8, cmd, "version")) { |
| 329 | 328 | 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) | |
| 332 | 332 | return verifyLibcxxCorrectlyLinked(); |
| 333 | 333 | } else if (mem.eql(u8, cmd, "env")) { |
| 334 | 334 | verifyLibcxxCorrectlyLinked(); |
| ... | ... | @@ -404,37 +404,69 @@ const usage_build_generic = |
| 404 | 404 | \\ --global-cache-dir [path] Override the global cache directory |
| 405 | 405 | \\ --zig-lib-dir [path] Override path to Zig installation lib directory |
| 406 | 406 | \\ |
| 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: | |
| 408 | 444 | \\ -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 | |
| 409 | 460 | \\ -mcpu [cpu] Specify target CPU and feature set |
| 410 | 461 | \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses |
| 411 | 462 | \\ small|kernel| |
| 412 | 463 | \\ medium|large] |
| 413 | \\ -x language Treat subsequent input files as having type <language> | |
| 414 | 464 | \\ -mred-zone Force-enable the "red-zone" |
| 415 | 465 | \\ -mno-red-zone Force-disable the "red-zone" |
| 416 | 466 | \\ -fomit-frame-pointer Omit the stack frame pointer |
| 417 | 467 | \\ -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 | |
| 432 | 468 | \\ -fPIC Force-enable Position Independent Code |
| 433 | 469 | \\ -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 | |
| 438 | 470 | \\ -fstack-check Enable stack probing in unsafe builds |
| 439 | 471 | \\ -fno-stack-check Disable stack probing in safe builds |
| 440 | 472 | \\ -fstack-protector Enable stack protection in unsafe builds |
| ... | ... | @@ -445,47 +477,18 @@ const usage_build_generic = |
| 445 | 477 | \\ -fno-valgrind Omit valgrind client requests in debug builds |
| 446 | 478 | \\ -fsanitize-thread Enable Thread Sanitizer |
| 447 | 479 | \\ -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 | |
| 450 | 480 | \\ -funwind-tables Always produce unwind table entries for all functions |
| 451 | 481 | \\ -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 | |
| 460 | 482 | \\ -ferror-tracing Enable error tracing in ReleaseFast mode |
| 461 | 483 | \\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe mode |
| 462 | 484 | \\ -fsingle-threaded Code assumes there is only one thread |
| 463 | 485 | \\ -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 | |
| 470 | 486 | \\ -fstrip Omit debug symbols |
| 471 | 487 | \\ -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 | |
| 484 | 488 | \\ -idirafter [dir] Add directory to AFTER include search path |
| 485 | 489 | \\ -isystem [dir] Add directory to SYSTEM include search path |
| 486 | 490 | \\ -I[dir] Add directory to include search path |
| 487 | 491 | \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted) |
| 488 | \\ --libc [file] Provide a file which specifies libc paths | |
| 489 | 492 | \\ -cflags [flags] -- Set extra flags for the next positional C source files |
| 490 | 493 | \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files |
| 491 | 494 | \\ -rcincludes=[type] Set the type of includes to use when compiling .rc source files |
| ... | ... | @@ -493,26 +496,8 @@ const usage_build_generic = |
| 493 | 496 | \\ msvc Use msvc include paths (must be present on the system) |
| 494 | 497 | \\ gnu Use mingw include paths (distributed with Zig) |
| 495 | 498 | \\ 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 | |
| 498 | 499 | \\ |
| 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: | |
| 516 | 501 | \\ -T[script], --script [script] Use a custom linker script |
| 517 | 502 | \\ --version-script [path] Provide a version .map file |
| 518 | 503 | \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) |
| ... | ... | @@ -529,7 +514,6 @@ const usage_build_generic = |
| 529 | 514 | \\ -fcompiler-rt Always include compiler-rt symbols in output |
| 530 | 515 | \\ -fno-compiler-rt Prevent including compiler-rt symbols in output |
| 531 | 516 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 532 | \\ -rpath [path] Add directory to the runtime library search path | |
| 533 | 517 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library |
| 534 | 518 | \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library |
| 535 | 519 | \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries |
| ... | ... | @@ -566,11 +550,6 @@ const usage_build_generic = |
| 566 | 550 | \\ --subsystem [subsystem] (Windows) /SUBSYSTEM:<subsystem> to the linker |
| 567 | 551 | \\ --stack [size] Override default stack size |
| 568 | 552 | \\ --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 | |
| 574 | 553 | \\ -install_name=[value] (Darwin) add dylib's install name |
| 575 | 554 | \\ --entitlements [path] (Darwin) add path to entitlements file for embedding in code signature |
| 576 | 555 | \\ -pagezero_size [value] (Darwin) size of the __PAGEZERO segment in hexadecimal notation |
| ... | ... | @@ -587,6 +566,30 @@ const usage_build_generic = |
| 587 | 566 | \\ --max-memory=[bytes] (WebAssembly) maximum size of the linear memory |
| 588 | 567 | \\ --shared-memory (WebAssembly) use shared linear memory |
| 589 | 568 | \\ --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 | |
| 590 | 593 | \\ --export=[value] (WebAssembly) Force a symbol to be exported |
| 591 | 594 | \\ |
| 592 | 595 | \\Test Options: |
| ... | ... | @@ -758,9 +761,24 @@ const Framework = struct { |
| 758 | 761 | }; |
| 759 | 762 | |
| 760 | 763 | const 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 | }; | |
| 764 | 782 | }; |
| 765 | 783 | |
| 766 | 784 | fn buildOutputType( |
| ... | ... | @@ -769,17 +787,11 @@ fn buildOutputType( |
| 769 | 787 | all_args: []const []const u8, |
| 770 | 788 | arg_mode: ArgMode, |
| 771 | 789 | ) !void { |
| 772 | var color: Color = .auto; | |
| 773 | var optimize_mode: std.builtin.OptimizeMode = .Debug; | |
| 774 | 790 | 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; | |
| 778 | 791 | var root_src_file: ?[]const u8 = null; |
| 779 | 792 | var version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 }; |
| 780 | 793 | var have_version = false; |
| 781 | 794 | var compatibility_version: ?std.SemanticVersion = null; |
| 782 | var strip: ?bool = null; | |
| 783 | 795 | var formatted_panics: ?bool = null; |
| 784 | 796 | var function_sections = false; |
| 785 | 797 | var data_sections = false; |
| ... | ... | @@ -807,54 +819,29 @@ fn buildOutputType( |
| 807 | 819 | var emit_docs: Emit = .no; |
| 808 | 820 | var emit_implib: Emit = .yes_default_path; |
| 809 | 821 | var emit_implib_arg_provided = false; |
| 810 | var target_arch_os_abi: []const u8 = "native"; | |
| 822 | var target_arch_os_abi: ?[]const u8 = null; | |
| 811 | 823 | 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; | |
| 815 | 824 | var emit_h: Emit = .no; |
| 816 | 825 | 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; | |
| 834 | 826 | var want_compiler_rt: ?bool = null; |
| 835 | var rdynamic: bool = false; | |
| 836 | 827 | var linker_script: ?[]const u8 = null; |
| 837 | 828 | var version_script: ?[]const u8 = null; |
| 838 | 829 | var disable_c_depfile = false; |
| 839 | var linker_sort_section: ?link.SortSection = null; | |
| 830 | var linker_sort_section: ?link.File.Elf.SortSection = null; | |
| 840 | 831 | 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; | |
| 842 | 833 | var linker_allow_shlib_undefined: ?bool = null; |
| 843 | 834 | var linker_bind_global_refs_locally: ?bool = null; |
| 844 | var linker_import_memory: ?bool = null; | |
| 845 | var linker_export_memory: ?bool = null; | |
| 846 | 835 | var linker_import_symbols: bool = false; |
| 847 | 836 | var linker_import_table: bool = false; |
| 848 | 837 | var linker_export_table: bool = false; |
| 849 | var linker_force_entry: ?bool = null; | |
| 850 | 838 | var linker_initial_memory: ?u64 = null; |
| 851 | 839 | var linker_max_memory: ?u64 = null; |
| 852 | var linker_shared_memory: bool = false; | |
| 853 | 840 | var linker_global_base: ?u64 = null; |
| 854 | 841 | var linker_print_gc_sections: bool = false; |
| 855 | 842 | var linker_print_icf_sections: bool = false; |
| 856 | 843 | var linker_print_map: bool = false; |
| 857 | var linker_opt_bisect_limit: i32 = -1; | |
| 844 | var llvm_opt_bisect_limit: c_int = -1; | |
| 858 | 845 | var linker_z_nocopyreloc = false; |
| 859 | 846 | var linker_z_nodelete = false; |
| 860 | 847 | var linker_z_notext = false; |
| ... | ... | @@ -867,25 +854,17 @@ fn buildOutputType( |
| 867 | 854 | var linker_tsaware = false; |
| 868 | 855 | var linker_nxcompat = false; |
| 869 | 856 | var linker_dynamicbase = true; |
| 870 | var linker_optimization: ?u8 = null; | |
| 857 | var linker_optimization: ?[]const u8 = null; | |
| 871 | 858 | var linker_module_definition_file: ?[]const u8 = null; |
| 872 | var test_evented_io = false; | |
| 873 | 859 | var test_no_exec = false; |
| 874 | var entry: ?[]const u8 = null; | |
| 860 | var entry: Compilation.CreateOptions.Entry = .default; | |
| 875 | 861 | 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; | |
| 882 | 864 | var link_eh_frame_hdr = false; |
| 883 | 865 | var link_emit_relocs = false; |
| 884 | 866 | 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; | |
| 889 | 868 | var runtime_args_start: ?usize = null; |
| 890 | 869 | var test_filter: ?[]const u8 = null; |
| 891 | 870 | var test_name_prefix: ?[]const u8 = null; |
| ... | ... | @@ -893,16 +872,14 @@ fn buildOutputType( |
| 893 | 872 | var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena); |
| 894 | 873 | var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); |
| 895 | 874 | var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); |
| 896 | var main_mod_path: ?[]const u8 = null; | |
| 897 | 875 | var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no; |
| 898 | 876 | 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; | |
| 902 | 879 | var enable_link_snapshots: bool = false; |
| 903 | 880 | var debug_incremental: bool = false; |
| 904 | 881 | var install_name: ?[]const u8 = null; |
| 905 | var hash_style: link.HashStyle = .both; | |
| 882 | var hash_style: link.File.Elf.HashStyle = .both; | |
| 906 | 883 | var entitlements: ?[]const u8 = null; |
| 907 | 884 | var pagezero_size: ?u64 = null; |
| 908 | 885 | var lib_search_strategy: SystemLib.SearchStrategy = .paths_first; |
| ... | ... | @@ -910,63 +887,103 @@ fn buildOutputType( |
| 910 | 887 | var headerpad_size: ?u32 = null; |
| 911 | 888 | var headerpad_max_install_names: bool = false; |
| 912 | 889 | var dead_strip_dylibs: bool = false; |
| 890 | var contains_res_file: bool = false; | |
| 913 | 891 | var reference_trace: ?u32 = null; |
| 914 | var error_tracing: ?bool = null; | |
| 915 | 892 | var pdb_out_path: ?[]const u8 = null; |
| 916 | var dwarf_format: ?std.dwarf.Format = null; | |
| 917 | 893 | 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); | |
| 928 | 894 | // 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) = .{}; | |
| 931 | 897 | 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); | |
| 934 | 898 | var rc_includes: Compilation.RcIncludes = .any; |
| 935 | var res_files = std.ArrayList(Compilation.LinkObject).init(arena); | |
| 936 | 899 | 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 | ||
| 940 | 907 | // null means replace with the test executable binary |
| 941 | 908 | 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 | ||
| 943 | 920 | // Contains every module specified via --mod. The dependencies are added |
| 944 | 921 | // 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 | }; | |
| 950 | 968 | |
| 951 | 969 | // before arg parsing, check for the NO_COLOR environment variable |
| 952 | 970 | // if it exists, default the color setting to .off |
| 953 | 971 | // explicit --color arguments will still override this setting. |
| 954 | 972 | // 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; | |
| 956 | 974 | |
| 957 | 975 | switch (arg_mode) { |
| 958 | 976 | .build, .translate_c, .zig_test, .run => { |
| 959 | var optimize_mode_string: ?[]const u8 = null; | |
| 960 | 977 | switch (arg_mode) { |
| 961 | 978 | .build => |m| { |
| 962 | output_mode = m; | |
| 979 | create_module.opts.output_mode = m; | |
| 963 | 980 | }, |
| 964 | 981 | .translate_c => { |
| 965 | 982 | emit_bin = .no; |
| 966 | output_mode = .Obj; | |
| 983 | create_module.opts.output_mode = .Obj; | |
| 967 | 984 | }, |
| 968 | 985 | .zig_test, .run => { |
| 969 | output_mode = .Exe; | |
| 986 | create_module.opts.output_mode = .Exe; | |
| 970 | 987 | }, |
| 971 | 988 | else => unreachable, |
| 972 | 989 | } |
| ... | ... | @@ -977,9 +994,6 @@ fn buildOutputType( |
| 977 | 994 | .args = all_args[2..], |
| 978 | 995 | }; |
| 979 | 996 | |
| 980 | var cssan = ClangSearchSanitizer.init(gpa, &clang_argv); | |
| 981 | defer cssan.map.deinit(); | |
| 982 | ||
| 983 | 997 | var file_ext: ?Compilation.FileExt = null; |
| 984 | 998 | args_loop: while (args_iter.next()) |arg| { |
| 985 | 999 | if (mem.startsWith(u8, arg, "@")) { |
| ... | ... | @@ -1002,49 +1016,77 @@ fn buildOutputType( |
| 1002 | 1016 | } else { |
| 1003 | 1017 | fatal("unexpected end-of-parameter mark: --", .{}); |
| 1004 | 1018 | } |
| 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, | |
| 1020 | 1032 | }); |
| 1021 | 1033 | } |
| 1022 | 1034 | } |
| 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(); | |
| 1023 | 1042 | |
| 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, | |
| 1027 | 1048 | }); |
| 1028 | 1049 | } |
| 1029 | 1050 | |
| 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 = .{ | |
| 1032 | 1067 | .root = .{ |
| 1033 | 1068 | .root_dir = Cache.Directory.cwd(), |
| 1034 | 1069 | .sub_path = fs.path.dirname(root_src) orelse "", |
| 1035 | 1070 | }, |
| 1036 | 1071 | .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; | |
| 1048 | 1090 | } else if (mem.eql(u8, arg, "--error-limit")) { |
| 1049 | 1091 | const next_arg = args_iter.nextOrFatal(); |
| 1050 | 1092 | error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| { |
| ... | ... | @@ -1057,7 +1099,7 @@ fn buildOutputType( |
| 1057 | 1099 | fatal("expected -- after -cflags", .{}); |
| 1058 | 1100 | }; |
| 1059 | 1101 | if (mem.eql(u8, next_arg, "--")) break; |
| 1060 | try extra_cflags.append(next_arg); | |
| 1102 | try extra_cflags.append(arena, next_arg); | |
| 1061 | 1103 | } |
| 1062 | 1104 | } else if (mem.eql(u8, arg, "-rcincludes")) { |
| 1063 | 1105 | rc_includes = parseRcIncludes(args_iter.nextOrFatal()); |
| ... | ... | @@ -1070,12 +1112,12 @@ fn buildOutputType( |
| 1070 | 1112 | fatal("expected -- after -rcflags", .{}); |
| 1071 | 1113 | }; |
| 1072 | 1114 | if (mem.eql(u8, next_arg, "--")) break; |
| 1073 | try extra_rcflags.append(next_arg); | |
| 1115 | try extra_rcflags.append(arena, next_arg); | |
| 1074 | 1116 | } |
| 1075 | 1117 | } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) { |
| 1076 | want_structured_cfg = true; | |
| 1118 | mod_opts.structured_cfg = true; | |
| 1077 | 1119 | } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) { |
| 1078 | want_structured_cfg = false; | |
| 1120 | mod_opts.structured_cfg = false; | |
| 1079 | 1121 | } else if (mem.eql(u8, arg, "--color")) { |
| 1080 | 1122 | const next_arg = args_iter.next() orelse { |
| 1081 | 1123 | fatal("expected [auto|on|off] after --color", .{}); |
| ... | ... | @@ -1086,46 +1128,40 @@ fn buildOutputType( |
| 1086 | 1128 | } else if (mem.eql(u8, arg, "--subsystem")) { |
| 1087 | 1129 | subsystem = try parseSubSystem(args_iter.nextOrFatal()); |
| 1088 | 1130 | } else if (mem.eql(u8, arg, "-O")) { |
| 1089 | optimize_mode_string = args_iter.nextOrFatal(); | |
| 1131 | mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal()); | |
| 1090 | 1132 | } else if (mem.startsWith(u8, arg, "-fentry=")) { |
| 1091 | entry = arg["-fentry=".len..]; | |
| 1133 | entry = .{ .named = arg["-fentry=".len..] }; | |
| 1092 | 1134 | } 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(), {}); | |
| 1094 | 1136 | } 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()); | |
| 1099 | 1138 | } 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()); | |
| 1104 | 1140 | } else if (mem.eql(u8, arg, "--name")) { |
| 1105 | 1141 | provided_name = args_iter.nextOrFatal(); |
| 1106 | 1142 | if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?))) |
| 1107 | 1143 | fatal("invalid package name '{s}': cannot contain folder separators", .{provided_name.?}); |
| 1108 | 1144 | } 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()); | |
| 1110 | 1146 | } 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()); | |
| 1112 | 1148 | } 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()); | |
| 1114 | 1150 | } 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(), .{}); | |
| 1116 | 1152 | } 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 }); | |
| 1118 | 1154 | } 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 }); | |
| 1120 | 1156 | } else if (mem.eql(u8, arg, "-install_name")) { |
| 1121 | 1157 | install_name = args_iter.nextOrFatal(); |
| 1122 | 1158 | } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) { |
| 1123 | 1159 | 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 { | |
| 1125 | 1161 | fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param}); |
| 1126 | 1162 | }; |
| 1127 | 1163 | } 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; | |
| 1129 | 1165 | } else if (mem.eql(u8, arg, "-pagezero_size")) { |
| 1130 | 1166 | const next_arg = args_iter.nextOrFatal(); |
| 1131 | 1167 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| ... | ... | @@ -1168,7 +1204,7 @@ fn buildOutputType( |
| 1168 | 1204 | // We don't know whether this library is part of libc |
| 1169 | 1205 | // or libc++ until we resolve the target, so we append |
| 1170 | 1206 | // to the list for now. |
| 1171 | try system_libs.put(args_iter.nextOrFatal(), .{ | |
| 1207 | try create_module.system_libs.put(arena, args_iter.nextOrFatal(), .{ | |
| 1172 | 1208 | .needed = false, |
| 1173 | 1209 | .weak = false, |
| 1174 | 1210 | .preferred_mode = lib_preferred_mode, |
| ... | ... | @@ -1179,38 +1215,37 @@ fn buildOutputType( |
| 1179 | 1215 | mem.eql(u8, arg, "-needed_library")) |
| 1180 | 1216 | { |
| 1181 | 1217 | const next_arg = args_iter.nextOrFatal(); |
| 1182 | try system_libs.put(next_arg, .{ | |
| 1218 | try create_module.system_libs.put(arena, next_arg, .{ | |
| 1183 | 1219 | .needed = true, |
| 1184 | 1220 | .weak = false, |
| 1185 | 1221 | .preferred_mode = lib_preferred_mode, |
| 1186 | 1222 | .search_strategy = lib_search_strategy, |
| 1187 | 1223 | }); |
| 1188 | 1224 | } 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(), .{ | |
| 1190 | 1226 | .needed = false, |
| 1191 | 1227 | .weak = true, |
| 1192 | 1228 | .preferred_mode = lib_preferred_mode, |
| 1193 | 1229 | .search_strategy = lib_search_strategy, |
| 1194 | 1230 | }); |
| 1195 | 1231 | } 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() }); | |
| 1198 | 1233 | } 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); | |
| 1200 | 1235 | } 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); | |
| 1202 | 1237 | } 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); | |
| 1204 | 1239 | } 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); | |
| 1206 | 1241 | } else if (mem.eql(u8, arg, "-iframework")) { |
| 1207 | 1242 | 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 | |
| 1210 | 1245 | } else if (mem.eql(u8, arg, "-iframeworkwithsysroot")) { |
| 1211 | 1246 | 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 | |
| 1214 | 1249 | } else if (mem.eql(u8, arg, "--version")) { |
| 1215 | 1250 | const next_arg = args_iter.nextOrFatal(); |
| 1216 | 1251 | version = std.SemanticVersion.parse(next_arg) catch |err| { |
| ... | ... | @@ -1222,23 +1257,23 @@ fn buildOutputType( |
| 1222 | 1257 | } else if (mem.eql(u8, arg, "-mcpu")) { |
| 1223 | 1258 | target_mcpu = args_iter.nextOrFatal(); |
| 1224 | 1259 | } 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..]); | |
| 1226 | 1263 | } else if (mem.startsWith(u8, arg, "-ofmt=")) { |
| 1227 | target_ofmt = arg["-ofmt=".len..]; | |
| 1264 | create_module.object_format = arg["-ofmt=".len..]; | |
| 1228 | 1265 | } else if (mem.startsWith(u8, arg, "-mcpu=")) { |
| 1229 | 1266 | target_mcpu = arg["-mcpu=".len..]; |
| 1230 | } else if (mem.startsWith(u8, arg, "-mcmodel=")) { | |
| 1231 | machine_code_model = parseCodeModel(arg["-mcmodel=".len..]); | |
| 1232 | 1267 | } else if (mem.startsWith(u8, arg, "-O")) { |
| 1233 | optimize_mode_string = arg["-O".len..]; | |
| 1268 | mod_opts.optimize_mode = parseOptimizeMode(arg["-O".len..]); | |
| 1234 | 1269 | } else if (mem.eql(u8, arg, "--dynamic-linker")) { |
| 1235 | target_dynamic_linker = args_iter.nextOrFatal(); | |
| 1270 | create_module.dynamic_linker = args_iter.nextOrFatal(); | |
| 1236 | 1271 | } 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 }); | |
| 1240 | 1275 | } else if (mem.eql(u8, arg, "--libc")) { |
| 1241 | libc_paths_file = args_iter.nextOrFatal(); | |
| 1276 | create_module.libc_paths_file = args_iter.nextOrFatal(); | |
| 1242 | 1277 | } else if (mem.eql(u8, arg, "--test-filter")) { |
| 1243 | 1278 | test_filter = args_iter.nextOrFatal(); |
| 1244 | 1279 | } else if (mem.eql(u8, arg, "--test-name-prefix")) { |
| ... | ... | @@ -1258,7 +1293,7 @@ fn buildOutputType( |
| 1258 | 1293 | warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); |
| 1259 | 1294 | _ = args_iter.nextOrFatal(); |
| 1260 | 1295 | } else { |
| 1261 | try log_scopes.append(gpa, args_iter.nextOrFatal()); | |
| 1296 | try log_scopes.append(arena, args_iter.nextOrFatal()); | |
| 1262 | 1297 | } |
| 1263 | 1298 | } else if (mem.eql(u8, arg, "--listen")) { |
| 1264 | 1299 | const next_arg = args_iter.nextOrFatal(); |
| ... | ... | @@ -1298,7 +1333,7 @@ fn buildOutputType( |
| 1298 | 1333 | } else if (mem.eql(u8, arg, "--test-cmd-bin")) { |
| 1299 | 1334 | try test_exec_args.append(null); |
| 1300 | 1335 | } else if (mem.eql(u8, arg, "--test-evented-io")) { |
| 1301 | test_evented_io = true; | |
| 1336 | create_module.opts.test_evented_io = true; | |
| 1302 | 1337 | } else if (mem.eql(u8, arg, "--test-no-exec")) { |
| 1303 | 1338 | test_no_exec = true; |
| 1304 | 1339 | } else if (mem.eql(u8, arg, "-ftime-report")) { |
| ... | ... | @@ -1306,65 +1341,65 @@ fn buildOutputType( |
| 1306 | 1341 | } else if (mem.eql(u8, arg, "-fstack-report")) { |
| 1307 | 1342 | stack_report = true; |
| 1308 | 1343 | } else if (mem.eql(u8, arg, "-fPIC")) { |
| 1309 | want_pic = true; | |
| 1344 | mod_opts.pic = true; | |
| 1310 | 1345 | } else if (mem.eql(u8, arg, "-fno-PIC")) { |
| 1311 | want_pic = false; | |
| 1346 | mod_opts.pic = false; | |
| 1312 | 1347 | } else if (mem.eql(u8, arg, "-fPIE")) { |
| 1313 | want_pie = true; | |
| 1348 | create_module.opts.pie = true; | |
| 1314 | 1349 | } else if (mem.eql(u8, arg, "-fno-PIE")) { |
| 1315 | want_pie = false; | |
| 1350 | create_module.opts.pie = false; | |
| 1316 | 1351 | } else if (mem.eql(u8, arg, "-flto")) { |
| 1317 | want_lto = true; | |
| 1352 | create_module.opts.lto = true; | |
| 1318 | 1353 | } else if (mem.eql(u8, arg, "-fno-lto")) { |
| 1319 | want_lto = false; | |
| 1354 | create_module.opts.lto = false; | |
| 1320 | 1355 | } else if (mem.eql(u8, arg, "-funwind-tables")) { |
| 1321 | want_unwind_tables = true; | |
| 1356 | mod_opts.unwind_tables = true; | |
| 1322 | 1357 | } else if (mem.eql(u8, arg, "-fno-unwind-tables")) { |
| 1323 | want_unwind_tables = false; | |
| 1358 | mod_opts.unwind_tables = false; | |
| 1324 | 1359 | } else if (mem.eql(u8, arg, "-fstack-check")) { |
| 1325 | want_stack_check = true; | |
| 1360 | mod_opts.stack_check = true; | |
| 1326 | 1361 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { |
| 1327 | want_stack_check = false; | |
| 1362 | mod_opts.stack_check = false; | |
| 1328 | 1363 | } 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; | |
| 1330 | 1365 | } else if (mem.eql(u8, arg, "-fno-stack-protector")) { |
| 1331 | want_stack_protector = 0; | |
| 1366 | mod_opts.stack_protector = 0; | |
| 1332 | 1367 | } else if (mem.eql(u8, arg, "-mred-zone")) { |
| 1333 | want_red_zone = true; | |
| 1368 | mod_opts.red_zone = true; | |
| 1334 | 1369 | } else if (mem.eql(u8, arg, "-mno-red-zone")) { |
| 1335 | want_red_zone = false; | |
| 1370 | mod_opts.red_zone = false; | |
| 1336 | 1371 | } else if (mem.eql(u8, arg, "-fomit-frame-pointer")) { |
| 1337 | omit_frame_pointer = true; | |
| 1372 | mod_opts.omit_frame_pointer = true; | |
| 1338 | 1373 | } else if (mem.eql(u8, arg, "-fno-omit-frame-pointer")) { |
| 1339 | omit_frame_pointer = false; | |
| 1374 | mod_opts.omit_frame_pointer = false; | |
| 1340 | 1375 | } else if (mem.eql(u8, arg, "-fsanitize-c")) { |
| 1341 | want_sanitize_c = true; | |
| 1376 | mod_opts.sanitize_c = true; | |
| 1342 | 1377 | } else if (mem.eql(u8, arg, "-fno-sanitize-c")) { |
| 1343 | want_sanitize_c = false; | |
| 1378 | mod_opts.sanitize_c = false; | |
| 1344 | 1379 | } else if (mem.eql(u8, arg, "-fvalgrind")) { |
| 1345 | want_valgrind = true; | |
| 1380 | mod_opts.valgrind = true; | |
| 1346 | 1381 | } else if (mem.eql(u8, arg, "-fno-valgrind")) { |
| 1347 | want_valgrind = false; | |
| 1382 | mod_opts.valgrind = false; | |
| 1348 | 1383 | } else if (mem.eql(u8, arg, "-fsanitize-thread")) { |
| 1349 | want_tsan = true; | |
| 1384 | mod_opts.sanitize_thread = true; | |
| 1350 | 1385 | } else if (mem.eql(u8, arg, "-fno-sanitize-thread")) { |
| 1351 | want_tsan = false; | |
| 1386 | mod_opts.sanitize_thread = false; | |
| 1352 | 1387 | } else if (mem.eql(u8, arg, "-fllvm")) { |
| 1353 | use_llvm = true; | |
| 1388 | create_module.opts.use_llvm = true; | |
| 1354 | 1389 | } else if (mem.eql(u8, arg, "-fno-llvm")) { |
| 1355 | use_llvm = false; | |
| 1390 | create_module.opts.use_llvm = false; | |
| 1356 | 1391 | } else if (mem.eql(u8, arg, "-flibllvm")) { |
| 1357 | use_lib_llvm = true; | |
| 1392 | create_module.opts.use_lib_llvm = true; | |
| 1358 | 1393 | } else if (mem.eql(u8, arg, "-fno-libllvm")) { |
| 1359 | use_lib_llvm = false; | |
| 1394 | create_module.opts.use_lib_llvm = false; | |
| 1360 | 1395 | } else if (mem.eql(u8, arg, "-flld")) { |
| 1361 | use_lld = true; | |
| 1396 | create_module.opts.use_lld = true; | |
| 1362 | 1397 | } else if (mem.eql(u8, arg, "-fno-lld")) { |
| 1363 | use_lld = false; | |
| 1398 | create_module.opts.use_lld = false; | |
| 1364 | 1399 | } else if (mem.eql(u8, arg, "-fclang")) { |
| 1365 | use_clang = true; | |
| 1400 | create_module.opts.use_clang = true; | |
| 1366 | 1401 | } else if (mem.eql(u8, arg, "-fno-clang")) { |
| 1367 | use_clang = false; | |
| 1402 | create_module.opts.use_clang = false; | |
| 1368 | 1403 | } else if (mem.eql(u8, arg, "-freference-trace")) { |
| 1369 | 1404 | reference_trace = 256; |
| 1370 | 1405 | } else if (mem.startsWith(u8, arg, "-freference-trace=")) { |
| ... | ... | @@ -1375,11 +1410,11 @@ fn buildOutputType( |
| 1375 | 1410 | } else if (mem.eql(u8, arg, "-fno-reference-trace")) { |
| 1376 | 1411 | reference_trace = null; |
| 1377 | 1412 | } else if (mem.eql(u8, arg, "-ferror-tracing")) { |
| 1378 | error_tracing = true; | |
| 1413 | mod_opts.error_tracing = true; | |
| 1379 | 1414 | } else if (mem.eql(u8, arg, "-fno-error-tracing")) { |
| 1380 | error_tracing = false; | |
| 1415 | mod_opts.error_tracing = false; | |
| 1381 | 1416 | } else if (mem.eql(u8, arg, "-rdynamic")) { |
| 1382 | rdynamic = true; | |
| 1417 | create_module.opts.rdynamic = true; | |
| 1383 | 1418 | } else if (mem.eql(u8, arg, "-fsoname")) { |
| 1384 | 1419 | soname = .yes_default_value; |
| 1385 | 1420 | } else if (mem.startsWith(u8, arg, "-fsoname=")) { |
| ... | ... | @@ -1432,36 +1467,36 @@ fn buildOutputType( |
| 1432 | 1467 | emit_implib = .no; |
| 1433 | 1468 | emit_implib_arg_provided = true; |
| 1434 | 1469 | } else if (mem.eql(u8, arg, "-dynamic")) { |
| 1435 | link_mode = .Dynamic; | |
| 1470 | create_module.opts.link_mode = .Dynamic; | |
| 1436 | 1471 | lib_preferred_mode = .Dynamic; |
| 1437 | 1472 | lib_search_strategy = .mode_first; |
| 1438 | 1473 | } else if (mem.eql(u8, arg, "-static")) { |
| 1439 | link_mode = .Static; | |
| 1474 | create_module.opts.link_mode = .Static; | |
| 1440 | 1475 | lib_preferred_mode = .Static; |
| 1441 | 1476 | lib_search_strategy = .no_fallback; |
| 1442 | 1477 | } else if (mem.eql(u8, arg, "-fdll-export-fns")) { |
| 1443 | dll_export_fns = true; | |
| 1478 | create_module.opts.dll_export_fns = true; | |
| 1444 | 1479 | } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) { |
| 1445 | dll_export_fns = false; | |
| 1480 | create_module.opts.dll_export_fns = false; | |
| 1446 | 1481 | } else if (mem.eql(u8, arg, "--show-builtin")) { |
| 1447 | 1482 | show_builtin = true; |
| 1448 | 1483 | emit_bin = .no; |
| 1449 | 1484 | } else if (mem.eql(u8, arg, "-fstrip")) { |
| 1450 | strip = true; | |
| 1485 | mod_opts.strip = true; | |
| 1451 | 1486 | } else if (mem.eql(u8, arg, "-fno-strip")) { |
| 1452 | strip = false; | |
| 1487 | mod_opts.strip = false; | |
| 1453 | 1488 | } else if (mem.eql(u8, arg, "-gdwarf32")) { |
| 1454 | dwarf_format = .@"32"; | |
| 1489 | create_module.opts.debug_format = .{ .dwarf = .@"32" }; | |
| 1455 | 1490 | } else if (mem.eql(u8, arg, "-gdwarf64")) { |
| 1456 | dwarf_format = .@"64"; | |
| 1491 | create_module.opts.debug_format = .{ .dwarf = .@"64" }; | |
| 1457 | 1492 | } else if (mem.eql(u8, arg, "-fformatted-panics")) { |
| 1458 | 1493 | formatted_panics = true; |
| 1459 | 1494 | } else if (mem.eql(u8, arg, "-fno-formatted-panics")) { |
| 1460 | 1495 | formatted_panics = false; |
| 1461 | 1496 | } else if (mem.eql(u8, arg, "-fsingle-threaded")) { |
| 1462 | single_threaded = true; | |
| 1497 | mod_opts.single_threaded = true; | |
| 1463 | 1498 | } else if (mem.eql(u8, arg, "-fno-single-threaded")) { |
| 1464 | single_threaded = false; | |
| 1499 | mod_opts.single_threaded = false; | |
| 1465 | 1500 | } else if (mem.eql(u8, arg, "-ffunction-sections")) { |
| 1466 | 1501 | function_sections = true; |
| 1467 | 1502 | } else if (mem.eql(u8, arg, "-fno-function-sections")) { |
| ... | ... | @@ -1475,7 +1510,9 @@ fn buildOutputType( |
| 1475 | 1510 | } else if (mem.eql(u8, arg, "-fno-builtin")) { |
| 1476 | 1511 | no_builtin = true; |
| 1477 | 1512 | } 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) }); | |
| 1479 | 1516 | } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { |
| 1480 | 1517 | link_eh_frame_hdr = true; |
| 1481 | 1518 | } else if (mem.eql(u8, arg, "--dynamicbase")) { |
| ... | ... | @@ -1518,13 +1555,16 @@ fn buildOutputType( |
| 1518 | 1555 | fatal("unsupported linker extension flag: -z {s}", .{z_arg}); |
| 1519 | 1556 | } |
| 1520 | 1557 | } else if (mem.eql(u8, arg, "--import-memory")) { |
| 1521 | linker_import_memory = true; | |
| 1558 | create_module.opts.import_memory = true; | |
| 1522 | 1559 | } else if (mem.eql(u8, arg, "-fentry")) { |
| 1523 | linker_force_entry = true; | |
| 1560 | switch (entry) { | |
| 1561 | .default, .disabled => entry = .enabled, | |
| 1562 | .enabled, .named => {}, | |
| 1563 | } | |
| 1524 | 1564 | } else if (mem.eql(u8, arg, "-fno-entry")) { |
| 1525 | linker_force_entry = false; | |
| 1565 | entry = .disabled; | |
| 1526 | 1566 | } else if (mem.eql(u8, arg, "--export-memory")) { |
| 1527 | linker_export_memory = true; | |
| 1567 | create_module.opts.export_memory = true; | |
| 1528 | 1568 | } else if (mem.eql(u8, arg, "--import-symbols")) { |
| 1529 | 1569 | linker_import_symbols = true; |
| 1530 | 1570 | } else if (mem.eql(u8, arg, "--import-table")) { |
| ... | ... | @@ -1536,11 +1576,11 @@ fn buildOutputType( |
| 1536 | 1576 | } else if (mem.startsWith(u8, arg, "--max-memory=")) { |
| 1537 | 1577 | linker_max_memory = parseIntSuffix(arg, "--max-memory=".len); |
| 1538 | 1578 | } else if (mem.eql(u8, arg, "--shared-memory")) { |
| 1539 | linker_shared_memory = true; | |
| 1579 | create_module.opts.shared_memory = true; | |
| 1540 | 1580 | } else if (mem.startsWith(u8, arg, "--global-base=")) { |
| 1541 | 1581 | linker_global_base = parseIntSuffix(arg, "--global-base=".len); |
| 1542 | 1582 | } 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..]); | |
| 1544 | 1584 | } else if (mem.eql(u8, arg, "-Bsymbolic")) { |
| 1545 | 1585 | linker_bind_global_refs_locally = true; |
| 1546 | 1586 | } else if (mem.eql(u8, arg, "--gc-sections")) { |
| ... | ... | @@ -1551,7 +1591,7 @@ fn buildOutputType( |
| 1551 | 1591 | build_id = .fast; |
| 1552 | 1592 | } else if (mem.startsWith(u8, arg, "--build-id=")) { |
| 1553 | 1593 | const style = arg["--build-id=".len..]; |
| 1554 | build_id = BuildId.parse(style) catch |err| { | |
| 1594 | build_id = std.zig.BuildId.parse(style) catch |err| { | |
| 1555 | 1595 | fatal("unable to parse --build-id style '{s}': {s}", .{ |
| 1556 | 1596 | style, @errorName(err), |
| 1557 | 1597 | }); |
| ... | ... | @@ -1585,37 +1625,37 @@ fn buildOutputType( |
| 1585 | 1625 | } else if (mem.startsWith(u8, arg, "-T")) { |
| 1586 | 1626 | linker_script = arg[2..]; |
| 1587 | 1627 | } 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..]); | |
| 1589 | 1629 | } else if (mem.startsWith(u8, arg, "-F")) { |
| 1590 | try framework_dirs.append(arg[2..]); | |
| 1630 | try create_module.framework_dirs.append(arena, arg[2..]); | |
| 1591 | 1631 | } else if (mem.startsWith(u8, arg, "-l")) { |
| 1592 | 1632 | // We don't know whether this library is part of libc |
| 1593 | 1633 | // or libc++ until we resolve the target, so we append |
| 1594 | 1634 | // to the list for now. |
| 1595 | try system_libs.put(arg["-l".len..], .{ | |
| 1635 | try create_module.system_libs.put(arena, arg["-l".len..], .{ | |
| 1596 | 1636 | .needed = false, |
| 1597 | 1637 | .weak = false, |
| 1598 | 1638 | .preferred_mode = lib_preferred_mode, |
| 1599 | 1639 | .search_strategy = lib_search_strategy, |
| 1600 | 1640 | }); |
| 1601 | 1641 | } 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..], .{ | |
| 1603 | 1643 | .needed = true, |
| 1604 | 1644 | .weak = false, |
| 1605 | 1645 | .preferred_mode = lib_preferred_mode, |
| 1606 | 1646 | .search_strategy = lib_search_strategy, |
| 1607 | 1647 | }); |
| 1608 | 1648 | } 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..], .{ | |
| 1610 | 1650 | .needed = false, |
| 1611 | 1651 | .weak = true, |
| 1612 | 1652 | .preferred_mode = lib_preferred_mode, |
| 1613 | 1653 | .search_strategy = lib_search_strategy, |
| 1614 | 1654 | }); |
| 1615 | 1655 | } else if (mem.startsWith(u8, arg, "-D")) { |
| 1616 | try clang_argv.append(arg); | |
| 1656 | try cc_argv.append(arena, arg); | |
| 1617 | 1657 | } 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); | |
| 1619 | 1659 | } else if (mem.eql(u8, arg, "-x")) { |
| 1620 | 1660 | const lang = args_iter.nextOrFatal(); |
| 1621 | 1661 | if (mem.eql(u8, lang, "none")) { |
| ... | ... | @@ -1626,23 +1666,31 @@ fn buildOutputType( |
| 1626 | 1666 | fatal("language not recognized: '{s}'", .{lang}); |
| 1627 | 1667 | } |
| 1628 | 1668 | } 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..]); | |
| 1632 | 1670 | } else { |
| 1633 | 1671 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 1634 | 1672 | } |
| 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 | }, | |
| 1639 | 1685 | .manifest => { |
| 1640 | 1686 | if (manifest_file) |other| { |
| 1641 | 1687 | fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other }); |
| 1642 | 1688 | } else manifest_file = arg; |
| 1643 | 1689 | }, |
| 1644 | 1690 | .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, | |
| 1646 | 1694 | .src_path = arg, |
| 1647 | 1695 | .extra_flags = try arena.dupe([]const u8, extra_cflags.items), |
| 1648 | 1696 | // duped when parsing the args. |
| ... | ... | @@ -1650,7 +1698,9 @@ fn buildOutputType( |
| 1650 | 1698 | }); |
| 1651 | 1699 | }, |
| 1652 | 1700 | .rc => { |
| 1653 | try rc_source_files.append(.{ | |
| 1701 | try create_module.rc_source_files.append(arena, .{ | |
| 1702 | // Populated after module creation. | |
| 1703 | .owner = undefined, | |
| 1654 | 1704 | .src_path = arg, |
| 1655 | 1705 | .extra_flags = try arena.dupe([]const u8, extra_rcflags.items), |
| 1656 | 1706 | }); |
| ... | ... | @@ -1668,19 +1718,15 @@ fn buildOutputType( |
| 1668 | 1718 | }, |
| 1669 | 1719 | } |
| 1670 | 1720 | } |
| 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 | } | |
| 1675 | 1721 | }, |
| 1676 | 1722 | .cc, .cpp => { |
| 1677 | 1723 | if (build_options.only_c) unreachable; |
| 1678 | 1724 | |
| 1679 | 1725 | emit_h = .no; |
| 1680 | 1726 | 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; | |
| 1684 | 1730 | // Clang's driver enables this switch unconditionally. |
| 1685 | 1731 | // Disabling the emission of .eh_frame_hdr can unexpectedly break |
| 1686 | 1732 | // some functionality that depend on it, such as C++ exceptions and |
| ... | ... | @@ -1733,24 +1779,37 @@ fn buildOutputType( |
| 1733 | 1779 | } |
| 1734 | 1780 | }, |
| 1735 | 1781 | .other => { |
| 1736 | try clang_argv.appendSlice(it.other_args); | |
| 1782 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1737 | 1783 | }, |
| 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))) { | |
| 1740 | 1785 | .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, | |
| 1742 | 1789 | .src_path = it.only_arg, |
| 1743 | 1790 | .ext = file_ext, // duped while parsing the args. |
| 1744 | 1791 | }); |
| 1745 | 1792 | }, |
| 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 | }, | |
| 1754 | 1813 | .manifest => { |
| 1755 | 1814 | if (manifest_file) |other| { |
| 1756 | 1815 | 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( |
| 1760 | 1819 | linker_module_definition_file = it.only_arg; |
| 1761 | 1820 | }, |
| 1762 | 1821 | .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 | }); | |
| 1764 | 1827 | }, |
| 1765 | 1828 | .zig => { |
| 1766 | 1829 | if (root_src_file) |other| { |
| ... | ... | @@ -1777,13 +1840,13 @@ fn buildOutputType( |
| 1777 | 1840 | // more control over what's in the resulting |
| 1778 | 1841 | // binary: no extra rpaths and DSO filename exactly |
| 1779 | 1842 | // as provided. Hello, Go. |
| 1780 | try link_objects.append(.{ | |
| 1843 | try create_module.link_objects.append(arena, .{ | |
| 1781 | 1844 | .path = it.only_arg, |
| 1782 | 1845 | .must_link = must_link, |
| 1783 | 1846 | .loption = true, |
| 1784 | 1847 | }); |
| 1785 | 1848 | } else { |
| 1786 | try system_libs.put(it.only_arg, .{ | |
| 1849 | try create_module.system_libs.put(arena, it.only_arg, .{ | |
| 1787 | 1850 | .needed = needed, |
| 1788 | 1851 | .weak = false, |
| 1789 | 1852 | .preferred_mode = lib_preferred_mode, |
| ... | ... | @@ -1796,16 +1859,16 @@ fn buildOutputType( |
| 1796 | 1859 | // Never mind what we're doing, just pass the args directly. For example --help. |
| 1797 | 1860 | return process.exit(try clangMain(arena, all_args)); |
| 1798 | 1861 | }, |
| 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, | |
| 1809 | 1872 | .function_sections => function_sections = true, |
| 1810 | 1873 | .no_function_sections => function_sections = false, |
| 1811 | 1874 | .data_sections => data_sections = true, |
| ... | ... | @@ -1814,26 +1877,26 @@ fn buildOutputType( |
| 1814 | 1877 | .no_builtin => no_builtin = true, |
| 1815 | 1878 | .color_diagnostics => color = .on, |
| 1816 | 1879 | .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, | |
| 1819 | 1882 | .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; | |
| 1822 | 1885 | } |
| 1823 | 1886 | }, |
| 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, | |
| 1827 | 1890 | .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; | |
| 1830 | 1893 | }, |
| 1831 | .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false, | |
| 1894 | .nostdlib_cpp => create_module.opts.ensure_libcpp_on_non_freestanding = false, | |
| 1832 | 1895 | .shared => { |
| 1833 | link_mode = .Dynamic; | |
| 1896 | create_module.opts.link_mode = .Dynamic; | |
| 1834 | 1897 | is_shared_lib = true; |
| 1835 | 1898 | }, |
| 1836 | .rdynamic => rdynamic = true, | |
| 1899 | .rdynamic => create_module.opts.rdynamic = true, | |
| 1837 | 1900 | .wl => { |
| 1838 | 1901 | var split_it = mem.splitScalar(u8, it.only_arg, ','); |
| 1839 | 1902 | while (split_it.next()) |linker_arg| { |
| ... | ... | @@ -1847,7 +1910,7 @@ fn buildOutputType( |
| 1847 | 1910 | const key = linker_arg[0..equals_pos]; |
| 1848 | 1911 | const value = linker_arg[equals_pos + 1 ..]; |
| 1849 | 1912 | 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| { | |
| 1851 | 1914 | fatal("unable to parse --build-id style '{s}': {s}", .{ |
| 1852 | 1915 | value, @errorName(err), |
| 1853 | 1916 | }); |
| ... | ... | @@ -1870,7 +1933,7 @@ fn buildOutputType( |
| 1870 | 1933 | } else if (mem.eql(u8, linker_arg, "--no-as-needed")) { |
| 1871 | 1934 | needed = true; |
| 1872 | 1935 | } else if (mem.eql(u8, linker_arg, "-no-pie")) { |
| 1873 | want_pie = false; | |
| 1936 | create_module.opts.pie = false; | |
| 1874 | 1937 | } else if (mem.eql(u8, linker_arg, "--sort-common")) { |
| 1875 | 1938 | // from ld.lld(1): --sort-common is ignored for GNU compatibility, |
| 1876 | 1939 | // this ignores plain --sort-common |
| ... | ... | @@ -1912,50 +1975,50 @@ fn buildOutputType( |
| 1912 | 1975 | if (mem.eql(u8, level, "s") or |
| 1913 | 1976 | mem.eql(u8, level, "z")) |
| 1914 | 1977 | { |
| 1915 | optimize_mode = .ReleaseSmall; | |
| 1978 | mod_opts.optimize_mode = .ReleaseSmall; | |
| 1916 | 1979 | } else if (mem.eql(u8, level, "1") or |
| 1917 | 1980 | mem.eql(u8, level, "2") or |
| 1918 | 1981 | mem.eql(u8, level, "3") or |
| 1919 | 1982 | mem.eql(u8, level, "4") or |
| 1920 | 1983 | mem.eql(u8, level, "fast")) |
| 1921 | 1984 | { |
| 1922 | optimize_mode = .ReleaseFast; | |
| 1985 | mod_opts.optimize_mode = .ReleaseFast; | |
| 1923 | 1986 | } else if (mem.eql(u8, level, "g") or |
| 1924 | 1987 | mem.eql(u8, level, "0")) |
| 1925 | 1988 | { |
| 1926 | optimize_mode = .Debug; | |
| 1989 | mod_opts.optimize_mode = .Debug; | |
| 1927 | 1990 | } else { |
| 1928 | try clang_argv.appendSlice(it.other_args); | |
| 1991 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1929 | 1992 | } |
| 1930 | 1993 | }, |
| 1931 | 1994 | .debug => { |
| 1932 | strip = false; | |
| 1995 | mod_opts.strip = false; | |
| 1933 | 1996 | if (mem.eql(u8, it.only_arg, "g")) { |
| 1934 | 1997 | // We handled with strip = false above. |
| 1935 | 1998 | } else if (mem.eql(u8, it.only_arg, "g1") or |
| 1936 | 1999 | mem.eql(u8, it.only_arg, "gline-tables-only")) |
| 1937 | 2000 | { |
| 1938 | 2001 | // 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"); | |
| 1940 | 2003 | } else { |
| 1941 | try clang_argv.appendSlice(it.other_args); | |
| 2004 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1942 | 2005 | } |
| 1943 | 2006 | }, |
| 1944 | 2007 | .gdwarf32 => { |
| 1945 | strip = false; | |
| 1946 | dwarf_format = .@"32"; | |
| 2008 | mod_opts.strip = false; | |
| 2009 | create_module.opts.debug_format = .{ .dwarf = .@"32" }; | |
| 1947 | 2010 | }, |
| 1948 | 2011 | .gdwarf64 => { |
| 1949 | strip = false; | |
| 1950 | dwarf_format = .@"64"; | |
| 2012 | mod_opts.strip = false; | |
| 2013 | create_module.opts.debug_format = .{ .dwarf = .@"64" }; | |
| 1951 | 2014 | }, |
| 1952 | 2015 | .sanitize => { |
| 1953 | 2016 | if (mem.eql(u8, it.only_arg, "undefined")) { |
| 1954 | want_sanitize_c = true; | |
| 2017 | mod_opts.sanitize_c = true; | |
| 1955 | 2018 | } else if (mem.eql(u8, it.only_arg, "thread")) { |
| 1956 | want_tsan = true; | |
| 2019 | mod_opts.sanitize_thread = true; | |
| 1957 | 2020 | } else { |
| 1958 | try clang_argv.appendSlice(it.other_args); | |
| 2021 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1959 | 2022 | } |
| 1960 | 2023 | }, |
| 1961 | 2024 | .linker_script => linker_script = it.only_arg, |
| ... | ... | @@ -1964,65 +2027,63 @@ fn buildOutputType( |
| 1964 | 2027 | // Have Clang print more infos, some tools such as CMake |
| 1965 | 2028 | // parse this to discover any implicit include and |
| 1966 | 2029 | // library dir to look-up into. |
| 1967 | try clang_argv.append("-v"); | |
| 2030 | try cc_argv.append(arena, "-v"); | |
| 1968 | 2031 | }, |
| 1969 | 2032 | .dry_run => { |
| 1970 | 2033 | // This flag means "dry run". Clang will not actually output anything |
| 1971 | 2034 | // to the file system. |
| 1972 | 2035 | verbose_link = true; |
| 1973 | 2036 | disable_c_depfile = true; |
| 1974 | try clang_argv.append("-###"); | |
| 2037 | try cc_argv.append(arena, "-###"); | |
| 1975 | 2038 | }, |
| 1976 | 2039 | .for_linker => try linker_args.append(it.only_arg), |
| 1977 | 2040 | .linker_input_z => { |
| 1978 | 2041 | try linker_args.append("-z"); |
| 1979 | 2042 | try linker_args.append(it.only_arg); |
| 1980 | 2043 | }, |
| 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), | |
| 1982 | 2045 | .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), | |
| 1984 | 2047 | .dep_file => { |
| 1985 | 2048 | disable_c_depfile = true; |
| 1986 | try clang_argv.appendSlice(it.other_args); | |
| 2049 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1987 | 2050 | }, |
| 1988 | 2051 | .dep_file_to_stdout => { // -M, -MM |
| 1989 | 2052 | // "Like -MD, but also implies -E and writes to stdout by default" |
| 1990 | 2053 | // "Like -MMD, but also implies -E and writes to stdout by default" |
| 1991 | 2054 | c_out_mode = .preprocessor; |
| 1992 | 2055 | disable_c_depfile = true; |
| 1993 | try clang_argv.appendSlice(it.other_args); | |
| 2056 | try cc_argv.appendSlice(arena, it.other_args); | |
| 1994 | 2057 | }, |
| 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, | |
| 1999 | 2062 | .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); | |
| 2003 | 2064 | }, |
| 2004 | 2065 | .sysroot => { |
| 2005 | sysroot = it.only_arg; | |
| 2066 | create_module.sysroot = it.only_arg; | |
| 2006 | 2067 | }, |
| 2007 | 2068 | .entry => { |
| 2008 | entry = it.only_arg; | |
| 2069 | entry = .{ .named = it.only_arg }; | |
| 2009 | 2070 | }, |
| 2010 | 2071 | .force_undefined_symbol => { |
| 2011 | try force_undefined_symbols.put(gpa, it.only_arg, {}); | |
| 2072 | try force_undefined_symbols.put(arena, it.only_arg, {}); | |
| 2012 | 2073 | }, |
| 2013 | .weak_library => try system_libs.put(it.only_arg, .{ | |
| 2074 | .weak_library => try create_module.system_libs.put(arena, it.only_arg, .{ | |
| 2014 | 2075 | .needed = false, |
| 2015 | 2076 | .weak = true, |
| 2016 | 2077 | .preferred_mode = lib_preferred_mode, |
| 2017 | 2078 | .search_strategy = lib_search_strategy, |
| 2018 | 2079 | }), |
| 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 }), | |
| 2020 | 2081 | .headerpad_max_install_names => headerpad_max_install_names = true, |
| 2021 | 2082 | .compress_debug_sections => { |
| 2022 | 2083 | if (it.only_arg.len == 0) { |
| 2023 | 2084 | linker_compress_debug_sections = .zlib; |
| 2024 | 2085 | } 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 { | |
| 2026 | 2087 | fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg}); |
| 2027 | 2088 | }; |
| 2028 | 2089 | } |
| ... | ... | @@ -2077,30 +2138,25 @@ fn buildOutputType( |
| 2077 | 2138 | } |
| 2078 | 2139 | provided_name = name[prefix..end]; |
| 2079 | 2140 | } 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()); | |
| 2081 | 2142 | } else if (mem.eql(u8, arg, "--subsystem")) { |
| 2082 | 2143 | subsystem = try parseSubSystem(linker_args_it.nextOrFatal()); |
| 2083 | 2144 | } else if (mem.eql(u8, arg, "-I") or |
| 2084 | 2145 | mem.eql(u8, arg, "--dynamic-linker") or |
| 2085 | 2146 | mem.eql(u8, arg, "-dynamic-linker")) |
| 2086 | 2147 | { |
| 2087 | target_dynamic_linker = linker_args_it.nextOrFatal(); | |
| 2148 | create_module.dynamic_linker = linker_args_it.nextOrFatal(); | |
| 2088 | 2149 | } else if (mem.eql(u8, arg, "-E") or |
| 2089 | 2150 | mem.eql(u8, arg, "--export-dynamic") or |
| 2090 | 2151 | mem.eql(u8, arg, "-export-dynamic")) |
| 2091 | 2152 | { |
| 2092 | rdynamic = true; | |
| 2153 | create_module.opts.rdynamic = true; | |
| 2093 | 2154 | } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) { |
| 2094 | 2155 | version_script = linker_args_it.nextOrFatal(); |
| 2095 | 2156 | } 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(); | |
| 2100 | 2158 | } 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..]; | |
| 2104 | 2160 | } else if (mem.eql(u8, arg, "-pagezero_size")) { |
| 2105 | 2161 | const next_arg = linker_args_it.nextOrFatal(); |
| 2106 | 2162 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| ... | ... | @@ -2131,7 +2187,7 @@ fn buildOutputType( |
| 2131 | 2187 | linker_print_map = true; |
| 2132 | 2188 | } else if (mem.eql(u8, arg, "--sort-section")) { |
| 2133 | 2189 | 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 { | |
| 2135 | 2191 | fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1}); |
| 2136 | 2192 | }; |
| 2137 | 2193 | } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or |
| ... | ... | @@ -2145,9 +2201,9 @@ fn buildOutputType( |
| 2145 | 2201 | } else if (mem.eql(u8, arg, "-Bsymbolic")) { |
| 2146 | 2202 | linker_bind_global_refs_locally = true; |
| 2147 | 2203 | } else if (mem.eql(u8, arg, "--import-memory")) { |
| 2148 | linker_import_memory = true; | |
| 2204 | create_module.opts.import_memory = true; | |
| 2149 | 2205 | } else if (mem.eql(u8, arg, "--export-memory")) { |
| 2150 | linker_export_memory = true; | |
| 2206 | create_module.opts.export_memory = true; | |
| 2151 | 2207 | } else if (mem.eql(u8, arg, "--import-symbols")) { |
| 2152 | 2208 | linker_import_symbols = true; |
| 2153 | 2209 | } else if (mem.eql(u8, arg, "--import-table")) { |
| ... | ... | @@ -2155,7 +2211,7 @@ fn buildOutputType( |
| 2155 | 2211 | } else if (mem.eql(u8, arg, "--export-table")) { |
| 2156 | 2212 | linker_export_table = true; |
| 2157 | 2213 | } else if (mem.eql(u8, arg, "--no-entry")) { |
| 2158 | linker_force_entry = false; | |
| 2214 | entry = .disabled; | |
| 2159 | 2215 | } else if (mem.eql(u8, arg, "--initial-memory")) { |
| 2160 | 2216 | const next_arg = linker_args_it.nextOrFatal(); |
| 2161 | 2217 | linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| ... | ... | @@ -2167,17 +2223,17 @@ fn buildOutputType( |
| 2167 | 2223 | fatal("unable to parse max memory size '{s}': {s}", .{ next_arg, @errorName(err) }); |
| 2168 | 2224 | }; |
| 2169 | 2225 | } else if (mem.eql(u8, arg, "--shared-memory")) { |
| 2170 | linker_shared_memory = true; | |
| 2226 | create_module.opts.shared_memory = true; | |
| 2171 | 2227 | } else if (mem.eql(u8, arg, "--global-base")) { |
| 2172 | 2228 | const next_arg = linker_args_it.nextOrFatal(); |
| 2173 | 2229 | linker_global_base = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 2174 | 2230 | fatal("unable to parse global base '{s}': {s}", .{ next_arg, @errorName(err) }); |
| 2175 | 2231 | }; |
| 2176 | 2232 | } 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()); | |
| 2178 | 2234 | } else if (mem.eql(u8, arg, "--compress-debug-sections")) { |
| 2179 | 2235 | 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 { | |
| 2181 | 2237 | fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1}); |
| 2182 | 2238 | }; |
| 2183 | 2239 | } else if (mem.startsWith(u8, arg, "-z")) { |
| ... | ... | @@ -2208,10 +2264,7 @@ fn buildOutputType( |
| 2208 | 2264 | } else if (mem.eql(u8, z_arg, "norelro")) { |
| 2209 | 2265 | linker_z_relro = false; |
| 2210 | 2266 | } 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..]); | |
| 2215 | 2268 | } else if (mem.startsWith(u8, z_arg, "common-page-size=")) { |
| 2216 | 2269 | linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len); |
| 2217 | 2270 | } else if (mem.startsWith(u8, z_arg, "max-page-size=")) { |
| ... | ... | @@ -2232,19 +2285,13 @@ fn buildOutputType( |
| 2232 | 2285 | }; |
| 2233 | 2286 | have_version = true; |
| 2234 | 2287 | } 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() }; | |
| 2236 | 2289 | } 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(), {}); | |
| 2238 | 2291 | } 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()); | |
| 2243 | 2293 | } 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()); | |
| 2248 | 2295 | } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { |
| 2249 | 2296 | linker_script = linker_args_it.nextOrFatal(); |
| 2250 | 2297 | } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { |
| ... | ... | @@ -2262,7 +2309,7 @@ fn buildOutputType( |
| 2262 | 2309 | } else if (mem.eql(u8, arg, "--high-entropy-va")) { |
| 2263 | 2310 | // This option does not do anything. |
| 2264 | 2311 | } else if (mem.eql(u8, arg, "--export-all-symbols")) { |
| 2265 | rdynamic = true; | |
| 2312 | create_module.opts.rdynamic = true; | |
| 2266 | 2313 | } else if (mem.eql(u8, arg, "--color-diagnostics") or |
| 2267 | 2314 | mem.eql(u8, arg, "--color-diagnostics=always")) |
| 2268 | 2315 | { |
| ... | ... | @@ -2276,7 +2323,7 @@ fn buildOutputType( |
| 2276 | 2323 | { |
| 2277 | 2324 | // -s, --strip-all Strip all symbols |
| 2278 | 2325 | // -S, --strip-debug Strip debugging symbols |
| 2279 | strip = true; | |
| 2326 | mod_opts.strip = true; | |
| 2280 | 2327 | } else if (mem.eql(u8, arg, "--start-group") or |
| 2281 | 2328 | mem.eql(u8, arg, "--end-group")) |
| 2282 | 2329 | { |
| ... | ... | @@ -2290,44 +2337,40 @@ fn buildOutputType( |
| 2290 | 2337 | _ = linker_args_it.nextOrFatal(); |
| 2291 | 2338 | } else if (mem.eql(u8, arg, "--major-subsystem-version")) { |
| 2292 | 2339 | 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 | }); | |
| 2299 | 2344 | }; |
| 2300 | 2345 | } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { |
| 2301 | 2346 | 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 | }); | |
| 2308 | 2351 | }; |
| 2309 | 2352 | } 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(), .{}); | |
| 2311 | 2354 | } 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 }); | |
| 2313 | 2356 | } 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 }); | |
| 2315 | 2358 | } 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(), .{ | |
| 2317 | 2360 | .weak = false, |
| 2318 | 2361 | .needed = true, |
| 2319 | 2362 | .preferred_mode = lib_preferred_mode, |
| 2320 | 2363 | .search_strategy = lib_search_strategy, |
| 2321 | 2364 | }); |
| 2322 | 2365 | } 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..], .{ | |
| 2324 | 2367 | .weak = true, |
| 2325 | 2368 | .needed = false, |
| 2326 | 2369 | .preferred_mode = lib_preferred_mode, |
| 2327 | 2370 | .search_strategy = lib_search_strategy, |
| 2328 | 2371 | }); |
| 2329 | 2372 | } 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(), .{ | |
| 2331 | 2374 | .weak = true, |
| 2332 | 2375 | .needed = false, |
| 2333 | 2376 | .preferred_mode = lib_preferred_mode, |
| ... | ... | @@ -2361,7 +2404,7 @@ fn buildOutputType( |
| 2361 | 2404 | } else if (mem.eql(u8, arg, "-install_name")) { |
| 2362 | 2405 | install_name = linker_args_it.nextOrFatal(); |
| 2363 | 2406 | } else if (mem.eql(u8, arg, "-force_load")) { |
| 2364 | try link_objects.append(.{ | |
| 2407 | try create_module.link_objects.append(arena, .{ | |
| 2365 | 2408 | .path = linker_args_it.nextOrFatal(), |
| 2366 | 2409 | .must_link = true, |
| 2367 | 2410 | }); |
| ... | ... | @@ -2369,7 +2412,7 @@ fn buildOutputType( |
| 2369 | 2412 | mem.eql(u8, arg, "--hash-style")) |
| 2370 | 2413 | { |
| 2371 | 2414 | 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 { | |
| 2373 | 2416 | fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{ |
| 2374 | 2417 | next_arg, |
| 2375 | 2418 | }); |
| ... | ... | @@ -2402,22 +2445,22 @@ fn buildOutputType( |
| 2402 | 2445 | } |
| 2403 | 2446 | } |
| 2404 | 2447 | |
| 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; | |
| 2408 | 2451 | } |
| 2409 | 2452 | } |
| 2410 | 2453 | |
| 2411 | 2454 | switch (c_out_mode) { |
| 2412 | 2455 | .link => { |
| 2413 | output_mode = if (is_shared_lib) .Lib else .Exe; | |
| 2456 | create_module.opts.output_mode = if (is_shared_lib) .Lib else .Exe; | |
| 2414 | 2457 | emit_bin = if (out_path) |p| .{ .yes = p } else EmitBin.yes_a_out; |
| 2415 | 2458 | if (emit_llvm) { |
| 2416 | 2459 | fatal("-emit-llvm cannot be used when linking", .{}); |
| 2417 | 2460 | } |
| 2418 | 2461 | }, |
| 2419 | 2462 | .object => { |
| 2420 | output_mode = .Obj; | |
| 2463 | create_module.opts.output_mode = .Obj; | |
| 2421 | 2464 | if (emit_llvm) { |
| 2422 | 2465 | emit_bin = .no; |
| 2423 | 2466 | if (out_path) |p| { |
| ... | ... | @@ -2434,7 +2477,7 @@ fn buildOutputType( |
| 2434 | 2477 | } |
| 2435 | 2478 | }, |
| 2436 | 2479 | .assembly => { |
| 2437 | output_mode = .Obj; | |
| 2480 | create_module.opts.output_mode = .Obj; | |
| 2438 | 2481 | emit_bin = .no; |
| 2439 | 2482 | if (emit_llvm) { |
| 2440 | 2483 | if (out_path) |p| { |
| ... | ... | @@ -2451,9 +2494,9 @@ fn buildOutputType( |
| 2451 | 2494 | } |
| 2452 | 2495 | }, |
| 2453 | 2496 | .preprocessor => { |
| 2454 | output_mode = .Obj; | |
| 2497 | create_module.opts.output_mode = .Obj; | |
| 2455 | 2498 | // 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) { | |
| 2457 | 2500 | // For example `zig cc` and no args should print the "no input files" message. |
| 2458 | 2501 | return process.exit(try clangMain(arena, all_args)); |
| 2459 | 2502 | } |
| ... | ... | @@ -2465,8 +2508,8 @@ fn buildOutputType( |
| 2465 | 2508 | } |
| 2466 | 2509 | }, |
| 2467 | 2510 | } |
| 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 | |
| 2470 | 2513 | root_src_file == null) |
| 2471 | 2514 | { |
| 2472 | 2515 | // For example `zig cc` and no args should print the "no input files" message. |
| ... | ... | @@ -2476,258 +2519,115 @@ fn buildOutputType( |
| 2476 | 2519 | }, |
| 2477 | 2520 | } |
| 2478 | 2521 | |
| 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}); | |
| 2516 | 2524 | } |
| 2517 | 2525 | |
| 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"; | |
| 2520 | 2531 | } |
| 2521 | 2532 | |
| 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; | |
| 2574 | 2546 | } |
| 2575 | 2547 | |
| 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; | |
| 2580 | 2550 | |
| 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; | |
| 2604 | 2553 | |
| 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; | |
| 2610 | 2556 | |
| 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; | |
| 2613 | 2559 | |
| 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; | |
| 2620 | 2562 | |
| 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", .{}); | |
| 2637 | 2565 | |
| 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]", .{}); | |
| 2655 | 2567 | |
| 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 | }; | |
| 2681 | 2570 | |
| 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; | |
| 2689 | 2582 | |
| 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)); | |
| 2697 | 2588 | |
| 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; | |
| 2702 | 2614 | } |
| 2703 | 2615 | |
| 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", .{}); | |
| 2708 | 2618 | } |
| 2709 | 2619 | |
| 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 | }); | |
| 2714 | 2624 | } |
| 2715 | 2625 | |
| 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 | }); | |
| 2729 | 2630 | } |
| 2730 | lib_dir_args = undefined; // From here we use lib_dirs instead. | |
| 2731 | 2631 | |
| 2732 | 2632 | const self_exe_path: ?[]const u8 = if (!process.can_spawn) |
| 2733 | 2633 | null |
| ... | ... | @@ -2757,290 +2657,119 @@ fn buildOutputType( |
| 2757 | 2657 | }; |
| 2758 | 2658 | defer zig_lib_directory.handle.close(); |
| 2759 | 2659 | |
| 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, | |
| 2806 | 2665 | }; |
| 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 | } | |
| 2818 | 2666 | } |
| 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"); | |
| 2829 | 2669 | } |
| 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, | |
| 2844 | 2674 | }; |
| 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(); | |
| 2854 | 2677 | |
| 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}); | |
| 2858 | 2680 | } |
| 2859 | 2681 | |
| 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; | |
| 2870 | 2687 | |
| 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}); | |
| 2873 | 2692 | } |
| 2874 | 2693 | |
| 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 | }; | |
| 2883 | 2709 | |
| 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 | }; | |
| 2890 | 2715 | |
| 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 | }); | |
| 2894 | 2751 | |
| 2895 | checked_paths.clearRetainingCapacity(); | |
| 2752 | break :root_mod test_mod; | |
| 2753 | } else main_mod; | |
| 2896 | 2754 | |
| 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; | |
| 2991 | 2756 | |
| 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)", .{}); | |
| 3026 | 2760 | } |
| 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)", .{}); | |
| 3036 | 2766 | } |
| 3037 | 2767 | } |
| 3038 | // After this point, resolved_system_libs is used instead of external_system_libs. | |
| 3039 | 2768 | |
| 3040 | 2769 | // We now repeat part of the process for frameworks. |
| 3041 | 2770 | var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena); |
| 3042 | 2771 | |
| 3043 | if (frameworks.keys().len > 0) { | |
| 2772 | if (create_module.frameworks.keys().len > 0) { | |
| 3044 | 2773 | var test_path = std.ArrayList(u8).init(gpa); |
| 3045 | 2774 | defer test_path.deinit(); |
| 3046 | 2775 | |
| ... | ... | @@ -3052,10 +2781,10 @@ fn buildOutputType( |
| 3052 | 2781 | checked_paths: []const u8, |
| 3053 | 2782 | }).init(arena); |
| 3054 | 2783 | |
| 3055 | framework: for (frameworks.keys(), frameworks.values()) |framework_name, info| { | |
| 2784 | framework: for (create_module.frameworks.keys(), create_module.frameworks.values()) |framework_name, info| { | |
| 3056 | 2785 | checked_paths.clearRetainingCapacity(); |
| 3057 | 2786 | |
| 3058 | for (framework_dirs.items) |framework_dir_path| { | |
| 2787 | for (create_module.framework_dirs.items) |framework_dir_path| { | |
| 3059 | 2788 | if (try accessFrameworkPath( |
| 3060 | 2789 | &test_path, |
| 3061 | 2790 | &checked_paths, |
| ... | ... | @@ -3090,15 +2819,15 @@ fn buildOutputType( |
| 3090 | 2819 | } |
| 3091 | 2820 | // After this point, resolved_frameworks is used instead of frameworks. |
| 3092 | 2821 | |
| 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 + | |
| 3097 | 2826 | @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; | |
| 3100 | 2829 | 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)}); | |
| 3102 | 2831 | } |
| 3103 | 2832 | } |
| 3104 | 2833 | |
| ... | ... | @@ -3108,10 +2837,12 @@ fn buildOutputType( |
| 3108 | 2837 | const output_to_cache = listen != .none; |
| 3109 | 2838 | const optional_version = if (have_version) version else null; |
| 3110 | 2839 | |
| 2840 | const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name; | |
| 2841 | ||
| 3111 | 2842 | const resolved_soname: ?[]const u8 = switch (soname) { |
| 3112 | 2843 | .yes => |explicit| explicit, |
| 3113 | 2844 | .no => null, |
| 3114 | .yes_default_value => switch (object_format) { | |
| 2845 | .yes_default_value => switch (target.ofmt) { | |
| 3115 | 2846 | .elf => if (have_version) |
| 3116 | 2847 | try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major }) |
| 3117 | 2848 | else |
| ... | ... | @@ -3120,7 +2851,7 @@ fn buildOutputType( |
| 3120 | 2851 | }, |
| 3121 | 2852 | }; |
| 3122 | 2853 | |
| 3123 | const a_out_basename = switch (object_format) { | |
| 2854 | const a_out_basename = switch (target.ofmt) { | |
| 3124 | 2855 | .coff => "a.exe", |
| 3125 | 2856 | else => "a.out", |
| 3126 | 2857 | }; |
| ... | ... | @@ -3142,9 +2873,9 @@ fn buildOutputType( |
| 3142 | 2873 | }, |
| 3143 | 2874 | .basename = try std.zig.binNameAlloc(arena, .{ |
| 3144 | 2875 | .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, | |
| 3148 | 2879 | .version = optional_version, |
| 3149 | 2880 | }), |
| 3150 | 2881 | }, |
| ... | ... | @@ -3262,15 +2993,15 @@ fn buildOutputType( |
| 3262 | 2993 | }; |
| 3263 | 2994 | defer emit_docs_resolved.deinit(); |
| 3264 | 2995 | |
| 3265 | const is_exe_or_dyn_lib = switch (output_mode) { | |
| 2996 | const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) { | |
| 3266 | 2997 | .Obj => false, |
| 3267 | .Lib => (link_mode orelse .Static) == .Dynamic, | |
| 2998 | .Lib => create_module.resolved_options.link_mode == .Dynamic, | |
| 3268 | 2999 | .Exe => true, |
| 3269 | 3000 | }; |
| 3270 | 3001 | // Note that cmake when targeting Windows will try to execute |
| 3271 | 3002 | // zig cc to make an executable and output an implib too. |
| 3272 | 3003 | 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; | |
| 3274 | 3005 | if (!implib_eligible) { |
| 3275 | 3006 | if (!emit_implib_arg_provided) { |
| 3276 | 3007 | emit_implib = .no; |
| ... | ... | @@ -3296,76 +3027,10 @@ fn buildOutputType( |
| 3296 | 3027 | }; |
| 3297 | 3028 | defer emit_implib_resolved.deinit(); |
| 3298 | 3029 | |
| 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 | ||
| 3347 | 3030 | var thread_pool: ThreadPool = undefined; |
| 3348 | 3031 | try thread_pool.init(.{ .allocator = gpa }); |
| 3349 | 3032 | defer thread_pool.deinit(); |
| 3350 | 3033 | |
| 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 | ||
| 3369 | 3034 | var cleanup_local_cache_dir: ?fs.Dir = null; |
| 3370 | 3035 | defer if (cleanup_local_cache_dir) |*dir| dir.close(); |
| 3371 | 3036 | |
| ... | ... | @@ -3381,37 +3046,37 @@ fn buildOutputType( |
| 3381 | 3046 | if (arg_mode == .run) { |
| 3382 | 3047 | break :l global_cache_directory; |
| 3383 | 3048 | } |
| 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, | |
| 3407 | 3071 | } |
| 3408 | 3072 | } |
| 3073 | ||
| 3409 | 3074 | // Otherwise we really don't have a reasonable place to put the local cache directory, |
| 3410 | 3075 | // so we utilize the global one. |
| 3411 | 3076 | break :l global_cache_directory; |
| 3412 | 3077 | }; |
| 3413 | 3078 | |
| 3414 | for (c_source_files.items) |*src| { | |
| 3079 | for (create_module.c_source_files.items) |*src| { | |
| 3415 | 3080 | if (!mem.eql(u8, src.src_path, "-")) continue; |
| 3416 | 3081 | |
| 3417 | 3082 | const ext = src.ext orelse |
| ... | ... | @@ -3420,7 +3085,7 @@ fn buildOutputType( |
| 3420 | 3085 | // "-" is stdin. Dump it to a real file. |
| 3421 | 3086 | const sep = fs.path.sep_str; |
| 3422 | 3087 | 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), | |
| 3424 | 3089 | }); |
| 3425 | 3090 | try local_cache_directory.handle.makePath("tmp"); |
| 3426 | 3091 | // Note that in one of the happy paths, execve() is used to switch |
| ... | ... | @@ -3448,20 +3113,35 @@ fn buildOutputType( |
| 3448 | 3113 | else => false, |
| 3449 | 3114 | }; |
| 3450 | 3115 | |
| 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 | ||
| 3451 | 3131 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 3452 | 3132 | |
| 3453 | const comp = Compilation.create(gpa, .{ | |
| 3133 | const comp = Compilation.create(gpa, arena, .{ | |
| 3454 | 3134 | .zig_lib_directory = zig_lib_directory, |
| 3455 | 3135 | .local_cache_directory = local_cache_directory, |
| 3456 | 3136 | .global_cache_directory = global_cache_directory, |
| 3137 | .thread_pool = &thread_pool, | |
| 3138 | .self_exe_path = self_exe_path, | |
| 3139 | .config = create_module.resolved_options, | |
| 3457 | 3140 | .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, | |
| 3464 | 3142 | .main_mod = main_mod, |
| 3143 | .root_mod = root_mod, | |
| 3144 | .std_mod = std_mod, | |
| 3465 | 3145 | .emit_bin = emit_bin_loc, |
| 3466 | 3146 | .emit_h = emit_h_resolved.data, |
| 3467 | 3147 | .emit_asm = emit_asm_resolved.data, |
| ... | ... | @@ -3469,45 +3149,21 @@ fn buildOutputType( |
| 3469 | 3149 | .emit_llvm_bc = emit_llvm_bc_resolved.data, |
| 3470 | 3150 | .emit_docs = emit_docs_resolved.data, |
| 3471 | 3151 | .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, | |
| 3479 | 3154 | .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, | |
| 3482 | 3157 | .manifest_file = manifest_file, |
| 3483 | 3158 | .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, | |
| 3486 | 3161 | .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, | |
| 3504 | 3165 | .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, | |
| 3509 | 3166 | .hash_style = hash_style, |
| 3510 | .rdynamic = rdynamic, | |
| 3511 | 3167 | .linker_script = linker_script, |
| 3512 | 3168 | .version_script = version_script, |
| 3513 | 3169 | .disable_c_depfile = disable_c_depfile, |
| ... | ... | @@ -3516,18 +3172,15 @@ fn buildOutputType( |
| 3516 | 3172 | .linker_gc_sections = linker_gc_sections, |
| 3517 | 3173 | .linker_allow_shlib_undefined = linker_allow_shlib_undefined, |
| 3518 | 3174 | .linker_bind_global_refs_locally = linker_bind_global_refs_locally, |
| 3519 | .linker_import_memory = linker_import_memory, | |
| 3520 | .linker_export_memory = linker_export_memory, | |
| 3521 | 3175 | .linker_import_symbols = linker_import_symbols, |
| 3522 | 3176 | .linker_import_table = linker_import_table, |
| 3523 | 3177 | .linker_export_table = linker_export_table, |
| 3524 | 3178 | .linker_initial_memory = linker_initial_memory, |
| 3525 | 3179 | .linker_max_memory = linker_max_memory, |
| 3526 | .linker_shared_memory = linker_shared_memory, | |
| 3527 | 3180 | .linker_print_gc_sections = linker_print_gc_sections, |
| 3528 | 3181 | .linker_print_icf_sections = linker_print_icf_sections, |
| 3529 | 3182 | .linker_print_map = linker_print_map, |
| 3530 | .linker_opt_bisect_limit = linker_opt_bisect_limit, | |
| 3183 | .llvm_opt_bisect_limit = llvm_opt_bisect_limit, | |
| 3531 | 3184 | .linker_global_base = linker_global_base, |
| 3532 | 3185 | .linker_export_symbol_names = linker_export_symbol_names.items, |
| 3533 | 3186 | .linker_z_nocopyreloc = linker_z_nocopyreloc, |
| ... | ... | @@ -3542,7 +3195,6 @@ fn buildOutputType( |
| 3542 | 3195 | .linker_tsaware = linker_tsaware, |
| 3543 | 3196 | .linker_nxcompat = linker_nxcompat, |
| 3544 | 3197 | .linker_dynamicbase = linker_dynamicbase, |
| 3545 | .linker_optimization = linker_optimization, | |
| 3546 | 3198 | .linker_compress_debug_sections = linker_compress_debug_sections, |
| 3547 | 3199 | .linker_module_definition_file = linker_module_definition_file, |
| 3548 | 3200 | .major_subsystem_version = major_subsystem_version, |
| ... | ... | @@ -3551,20 +3203,16 @@ fn buildOutputType( |
| 3551 | 3203 | .link_emit_relocs = link_emit_relocs, |
| 3552 | 3204 | .entry = entry, |
| 3553 | 3205 | .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, | |
| 3557 | 3208 | .formatted_panics = formatted_panics, |
| 3558 | .single_threaded = single_threaded, | |
| 3559 | 3209 | .function_sections = function_sections, |
| 3560 | 3210 | .data_sections = data_sections, |
| 3561 | 3211 | .no_builtin = no_builtin, |
| 3562 | .self_exe_path = self_exe_path, | |
| 3563 | .thread_pool = &thread_pool, | |
| 3564 | 3212 | .clang_passthrough_mode = clang_passthrough_mode, |
| 3565 | 3213 | .clang_preprocessor_mode = clang_preprocessor_mode, |
| 3566 | 3214 | .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, | |
| 3568 | 3216 | .verbose_cc = verbose_cc, |
| 3569 | 3217 | .verbose_link = verbose_link, |
| 3570 | 3218 | .verbose_air = verbose_air, |
| ... | ... | @@ -3574,21 +3222,16 @@ fn buildOutputType( |
| 3574 | 3222 | .verbose_llvm_bc = verbose_llvm_bc, |
| 3575 | 3223 | .verbose_cimport = verbose_cimport, |
| 3576 | 3224 | .verbose_llvm_cpu_features = verbose_llvm_cpu_features, |
| 3577 | .machine_code_model = machine_code_model, | |
| 3578 | .color = color, | |
| 3579 | 3225 | .time_report = time_report, |
| 3580 | 3226 | .stack_report = stack_report, |
| 3581 | .is_test = arg_mode == .zig_test, | |
| 3582 | 3227 | .each_lib_rpath = each_lib_rpath, |
| 3583 | 3228 | .build_id = build_id, |
| 3584 | .test_evented_io = test_evented_io, | |
| 3585 | 3229 | .test_filter = test_filter, |
| 3586 | 3230 | .test_name_prefix = test_name_prefix, |
| 3587 | 3231 | .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, | |
| 3589 | 3234 | .subsystem = subsystem, |
| 3590 | .dwarf_format = dwarf_format, | |
| 3591 | .wasi_exec_model = wasi_exec_model, | |
| 3592 | 3235 | .debug_compile_errors = debug_compile_errors, |
| 3593 | 3236 | .enable_link_snapshots = enable_link_snapshots, |
| 3594 | 3237 | .install_name = install_name, |
| ... | ... | @@ -3598,13 +3241,15 @@ fn buildOutputType( |
| 3598 | 3241 | .headerpad_max_install_names = headerpad_max_install_names, |
| 3599 | 3242 | .dead_strip_dylibs = dead_strip_dylibs, |
| 3600 | 3243 | .reference_trace = reference_trace, |
| 3601 | .error_tracing = error_tracing, | |
| 3602 | 3244 | .pdb_out_path = pdb_out_path, |
| 3603 | 3245 | .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), | |
| 3605 | 3251 | }) catch |err| switch (err) { |
| 3606 | 3252 | error.LibCUnavailable => { |
| 3607 | const target = target_info.target; | |
| 3608 | 3253 | const triple_name = try target.zigTriple(arena); |
| 3609 | 3254 | std.log.err("unable to find or provide libc for target '{s}'", .{triple_name}); |
| 3610 | 3255 | |
| ... | ... | @@ -3632,7 +3277,9 @@ fn buildOutputType( |
| 3632 | 3277 | defer if (!comp_destroyed) comp.destroy(); |
| 3633 | 3278 | |
| 3634 | 3279 | 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); | |
| 3636 | 3283 | } |
| 3637 | 3284 | switch (listen) { |
| 3638 | 3285 | .none => {}, |
| ... | ... | @@ -3681,7 +3328,7 @@ fn buildOutputType( |
| 3681 | 3328 | return cmdTranslateC(comp, arena, null); |
| 3682 | 3329 | } |
| 3683 | 3330 | |
| 3684 | updateModule(comp) catch |err| switch (err) { | |
| 3331 | updateModule(comp, color) catch |err| switch (err) { | |
| 3685 | 3332 | error.SemanticAnalyzeFail => { |
| 3686 | 3333 | assert(listen == .none); |
| 3687 | 3334 | saveState(comp, debug_incremental); |
| ... | ... | @@ -3693,10 +3340,10 @@ fn buildOutputType( |
| 3693 | 3340 | try comp.makeBinFileExecutable(); |
| 3694 | 3341 | saveState(comp, debug_incremental); |
| 3695 | 3342 | |
| 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: { | |
| 3697 | 3344 | // Default to using `zig run` to execute the produced .c code from `zig test`. |
| 3698 | 3345 | 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; | |
| 3700 | 3347 | const c_code_path = try fs.path.join(arena, &[_][]const u8{ |
| 3701 | 3348 | c_code_directory.path orelse ".", c_code_loc.basename, |
| 3702 | 3349 | }); |
| ... | ... | @@ -3706,23 +3353,24 @@ fn buildOutputType( |
| 3706 | 3353 | try test_exec_args.appendSlice(&.{ "-I", p }); |
| 3707 | 3354 | } |
| 3708 | 3355 | |
| 3709 | if (link_libc) { | |
| 3356 | if (create_module.resolved_options.link_libc) { | |
| 3710 | 3357 | try test_exec_args.append("-lc"); |
| 3711 | } else if (target_info.target.os.tag == .windows) { | |
| 3358 | } else if (target.os.tag == .windows) { | |
| 3712 | 3359 | try test_exec_args.appendSlice(&.{ |
| 3713 | 3360 | "--subsystem", "console", |
| 3714 | 3361 | "-lkernel32", "-lntdll", |
| 3715 | 3362 | }); |
| 3716 | 3363 | } |
| 3717 | 3364 | |
| 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| { | |
| 3719 | 3367 | try test_exec_args.append("-target"); |
| 3720 | try test_exec_args.append(target_arch_os_abi); | |
| 3368 | try test_exec_args.append(triple); | |
| 3721 | 3369 | } |
| 3722 | if (target_mcpu) |mcpu| { | |
| 3370 | if (first_cli_mod.target_mcpu) |mcpu| { | |
| 3723 | 3371 | try test_exec_args.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu})); |
| 3724 | 3372 | } |
| 3725 | if (target_dynamic_linker) |dl| { | |
| 3373 | if (create_module.dynamic_linker) |dl| { | |
| 3726 | 3374 | try test_exec_args.append("--dynamic-linker"); |
| 3727 | 3375 | try test_exec_args.append(dl); |
| 3728 | 3376 | } |
| ... | ... | @@ -3742,11 +3390,11 @@ fn buildOutputType( |
| 3742 | 3390 | test_exec_args.items, |
| 3743 | 3391 | self_exe_path.?, |
| 3744 | 3392 | arg_mode, |
| 3745 | &target_info, | |
| 3393 | &target, | |
| 3746 | 3394 | &comp_destroyed, |
| 3747 | 3395 | all_args, |
| 3748 | 3396 | runtime_args_start, |
| 3749 | link_libc, | |
| 3397 | create_module.resolved_options.link_libc, | |
| 3750 | 3398 | ); |
| 3751 | 3399 | } |
| 3752 | 3400 | |
| ... | ... | @@ -3754,6 +3402,522 @@ fn buildOutputType( |
| 3754 | 3402 | return cleanExit(); |
| 3755 | 3403 | } |
| 3756 | 3404 | |
| 3405 | const 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 | ||
| 3445 | fn 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 | ||
| 3757 | 3921 | fn saveState(comp: *Compilation, debug_incremental: bool) void { |
| 3758 | 3922 | if (debug_incremental) { |
| 3759 | 3923 | comp.saveState() catch |err| { |
| ... | ... | @@ -3805,7 +3969,7 @@ fn serve( |
| 3805 | 3969 | const hdr = try server.receiveMessage(); |
| 3806 | 3970 | |
| 3807 | 3971 | switch (hdr.tag) { |
| 3808 | .exit => return, | |
| 3972 | .exit => return cleanExit(), | |
| 3809 | 3973 | .update => { |
| 3810 | 3974 | assert(main_progress_node.recently_updated_child == null); |
| 3811 | 3975 | tracy.frameMark(); |
| ... | ... | @@ -3827,7 +3991,7 @@ fn serve( |
| 3827 | 3991 | continue; |
| 3828 | 3992 | } |
| 3829 | 3993 | |
| 3830 | if (comp.bin_file.options.output_mode == .Exe) { | |
| 3994 | if (comp.config.output_mode == .Exe) { | |
| 3831 | 3995 | try comp.makeBinFileWritable(); |
| 3832 | 3996 | } |
| 3833 | 3997 | |
| ... | ... | @@ -3862,7 +4026,7 @@ fn serve( |
| 3862 | 4026 | // test_exec_args, |
| 3863 | 4027 | // self_exe_path.?, |
| 3864 | 4028 | // arg_mode, |
| 3865 | // target_info, | |
| 4029 | // target, | |
| 3866 | 4030 | // true, |
| 3867 | 4031 | // &comp_destroyed, |
| 3868 | 4032 | // all_args, |
| ... | ... | @@ -3877,7 +4041,7 @@ fn serve( |
| 3877 | 4041 | try comp.hotCodeSwap(main_progress_node, pid); |
| 3878 | 4042 | try serveUpdateResults(&server, comp); |
| 3879 | 4043 | } else { |
| 3880 | if (comp.bin_file.options.output_mode == .Exe) { | |
| 4044 | if (comp.config.output_mode == .Exe) { | |
| 3881 | 4045 | try comp.makeBinFileWritable(); |
| 3882 | 4046 | } |
| 3883 | 4047 | try comp.update(main_progress_node); |
| ... | ... | @@ -3967,63 +4131,76 @@ fn serveUpdateResults(s: *Server, comp: *Compilation) !void { |
| 3967 | 4131 | try s.serveErrorBundle(error_bundle); |
| 3968 | 4132 | return; |
| 3969 | 4133 | } |
| 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; | |
| 3977 | 4170 | const full_path = try emit.directory.join(gpa, &.{emit.sub_path}); |
| 3978 | 4171 | defer gpa.free(full_path); |
| 3979 | 4172 | try s.serveEmitBinPath(full_path, .{ |
| 3980 | 4173 | .flags = .{ .cache_hit = comp.last_update_was_cache_hit }, |
| 3981 | 4174 | }); |
| 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}); | |
| 3984 | 4186 | defer gpa.free(full_path); |
| 3985 | 4187 | try s.serveEmitBinPath(full_path, .{ |
| 3986 | 4188 | .flags = .{ .cache_hit = comp.last_update_was_cache_hit }, |
| 3987 | 4189 | }); |
| 4190 | return; | |
| 3988 | 4191 | } |
| 3989 | 4192 | } |
| 3990 | 4193 | |
| 3991 | const 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 | ||
| 4017 | fn parseCrossTargetOrReportFatalError( | |
| 4194 | fn parseTargetQueryOrReportFatalError( | |
| 4018 | 4195 | allocator: Allocator, |
| 4019 | opts: std.zig.CrossTarget.ParseOptions, | |
| 4020 | ) !std.zig.CrossTarget { | |
| 4196 | opts: std.Target.Query.ParseOptions, | |
| 4197 | ) std.Target.Query { | |
| 4021 | 4198 | var opts_with_diags = opts; |
| 4022 | var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{}; | |
| 4199 | var diags: std.Target.Query.ParseOptions.Diagnostics = .{}; | |
| 4023 | 4200 | if (opts_with_diags.diagnostics == null) { |
| 4024 | 4201 | opts_with_diags.diagnostics = &diags; |
| 4025 | 4202 | } |
| 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) { | |
| 4027 | 4204 | error.UnknownCpuModel => { |
| 4028 | 4205 | help: { |
| 4029 | 4206 | var help_text = std.ArrayList(u8).init(allocator); |
| ... | ... | @@ -4061,7 +4238,9 @@ fn parseCrossTargetOrReportFatalError( |
| 4061 | 4238 | } |
| 4062 | 4239 | fatal("unknown object format: '{s}'", .{opts.object_format.?}); |
| 4063 | 4240 | }, |
| 4064 | else => |e| return e, | |
| 4241 | else => |e| fatal("unable to parse target query '{s}': {s}", .{ | |
| 4242 | opts.arch_os_abi, @errorName(e), | |
| 4243 | }), | |
| 4065 | 4244 | }; |
| 4066 | 4245 | } |
| 4067 | 4246 | |
| ... | ... | @@ -4072,17 +4251,17 @@ fn runOrTest( |
| 4072 | 4251 | test_exec_args: []const ?[]const u8, |
| 4073 | 4252 | self_exe_path: []const u8, |
| 4074 | 4253 | arg_mode: ArgMode, |
| 4075 | target_info: *const std.zig.system.NativeTargetInfo, | |
| 4254 | target: *const std.Target, | |
| 4076 | 4255 | comp_destroyed: *bool, |
| 4077 | 4256 | all_args: []const []const u8, |
| 4078 | 4257 | runtime_args_start: ?usize, |
| 4079 | 4258 | link_libc: bool, |
| 4080 | 4259 | ) !void { |
| 4081 | const exe_emit = comp.bin_file.options.emit orelse return; | |
| 4260 | const lf = comp.bin_file orelse return; | |
| 4082 | 4261 | // A naive `directory.join` here will indeed get the correct path to the binary, |
| 4083 | 4262 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. |
| 4084 | 4263 | 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, | |
| 4086 | 4265 | }); |
| 4087 | 4266 | |
| 4088 | 4267 | var argv = std.ArrayList([]const u8).init(gpa); |
| ... | ... | @@ -4106,7 +4285,7 @@ fn runOrTest( |
| 4106 | 4285 | if (process.can_execv and arg_mode == .run) { |
| 4107 | 4286 | // execv releases the locks; no need to destroy the Compilation here. |
| 4108 | 4287 | 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); | |
| 4110 | 4289 | const cmd = try std.mem.join(arena, " ", argv.items); |
| 4111 | 4290 | fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd }); |
| 4112 | 4291 | } else if (process.can_spawn) { |
| ... | ... | @@ -4122,7 +4301,7 @@ fn runOrTest( |
| 4122 | 4301 | comp_destroyed.* = true; |
| 4123 | 4302 | |
| 4124 | 4303 | 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); | |
| 4126 | 4305 | const cmd = try std.mem.join(arena, " ", argv.items); |
| 4127 | 4306 | fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd }); |
| 4128 | 4307 | }; |
| ... | ... | @@ -4174,7 +4353,7 @@ fn runOrTestHotSwap( |
| 4174 | 4353 | all_args: []const []const u8, |
| 4175 | 4354 | runtime_args_start: ?usize, |
| 4176 | 4355 | ) !std.ChildProcess.Id { |
| 4177 | const exe_emit = comp.bin_file.options.emit.?; | |
| 4356 | const lf = comp.bin_file.?; | |
| 4178 | 4357 | |
| 4179 | 4358 | const exe_path = switch (builtin.target.os.tag) { |
| 4180 | 4359 | // On Windows it seems impossible to perform an atomic rename of a file that is currently |
| ... | ... | @@ -4182,16 +4361,16 @@ fn runOrTestHotSwap( |
| 4182 | 4361 | // tmp zig-cache and use it to spawn the child process. This way we are free to update |
| 4183 | 4362 | // the binary with each requested hot update. |
| 4184 | 4363 | .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, .{}); | |
| 4186 | 4365 | 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, | |
| 4188 | 4367 | }); |
| 4189 | 4368 | }, |
| 4190 | 4369 | |
| 4191 | 4370 | // A naive `directory.join` here will indeed get the correct path to the binary, |
| 4192 | 4371 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. |
| 4193 | 4372 | 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, | |
| 4195 | 4374 | }), |
| 4196 | 4375 | }; |
| 4197 | 4376 | defer gpa.free(exe_path); |
| ... | ... | @@ -4263,13 +4442,13 @@ fn runOrTestHotSwap( |
| 4263 | 4442 | } |
| 4264 | 4443 | } |
| 4265 | 4444 | |
| 4266 | fn updateModule(comp: *Compilation) !void { | |
| 4445 | fn updateModule(comp: *Compilation, color: Color) !void { | |
| 4267 | 4446 | { |
| 4268 | 4447 | // If the terminal is dumb, we dont want to show the user all the output. |
| 4269 | 4448 | var progress: std.Progress = .{ .dont_print_on_dumb = true }; |
| 4270 | 4449 | const main_progress_node = progress.start("", 0); |
| 4271 | 4450 | defer main_progress_node.end(); |
| 4272 | switch (comp.color) { | |
| 4451 | switch (color) { | |
| 4273 | 4452 | .off => { |
| 4274 | 4453 | progress.terminal = null; |
| 4275 | 4454 | }, |
| ... | ... | @@ -4287,24 +4466,25 @@ fn updateModule(comp: *Compilation) !void { |
| 4287 | 4466 | defer errors.deinit(comp.gpa); |
| 4288 | 4467 | |
| 4289 | 4468 | if (errors.errorMessageCount() > 0) { |
| 4290 | errors.renderToStdErr(renderOptions(comp.color)); | |
| 4469 | errors.renderToStdErr(renderOptions(color)); | |
| 4291 | 4470 | return error.SemanticAnalyzeFail; |
| 4292 | 4471 | } |
| 4293 | 4472 | } |
| 4294 | 4473 | |
| 4295 | 4474 | fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void { |
| 4296 | 4475 | if (build_options.only_core_functionality) @panic("@translate-c is not available in a zig2.c build"); |
| 4476 | const color: Color = .auto; | |
| 4297 | 4477 | assert(comp.c_source_files.len == 1); |
| 4298 | 4478 | const c_source_file = comp.c_source_files[0]; |
| 4299 | 4479 | |
| 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}); | |
| 4301 | 4481 | |
| 4302 | var man: Cache.Manifest = comp.obtainCObjectCacheManifest(); | |
| 4482 | var man: Cache.Manifest = comp.obtainCObjectCacheManifest(comp.root_mod); | |
| 4303 | 4483 | man.want_shared_lock = false; |
| 4304 | 4484 | defer man.deinit(); |
| 4305 | 4485 | |
| 4306 | 4486 | 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); | |
| 4308 | 4488 | Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err| { |
| 4309 | 4489 | fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) }); |
| 4310 | 4490 | }; |
| ... | ... | @@ -4313,14 +4493,14 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati |
| 4313 | 4493 | const digest = if (try man.hit()) man.final() else digest: { |
| 4314 | 4494 | if (fancy_output) |p| p.cache_hit = false; |
| 4315 | 4495 | 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] | |
| 4317 | 4497 | |
| 4318 | 4498 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); |
| 4319 | 4499 | defer zig_cache_tmp_dir.close(); |
| 4320 | 4500 | |
| 4321 | 4501 | const ext = Compilation.classifyFileExt(c_source_file.src_path); |
| 4322 | 4502 | 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()) | |
| 4324 | 4504 | break :blk null; |
| 4325 | 4505 | |
| 4326 | 4506 | 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 |
| 4330 | 4510 | }; |
| 4331 | 4511 | |
| 4332 | 4512 | // 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); | |
| 4334 | 4515 | try argv.append(c_source_file.src_path); |
| 4335 | 4516 | |
| 4336 | 4517 | if (comp.verbose_cc) { |
| 4337 | 4518 | Compilation.dump_argv(argv.items); |
| 4338 | 4519 | } |
| 4339 | 4520 | |
| 4340 | var tree = switch (comp.c_frontend) { | |
| 4521 | var tree = switch (comp.config.c_frontend) { | |
| 4341 | 4522 | .aro => tree: { |
| 4342 | 4523 | const aro = @import("aro"); |
| 4343 | 4524 | const translate_c = @import("aro_translate_c.zig"); |
| ... | ... | @@ -4385,7 +4566,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati |
| 4385 | 4566 | p.errors = errors; |
| 4386 | 4567 | return; |
| 4387 | 4568 | } else { |
| 4388 | errors.renderToStdErr(renderOptions(comp.color)); | |
| 4569 | errors.renderToStdErr(renderOptions(color)); | |
| 4389 | 4570 | process.exit(1); |
| 4390 | 4571 | } |
| 4391 | 4572 | }, |
| ... | ... | @@ -4667,9 +4848,12 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes: |
| 4667 | 4848 | while (true) { |
| 4668 | 4849 | switch (cur_includes) { |
| 4669 | 4850 | .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(); | |
| 4673 | 4857 | const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| { |
| 4674 | 4858 | if (cur_includes == .any) { |
| 4675 | 4859 | // fall back to mingw |
| ... | ... | @@ -4692,9 +4876,12 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes: |
| 4692 | 4876 | }; |
| 4693 | 4877 | }, |
| 4694 | 4878 | .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(); | |
| 4698 | 4885 | const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null); |
| 4699 | 4886 | return .{ |
| 4700 | 4887 | .include_paths = detected_libc.libc_include_dir_list, |
| ... | ... | @@ -4755,9 +4942,10 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4755 | 4942 | } |
| 4756 | 4943 | } |
| 4757 | 4944 | |
| 4758 | const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{ | |
| 4945 | const target_query = parseTargetQueryOrReportFatalError(gpa, .{ | |
| 4759 | 4946 | .arch_os_abi = target_arch_os_abi, |
| 4760 | 4947 | }); |
| 4948 | const target = resolveTargetQueryOrFatal(target_query); | |
| 4761 | 4949 | |
| 4762 | 4950 | if (print_includes) { |
| 4763 | 4951 | var arena_state = std.heap.ArenaAllocator.init(gpa); |
| ... | ... | @@ -4767,7 +4955,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4767 | 4955 | const libc_installation: ?*LibCInstallation = libc: { |
| 4768 | 4956 | if (input_file) |libc_file| { |
| 4769 | 4957 | 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| { | |
| 4771 | 4959 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4772 | 4960 | }; |
| 4773 | 4961 | break :libc libc; |
| ... | ... | @@ -4782,8 +4970,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4782 | 4970 | }; |
| 4783 | 4971 | defer zig_lib_directory.handle.close(); |
| 4784 | 4972 | |
| 4785 | const target = cross_target.toTarget(); | |
| 4786 | const is_native_abi = cross_target.isNativeAbi(); | |
| 4973 | const is_native_abi = target_query.isNativeAbi(); | |
| 4787 | 4974 | |
| 4788 | 4975 | const libc_dirs = Compilation.detectLibCIncludeDirs( |
| 4789 | 4976 | arena, |
| ... | ... | @@ -4813,20 +5000,18 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { |
| 4813 | 5000 | } |
| 4814 | 5001 | |
| 4815 | 5002 | 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| { | |
| 4817 | 5004 | fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); |
| 4818 | 5005 | }; |
| 4819 | 5006 | defer libc.deinit(gpa); |
| 4820 | 5007 | } else { |
| 4821 | if (!cross_target.isNative()) { | |
| 5008 | if (!target_query.isNative()) { | |
| 4822 | 5009 | fatal("unable to detect libc for non-native target", .{}); |
| 4823 | 5010 | } |
| 4824 | const target_info = try detectNativeTargetInfo(cross_target); | |
| 4825 | ||
| 4826 | 5011 | var libc = LibCInstallation.findNative(.{ |
| 4827 | 5012 | .allocator = gpa, |
| 4828 | 5013 | .verbose = true, |
| 4829 | .target = target_info.target, | |
| 5014 | .target = target, | |
| 4830 | 5015 | }) catch |err| { |
| 4831 | 5016 | fatal("unable to detect native libc: {s}", .{@errorName(err)}); |
| 4832 | 5017 | }; |
| ... | ... | @@ -4918,6 +5103,7 @@ pub const usage_build = |
| 4918 | 5103 | \\ --global-cache-dir [path] Override path to global Zig cache directory |
| 4919 | 5104 | \\ --zig-lib-dir [arg] Override path to Zig lib directory |
| 4920 | 5105 | \\ --build-runner [file] Override path to build runner |
| 5106 | \\ --prominent-compile-errors Buffer compile errors and display at end | |
| 4921 | 5107 | \\ --seed [integer] For shuffling dependency traversal order (default: random) |
| 4922 | 5108 | \\ --fetch Exit after fetching dependency tree |
| 4923 | 5109 | \\ -h, --help Print this help and exit |
| ... | ... | @@ -5024,7 +5210,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5024 | 5210 | if (!build_options.enable_logging) { |
| 5025 | 5211 | warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); |
| 5026 | 5212 | } else { |
| 5027 | try log_scopes.append(gpa, args[i]); | |
| 5213 | try log_scopes.append(arena, args[i]); | |
| 5028 | 5214 | } |
| 5029 | 5215 | continue; |
| 5030 | 5216 | } 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 |
| 5114 | 5300 | |
| 5115 | 5301 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 5116 | 5302 | |
| 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 | }; | |
| 5119 | 5309 | |
| 5120 | 5310 | const exe_basename = try std.zig.binNameAlloc(arena, .{ |
| 5121 | 5311 | .root_name = "build", |
| 5122 | .target = target_info.target, | |
| 5312 | .target = resolved_target.result, | |
| 5123 | 5313 | .output_mode = .Exe, |
| 5124 | 5314 | }); |
| 5125 | 5315 | const emit_bin: Compilation.EmitLoc = .{ |
| ... | ... | @@ -5130,29 +5320,62 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5130 | 5320 | try thread_pool.init(.{ .allocator = gpa }); |
| 5131 | 5321 | defer thread_pool.deinit(); |
| 5132 | 5322 | |
| 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 | }); | |
| 5148 | 5354 | |
| 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 | }, | |
| 5152 | 5363 | .fully_qualified_name = "root.@build", |
| 5153 | }; | |
| 5364 | .cc_argv = &.{}, | |
| 5365 | .inherited = .{}, | |
| 5366 | .global = config, | |
| 5367 | .parent = root_mod, | |
| 5368 | .builtin_mod = builtin_mod, | |
| 5369 | }); | |
| 5154 | 5370 | 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 | ); | |
| 5156 | 5379 | } else { |
| 5157 | 5380 | var http_client: std.http.Client = .{ .allocator = gpa }; |
| 5158 | 5381 | defer http_client.deinit(); |
| ... | ... | @@ -5196,7 +5419,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5196 | 5419 | .has_build_zig = true, |
| 5197 | 5420 | .oom_flag = false, |
| 5198 | 5421 | |
| 5199 | .module = &build_mod, | |
| 5422 | .module = build_mod, | |
| 5200 | 5423 | }; |
| 5201 | 5424 | job_queue.all_fetches.appendAssumeCapacity(&fetch); |
| 5202 | 5425 | |
| ... | ... | @@ -5225,8 +5448,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5225 | 5448 | const deps_mod = try createDependenciesModule( |
| 5226 | 5449 | arena, |
| 5227 | 5450 | source_buf.items, |
| 5228 | &main_mod, | |
| 5451 | root_mod, | |
| 5452 | global_cache_directory, | |
| 5229 | 5453 | local_cache_directory, |
| 5454 | builtin_mod, | |
| 5455 | config, | |
| 5230 | 5456 | ); |
| 5231 | 5457 | |
| 5232 | 5458 | { |
| ... | ... | @@ -5242,13 +5468,21 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5242 | 5468 | if (!f.has_build_zig) |
| 5243 | 5469 | continue; |
| 5244 | 5470 | 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 | }, | |
| 5247 | 5476 | .fully_qualified_name = try std.fmt.allocPrint( |
| 5248 | 5477 | arena, |
| 5249 | 5478 | "root.@dependencies.{s}", |
| 5250 | 5479 | .{&hash}, |
| 5251 | 5480 | ), |
| 5481 | .cc_argv = &.{}, | |
| 5482 | .inherited = .{}, | |
| 5483 | .global = config, | |
| 5484 | .parent = root_mod, | |
| 5485 | .builtin_mod = builtin_mod, | |
| 5252 | 5486 | }); |
| 5253 | 5487 | const hash_cloned = try arena.dupe(u8, &hash); |
| 5254 | 5488 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); |
| ... | ... | @@ -5276,22 +5510,18 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5276 | 5510 | } |
| 5277 | 5511 | } |
| 5278 | 5512 | |
| 5279 | try main_mod.deps.put(arena, "@build", &build_mod); | |
| 5513 | try root_mod.deps.put(arena, "@build", build_mod); | |
| 5280 | 5514 | |
| 5281 | const comp = Compilation.create(gpa, .{ | |
| 5515 | const comp = Compilation.create(gpa, arena, .{ | |
| 5282 | 5516 | .zig_lib_directory = zig_lib_directory, |
| 5283 | 5517 | .local_cache_directory = local_cache_directory, |
| 5284 | 5518 | .global_cache_directory = global_cache_directory, |
| 5285 | 5519 | .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, | |
| 5292 | 5523 | .emit_bin = emit_bin, |
| 5293 | 5524 | .emit_h = null, |
| 5294 | .optimize_mode = .Debug, | |
| 5295 | 5525 | .self_exe_path = self_exe_path, |
| 5296 | 5526 | .thread_pool = &thread_pool, |
| 5297 | 5527 | .verbose_cc = verbose_cc, |
| ... | ... | @@ -5311,17 +5541,16 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5311 | 5541 | }; |
| 5312 | 5542 | defer comp.destroy(); |
| 5313 | 5543 | |
| 5314 | updateModule(comp) catch |err| switch (err) { | |
| 5544 | updateModule(comp, color) catch |err| switch (err) { | |
| 5315 | 5545 | error.SemanticAnalyzeFail => process.exit(2), |
| 5316 | 5546 | else => |e| return e, |
| 5317 | 5547 | }; |
| 5318 | try comp.makeBinFileExecutable(); | |
| 5319 | 5548 | |
| 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.?}); | |
| 5325 | 5554 | |
| 5326 | 5555 | break :argv child_argv.items; |
| 5327 | 5556 | }; |
| ... | ... | @@ -5515,7 +5744,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 5515 | 5744 | .root_decl = .none, |
| 5516 | 5745 | }; |
| 5517 | 5746 | |
| 5518 | file.mod = try Package.Module.create(arena, .{ | |
| 5747 | file.mod = try Package.Module.createLimited(arena, .{ | |
| 5519 | 5748 | .root = Package.Path.cwd(), |
| 5520 | 5749 | .root_src_path = file.sub_file_path, |
| 5521 | 5750 | .fully_qualified_name = "root", |
| ... | ... | @@ -5725,7 +5954,7 @@ fn fmtPathFile( |
| 5725 | 5954 | .root_decl = .none, |
| 5726 | 5955 | }; |
| 5727 | 5956 | |
| 5728 | file.mod = try Package.Module.create(fmt.arena, .{ | |
| 5957 | file.mod = try Package.Module.createLimited(fmt.arena, .{ | |
| 5729 | 5958 | .root = Package.Path.cwd(), |
| 5730 | 5959 | .root_src_path = file.sub_file_path, |
| 5731 | 5960 | .fully_qualified_name = "root", |
| ... | ... | @@ -5805,15 +6034,13 @@ pub fn putAstErrorsIntoBundle( |
| 5805 | 6034 | .tree = tree, |
| 5806 | 6035 | .tree_loaded = true, |
| 5807 | 6036 | .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 | }), | |
| 5809 | 6042 | .root_decl = .none, |
| 5810 | 6043 | }; |
| 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 | }); | |
| 5817 | 6044 | defer gpa.destroy(file.mod); |
| 5818 | 6045 | |
| 5819 | 6046 | file.zir = try AstGen.generate(gpa, file.tree); |
| ... | ... | @@ -6270,10 +6497,6 @@ test "fds" { |
| 6270 | 6497 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 6271 | 6498 | } |
| 6272 | 6499 | |
| 6273 | fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo { | |
| 6274 | return std.zig.system.NativeTargetInfo.detect(cross_target); | |
| 6275 | } | |
| 6276 | ||
| 6277 | 6500 | const usage_ast_check = |
| 6278 | 6501 | \\Usage: zig ast-check [file] |
| 6279 | 6502 | \\ |
| ... | ... | @@ -6378,7 +6601,7 @@ pub fn cmdAstCheck( |
| 6378 | 6601 | file.stat.size = source.len; |
| 6379 | 6602 | } |
| 6380 | 6603 | |
| 6381 | file.mod = try Package.Module.create(arena, .{ | |
| 6604 | file.mod = try Package.Module.createLimited(arena, .{ | |
| 6382 | 6605 | .root = Package.Path.cwd(), |
| 6383 | 6606 | .root_src_path = file.sub_file_path, |
| 6384 | 6607 | .fully_qualified_name = "root", |
| ... | ... | @@ -6551,7 +6774,7 @@ pub fn cmdChangelist( |
| 6551 | 6774 | .root_decl = .none, |
| 6552 | 6775 | }; |
| 6553 | 6776 | |
| 6554 | file.mod = try Package.Module.create(arena, .{ | |
| 6777 | file.mod = try Package.Module.createLimited(arena, .{ | |
| 6555 | 6778 | .root = Package.Path.cwd(), |
| 6556 | 6779 | .root_src_path = file.sub_file_path, |
| 6557 | 6780 | .fully_qualified_name = "root", |
| ... | ... | @@ -6670,24 +6893,24 @@ fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 { |
| 6670 | 6893 | fn warnAboutForeignBinaries( |
| 6671 | 6894 | arena: Allocator, |
| 6672 | 6895 | arg_mode: ArgMode, |
| 6673 | target_info: *const std.zig.system.NativeTargetInfo, | |
| 6896 | target: *const std.Target, | |
| 6674 | 6897 | link_libc: bool, |
| 6675 | 6898 | ) !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); | |
| 6678 | 6901 | |
| 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 })) { | |
| 6680 | 6903 | .native => return, |
| 6681 | 6904 | .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); | |
| 6684 | 6907 | warn("the host system ({s}) does not appear to be capable of executing binaries from the target ({s}). Consider installing Rosetta.", .{ |
| 6685 | 6908 | host_name, foreign_name, |
| 6686 | 6909 | }); |
| 6687 | 6910 | }, |
| 6688 | 6911 | .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); | |
| 6691 | 6914 | switch (arg_mode) { |
| 6692 | 6915 | .zig_test => warn( |
| 6693 | 6916 | "the host system ({s}) does not appear to be capable of executing binaries " ++ |
| ... | ... | @@ -6703,8 +6926,8 @@ fn warnAboutForeignBinaries( |
| 6703 | 6926 | } |
| 6704 | 6927 | }, |
| 6705 | 6928 | .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); | |
| 6708 | 6931 | switch (arg_mode) { |
| 6709 | 6932 | .zig_test => warn( |
| 6710 | 6933 | "the host system ({s}) does not appear to be capable of executing binaries " ++ |
| ... | ... | @@ -6720,8 +6943,8 @@ fn warnAboutForeignBinaries( |
| 6720 | 6943 | } |
| 6721 | 6944 | }, |
| 6722 | 6945 | .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); | |
| 6725 | 6948 | switch (arg_mode) { |
| 6726 | 6949 | .zig_test => warn( |
| 6727 | 6950 | "the host system ({s}) does not appear to be capable of executing binaries " ++ |
| ... | ... | @@ -6737,8 +6960,8 @@ fn warnAboutForeignBinaries( |
| 6737 | 6960 | } |
| 6738 | 6961 | }, |
| 6739 | 6962 | .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); | |
| 6742 | 6965 | switch (arg_mode) { |
| 6743 | 6966 | .zig_test => warn( |
| 6744 | 6967 | "the host system ({s}) does not appear to be capable of executing binaries " ++ |
| ... | ... | @@ -6754,7 +6977,7 @@ fn warnAboutForeignBinaries( |
| 6754 | 6977 | } |
| 6755 | 6978 | }, |
| 6756 | 6979 | .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)"; | |
| 6758 | 6981 | const tip_suffix = switch (arg_mode) { |
| 6759 | 6982 | .zig_test => ", '--test-no-exec', or '--test-cmd'", |
| 6760 | 6983 | else => "", |
| ... | ... | @@ -6764,8 +6987,8 @@ fn warnAboutForeignBinaries( |
| 6764 | 6987 | }); |
| 6765 | 6988 | }, |
| 6766 | 6989 | .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); | |
| 6769 | 6992 | const tip_suffix = switch (arg_mode) { |
| 6770 | 6993 | .zig_test => ". Consider using '--test-no-exec' or '--test-cmd'", |
| 6771 | 6994 | else => "", |
| ... | ... | @@ -6814,18 +7037,22 @@ fn parseSubSystem(next_arg: []const u8) !std.Target.SubSystem { |
| 6814 | 7037 | /// Silently ignore superfluous search dirs. |
| 6815 | 7038 | /// Warn when a dir is added to multiple searchlists. |
| 6816 | 7039 | const ClangSearchSanitizer = struct { |
| 6817 | argv: *std.ArrayList([]const u8), | |
| 6818 | map: std.StringHashMap(Membership), | |
| 7040 | map: std.StringHashMapUnmanaged(Membership) = .{}, | |
| 6819 | 7041 | |
| 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(); | |
| 6825 | 7044 | } |
| 6826 | 7045 | |
| 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); | |
| 6829 | 7056 | const m = gopr.value_ptr; |
| 6830 | 7057 | if (!gopr.found_existing) { |
| 6831 | 7058 | // init empty membership |
| ... | ... | @@ -6872,8 +7099,9 @@ const ClangSearchSanitizer = struct { |
| 6872 | 7099 | if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" }); |
| 6873 | 7100 | }, |
| 6874 | 7101 | } |
| 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); | |
| 6877 | 7105 | } |
| 6878 | 7106 | |
| 6879 | 7107 | const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot }; |
| ... | ... | @@ -7249,11 +7477,22 @@ fn cmdFetch( |
| 7249 | 7477 | fn createEmptyDependenciesModule( |
| 7250 | 7478 | arena: Allocator, |
| 7251 | 7479 | main_mod: *Package.Module, |
| 7480 | global_cache_directory: Cache.Directory, | |
| 7252 | 7481 | local_cache_directory: Cache.Directory, |
| 7482 | builtin_mod: *Package.Module, | |
| 7483 | global_options: Compilation.Config, | |
| 7253 | 7484 | ) !void { |
| 7254 | 7485 | var source = std.ArrayList(u8).init(arena); |
| 7255 | 7486 | 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 | ); | |
| 7257 | 7496 | } |
| 7258 | 7497 | |
| 7259 | 7498 | /// Creates the dependencies.zig file and corresponding `Package.Module` for the |
| ... | ... | @@ -7262,7 +7501,10 @@ fn createDependenciesModule( |
| 7262 | 7501 | arena: Allocator, |
| 7263 | 7502 | source: []const u8, |
| 7264 | 7503 | main_mod: *Package.Module, |
| 7504 | global_cache_directory: Cache.Directory, | |
| 7265 | 7505 | local_cache_directory: Cache.Directory, |
| 7506 | builtin_mod: *Package.Module, | |
| 7507 | global_options: Compilation.Config, | |
| 7266 | 7508 | ) !*Package.Module { |
| 7267 | 7509 | // Atomically create the file in a directory named after the hash of its contents. |
| 7268 | 7510 | const basename = "dependencies.zig"; |
| ... | ... | @@ -7288,25 +7530,25 @@ fn createDependenciesModule( |
| 7288 | 7530 | ); |
| 7289 | 7531 | |
| 7290 | 7532 | 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, | |
| 7294 | 7540 | }, |
| 7295 | .root_src_path = basename, | |
| 7296 | 7541 | .fully_qualified_name = "root.@dependencies", |
| 7542 | .parent = main_mod, | |
| 7543 | .builtin_mod = builtin_mod, | |
| 7544 | .cc_argv = &.{}, | |
| 7545 | .inherited = .{}, | |
| 7546 | .global = global_options, | |
| 7297 | 7547 | }); |
| 7298 | 7548 | try main_mod.deps.put(arena, "@dependencies", deps_mod); |
| 7299 | 7549 | return deps_mod; |
| 7300 | 7550 | } |
| 7301 | 7551 | |
| 7302 | fn 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 | ||
| 7310 | 7552 | const BuildRoot = struct { |
| 7311 | 7553 | directory: Cache.Directory, |
| 7312 | 7554 | build_zig_basename: []const u8, |
| ... | ... | @@ -7514,3 +7756,28 @@ fn findTemplates(gpa: Allocator, arena: Allocator) Templates { |
| 7514 | 7756 | .buffer = std.ArrayList(u8).init(gpa), |
| 7515 | 7757 | }; |
| 7516 | 7758 | } |
| 7759 | ||
| 7760 | fn 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 | ||
| 7765 | fn 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 | ||
| 7770 | fn 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 | ||
| 7775 | fn 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 | ||
| 7780 | fn 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 |
| 41 | 41 | //"-D_UNICODE", |
| 42 | 42 | //"-DWPRFLAG=1", |
| 43 | 43 | }); |
| 44 | return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &.{ | |
| 44 | var files = [_]Compilation.CSourceFile{ | |
| 45 | 45 | .{ |
| 46 | 46 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 47 | 47 | "libc", "mingw", "crt", "crtexe.c", |
| 48 | 48 | }), |
| 49 | 49 | .extra_flags = args.items, |
| 50 | .owner = undefined, | |
| 50 | 51 | }, |
| 51 | }); | |
| 52 | }; | |
| 53 | return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files); | |
| 52 | 54 | }, |
| 53 | 55 | |
| 54 | 56 | .dllcrt2_o => { |
| ... | ... | @@ -60,14 +62,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 60 | 62 | "-U__CRTDLL__", |
| 61 | 63 | "-D__MSVCRT__", |
| 62 | 64 | }); |
| 63 | return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &.{ | |
| 65 | var files = [_]Compilation.CSourceFile{ | |
| 64 | 66 | .{ |
| 65 | 67 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 66 | 68 | "libc", "mingw", "crt", "crtdll.c", |
| 67 | 69 | }), |
| 68 | 70 | .extra_flags = args.items, |
| 71 | .owner = undefined, | |
| 69 | 72 | }, |
| 70 | }); | |
| 73 | }; | |
| 74 | return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files); | |
| 71 | 75 | }, |
| 72 | 76 | |
| 73 | 77 | .mingw32_lib => { |
| ... | ... | @@ -97,6 +101,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 97 | 101 | "libc", "mingw", "crt", dep, |
| 98 | 102 | }), |
| 99 | 103 | .extra_flags = args.items, |
| 104 | .owner = undefined, | |
| 100 | 105 | }; |
| 101 | 106 | } |
| 102 | 107 | 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 |
| 125 | 130 | (try c_source_files.addOne()).* = .{ |
| 126 | 131 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep }), |
| 127 | 132 | .extra_flags = extra_flags, |
| 133 | .owner = undefined, | |
| 128 | 134 | }; |
| 129 | 135 | } |
| 130 | 136 | if (comp.getTarget().cpu.arch == .x86) { |
| ... | ... | @@ -134,6 +140,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 134 | 140 | "libc", "mingw", dep, |
| 135 | 141 | }), |
| 136 | 142 | .extra_flags = extra_flags, |
| 143 | .owner = undefined, | |
| 137 | 144 | }; |
| 138 | 145 | } |
| 139 | 146 | } else { |
| ... | ... | @@ -143,6 +150,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 143 | 150 | "libc", "mingw", dep, |
| 144 | 151 | }), |
| 145 | 152 | .extra_flags = extra_flags, |
| 153 | .owner = undefined, | |
| 146 | 154 | }; |
| 147 | 155 | } |
| 148 | 156 | } |
| ... | ... | @@ -175,6 +183,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 175 | 183 | "libc", "mingw", dep, |
| 176 | 184 | }), |
| 177 | 185 | .extra_flags = extra_flags, |
| 186 | .owner = undefined, | |
| 178 | 187 | }; |
| 179 | 188 | } |
| 180 | 189 | const target = comp.getTarget(); |
| ... | ... | @@ -185,6 +194,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 185 | 194 | "libc", "mingw", dep, |
| 186 | 195 | }), |
| 187 | 196 | .extra_flags = extra_flags, |
| 197 | .owner = undefined, | |
| 188 | 198 | }; |
| 189 | 199 | } |
| 190 | 200 | } else if (target.cpu.arch.isARM()) { |
| ... | ... | @@ -194,6 +204,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 194 | 204 | "libc", "mingw", dep, |
| 195 | 205 | }), |
| 196 | 206 | .extra_flags = extra_flags, |
| 207 | .owner = undefined, | |
| 197 | 208 | }; |
| 198 | 209 | } |
| 199 | 210 | } else if (target.cpu.arch.isAARCH64()) { |
| ... | ... | @@ -203,6 +214,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 203 | 214 | "libc", "mingw", dep, |
| 204 | 215 | }), |
| 205 | 216 | .extra_flags = extra_flags, |
| 217 | .owner = undefined, | |
| 206 | 218 | }; |
| 207 | 219 | } |
| 208 | 220 | } else { |
| ... | ... | @@ -238,6 +250,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 238 | 250 | "libc", "mingw", "libsrc", dep, |
| 239 | 251 | }), |
| 240 | 252 | .extra_flags = extra_flags, |
| 253 | .owner = undefined, | |
| 241 | 254 | }; |
| 242 | 255 | } |
| 243 | 256 | return comp.build_crt_file("uuid", .Lib, .@"mingw-w64 uuid.lib", prog_node, &c_source_files); |
| ... | ... | @@ -274,7 +287,7 @@ fn add_cc_args( |
| 274 | 287 | } |
| 275 | 288 | |
| 276 | 289 | pub 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"); | |
| 278 | 291 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
| 279 | 292 | defer arena_allocator.deinit(); |
| 280 | 293 | const arena = arena_allocator.allocator(); |
src/musl.zig+80-44| ... | ... | @@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator; |
| 3 | 3 | const mem = std.mem; |
| 4 | 4 | const path = std.fs.path; |
| 5 | 5 | const assert = std.debug.assert; |
| 6 | const Module = @import("Package/Module.zig"); | |
| 6 | 7 | |
| 7 | 8 | const Compilation = @import("Compilation.zig"); |
| 8 | 9 | const build_options = @import("build_options"); |
| ... | ... | @@ -33,12 +34,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 33 | 34 | try args.appendSlice(&[_][]const u8{ |
| 34 | 35 | "-Qunused-arguments", |
| 35 | 36 | }); |
| 36 | return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &.{ | |
| 37 | var files = [_]Compilation.CSourceFile{ | |
| 37 | 38 | .{ |
| 38 | 39 | .src_path = try start_asm_path(comp, arena, "crti.s"), |
| 39 | 40 | .extra_flags = args.items, |
| 41 | .owner = undefined, | |
| 40 | 42 | }, |
| 41 | }); | |
| 43 | }; | |
| 44 | return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &files); | |
| 42 | 45 | }, |
| 43 | 46 | .crtn_o => { |
| 44 | 47 | var args = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -46,12 +49,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 46 | 49 | try args.appendSlice(&[_][]const u8{ |
| 47 | 50 | "-Qunused-arguments", |
| 48 | 51 | }); |
| 49 | return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &.{ | |
| 52 | var files = [_]Compilation.CSourceFile{ | |
| 50 | 53 | .{ |
| 51 | 54 | .src_path = try start_asm_path(comp, arena, "crtn.s"), |
| 52 | 55 | .extra_flags = args.items, |
| 56 | .owner = undefined, | |
| 53 | 57 | }, |
| 54 | }); | |
| 58 | }; | |
| 59 | return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &files); | |
| 55 | 60 | }, |
| 56 | 61 | .crt1_o => { |
| 57 | 62 | var args = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -60,14 +65,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 60 | 65 | "-fno-stack-protector", |
| 61 | 66 | "-DCRT", |
| 62 | 67 | }); |
| 63 | return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &.{ | |
| 68 | var files = [_]Compilation.CSourceFile{ | |
| 64 | 69 | .{ |
| 65 | 70 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 66 | 71 | "libc", "musl", "crt", "crt1.c", |
| 67 | 72 | }), |
| 68 | 73 | .extra_flags = args.items, |
| 74 | .owner = undefined, | |
| 69 | 75 | }, |
| 70 | }); | |
| 76 | }; | |
| 77 | return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &files); | |
| 71 | 78 | }, |
| 72 | 79 | .rcrt1_o => { |
| 73 | 80 | var args = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -77,14 +84,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 77 | 84 | "-fno-stack-protector", |
| 78 | 85 | "-DCRT", |
| 79 | 86 | }); |
| 80 | return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &.{ | |
| 87 | var files = [_]Compilation.CSourceFile{ | |
| 81 | 88 | .{ |
| 82 | 89 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 83 | 90 | "libc", "musl", "crt", "rcrt1.c", |
| 84 | 91 | }), |
| 85 | 92 | .extra_flags = args.items, |
| 93 | .owner = undefined, | |
| 86 | 94 | }, |
| 87 | }); | |
| 95 | }; | |
| 96 | return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &files); | |
| 88 | 97 | }, |
| 89 | 98 | .scrt1_o => { |
| 90 | 99 | var args = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -94,14 +103,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 94 | 103 | "-fno-stack-protector", |
| 95 | 104 | "-DCRT", |
| 96 | 105 | }); |
| 97 | return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &.{ | |
| 106 | var files = [_]Compilation.CSourceFile{ | |
| 98 | 107 | .{ |
| 99 | 108 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 100 | 109 | "libc", "musl", "crt", "Scrt1.c", |
| 101 | 110 | }), |
| 102 | 111 | .extra_flags = args.items, |
| 112 | .owner = undefined, | |
| 103 | 113 | }, |
| 104 | }); | |
| 114 | }; | |
| 115 | return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &files); | |
| 105 | 116 | }, |
| 106 | 117 | .libc_a => { |
| 107 | 118 | // 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 |
| 185 | 196 | c_source_file.* = .{ |
| 186 | 197 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }), |
| 187 | 198 | .extra_flags = args.items, |
| 199 | .owner = undefined, | |
| 188 | 200 | }; |
| 189 | 201 | } |
| 190 | 202 | return comp.build_crt_file("c", .Lib, .@"musl libc.a", prog_node, c_source_files.items); |
| 191 | 203 | }, |
| 192 | 204 | .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; | |
| 194 | 220 | const arch_define = try std.fmt.allocPrint(arena, "-DARCH_{s}", .{ |
| 195 | 221 | @tagName(target.cpu.arch), |
| 196 | 222 | }); |
| 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 } | |
| 199 | 225 | 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 | }); | |
| 201 | 253 | |
| 202 | const sub_compilation = try Compilation.create(comp.gpa, .{ | |
| 254 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | |
| 203 | 255 | .local_cache_directory = comp.global_cache_directory, |
| 204 | 256 | .global_cache_directory = comp.global_cache_directory, |
| 205 | .cache_mode = .whole, | |
| 206 | 257 | .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, | |
| 212 | 262 | .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" }, | |
| 223 | 266 | .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, | |
| 228 | 267 | .verbose_cc = comp.verbose_cc, |
| 229 | .verbose_link = comp.bin_file.options.verbose_link, | |
| 268 | .verbose_link = comp.verbose_link, | |
| 230 | 269 | .verbose_air = comp.verbose_air, |
| 231 | 270 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 232 | 271 | .verbose_cimport = comp.verbose_cimport, |
| 233 | 272 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 234 | 273 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 235 | 274 | .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 | }, | |
| 237 | 279 | }, |
| 238 | .clang_argv = clang_argv, | |
| 239 | 280 | .skip_linker_dependencies = true, |
| 240 | 281 | .soname = "libc.so", |
| 241 | 282 | }); |
| ... | ... | @@ -248,12 +289,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 248 | 289 | const basename = try comp.gpa.dupe(u8, "libc.so"); |
| 249 | 290 | errdefer comp.gpa.free(basename); |
| 250 | 291 | |
| 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()); | |
| 257 | 293 | }, |
| 258 | 294 | } |
| 259 | 295 | } |
src/print_env.zig+2-2| ... | ... | @@ -17,8 +17,8 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr |
| 17 | 17 | |
| 18 | 18 | const global_cache_dir = try introspect.resolveGlobalCacheDir(arena); |
| 19 | 19 | |
| 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); | |
| 22 | 22 | |
| 23 | 23 | var bw = std.io.bufferedWriter(stdout); |
| 24 | 24 | const w = bw.writer(); |
src/target.zig+70-97| ... | ... | @@ -2,6 +2,9 @@ const std = @import("std"); |
| 2 | 2 | const Type = @import("type.zig").Type; |
| 3 | 3 | const AddressSpace = std.builtin.AddressSpace; |
| 4 | 4 | const Alignment = @import("InternPool.zig").Alignment; |
| 5 | const Feature = @import("Module.zig").Feature; | |
| 6 | ||
| 7 | pub const default_stack_protector_buffer_size = 4; | |
| 5 | 8 | |
| 6 | 9 | pub const ArchOsAbi = struct { |
| 7 | 10 | arch: std.Target.Cpu.Arch, |
| ... | ... | @@ -204,11 +207,18 @@ pub fn supports_fpic(target: std.Target) bool { |
| 204 | 207 | return target.os.tag != .windows and target.os.tag != .uefi; |
| 205 | 208 | } |
| 206 | 209 | |
| 207 | pub fn isSingleThreaded(target: std.Target) bool { | |
| 210 | pub fn alwaysSingleThreaded(target: std.Target) bool { | |
| 208 | 211 | _ = target; |
| 209 | 212 | return false; |
| 210 | 213 | } |
| 211 | 214 | |
| 215 | pub fn defaultSingleThreaded(target: std.Target) bool { | |
| 216 | return switch (target.cpu.arch) { | |
| 217 | .wasm32, .wasm64 => true, | |
| 218 | else => false, | |
| 219 | }; | |
| 220 | } | |
| 221 | ||
| 212 | 222 | /// Valgrind supports more, but Zig does not support them yet. |
| 213 | 223 | pub fn hasValgrindSupport(target: std.Target) bool { |
| 214 | 224 | switch (target.cpu.arch) { |
| ... | ... | @@ -314,6 +324,14 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool { |
| 314 | 324 | }; |
| 315 | 325 | } |
| 316 | 326 | |
| 327 | /// The set of targets that Zig supports using LLD to link for. | |
| 328 | pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool { | |
| 329 | return switch (ofmt) { | |
| 330 | .elf, .coff, .wasm => true, | |
| 331 | else => false, | |
| 332 | }; | |
| 333 | } | |
| 334 | ||
| 317 | 335 | /// The set of targets that our own self-hosted backends have robust support for. |
| 318 | 336 | /// Used to select between LLVM backend and self-hosted backend when compiling in |
| 319 | 337 | /// 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 |
| 343 | 361 | }; |
| 344 | 362 | } |
| 345 | 363 | |
| 364 | pub fn clangSupportsStackProtector(target: std.Target) bool { | |
| 365 | return switch (target.cpu.arch) { | |
| 366 | .spirv32, .spirv64 => return false, | |
| 367 | else => true, | |
| 368 | }; | |
| 369 | } | |
| 370 | ||
| 346 | 371 | pub fn libcProvidesStackProtector(target: std.Target) bool { |
| 347 | 372 | return !target.isMinGW() and target.os.tag != .wasi and !target.isSpirV(); |
| 348 | 373 | } |
| ... | ... | @@ -356,96 +381,6 @@ pub fn supportsReturnAddress(target: std.Target) bool { |
| 356 | 381 | }; |
| 357 | 382 | } |
| 358 | 383 | |
| 359 | fn 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 | ||
| 367 | pub 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 | ||
| 441 | pub 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 | ||
| 449 | 384 | pub const CompilerRtClassification = enum { none, only_compiler_rt, only_libunwind, both }; |
| 450 | 385 | |
| 451 | 386 | pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerRtClassification { |
| ... | ... | @@ -465,12 +400,16 @@ pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerR |
| 465 | 400 | } |
| 466 | 401 | |
| 467 | 402 | pub 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 | }; | |
| 474 | 413 | } |
| 475 | 414 | |
| 476 | 415 | pub fn defaultCompilerRtOptimizeMode(target: std.Target) std.builtin.OptimizeMode { |
| ... | ... | @@ -709,3 +648,37 @@ pub fn fnCallConvAllowsZigTypes(target: std.Target, cc: std.builtin.CallingConve |
| 709 | 648 | else => false, |
| 710 | 649 | }; |
| 711 | 650 | } |
| 651 | ||
| 652 | pub 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 | ||
| 668 | pub 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 |
| 74 | 74 | var args = std.ArrayList([]const u8).init(arena); |
| 75 | 75 | try addCCArgs(comp, arena, &args, .{}); |
| 76 | 76 | 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{ | |
| 78 | 78 | .{ |
| 79 | 79 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 80 | 80 | "libc", try sanitize(arena, crt1_reactor_src_file), |
| 81 | 81 | }), |
| 82 | 82 | .extra_flags = args.items, |
| 83 | .owner = undefined, | |
| 83 | 84 | }, |
| 84 | }); | |
| 85 | }; | |
| 86 | return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files); | |
| 85 | 87 | }, |
| 86 | 88 | .crt1_command_o => { |
| 87 | 89 | var args = std.ArrayList([]const u8).init(arena); |
| 88 | 90 | try addCCArgs(comp, arena, &args, .{}); |
| 89 | 91 | 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{ | |
| 91 | 93 | .{ |
| 92 | 94 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 93 | 95 | "libc", try sanitize(arena, crt1_command_src_file), |
| 94 | 96 | }), |
| 95 | 97 | .extra_flags = args.items, |
| 98 | .owner = undefined, | |
| 96 | 99 | }, |
| 97 | }); | |
| 100 | }; | |
| 101 | return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files); | |
| 98 | 102 | }, |
| 99 | 103 | .libc_a => { |
| 100 | 104 | 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 |
| 109 | 113 | "libc", try sanitize(arena, file_path), |
| 110 | 114 | }), |
| 111 | 115 | .extra_flags = args.items, |
| 116 | .owner = undefined, | |
| 112 | 117 | }); |
| 113 | 118 | } |
| 114 | 119 | } |
| ... | ... | @@ -125,6 +130,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 125 | 130 | "libc", try sanitize(arena, file_path), |
| 126 | 131 | }), |
| 127 | 132 | .extra_flags = args.items, |
| 133 | .owner = undefined, | |
| 128 | 134 | }); |
| 129 | 135 | } |
| 130 | 136 | } |
| ... | ... | @@ -141,6 +147,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 141 | 147 | "libc", try sanitize(arena, file_path), |
| 142 | 148 | }), |
| 143 | 149 | .extra_flags = args.items, |
| 150 | .owner = undefined, | |
| 144 | 151 | }); |
| 145 | 152 | } |
| 146 | 153 | } |
| ... | ... | @@ -159,6 +166,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 159 | 166 | "libc", try sanitize(arena, file_path), |
| 160 | 167 | }), |
| 161 | 168 | .extra_flags = args.items, |
| 169 | .owner = undefined, | |
| 162 | 170 | }); |
| 163 | 171 | } |
| 164 | 172 | 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 |
| 175 | 183 | "libc", try sanitize(arena, file_path), |
| 176 | 184 | }), |
| 177 | 185 | .extra_flags = args.items, |
| 186 | .owner = undefined, | |
| 178 | 187 | }); |
| 179 | 188 | } |
| 180 | 189 | 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 |
| 191 | 200 | "libc", try sanitize(arena, file_path), |
| 192 | 201 | }), |
| 193 | 202 | .extra_flags = args.items, |
| 203 | .owner = undefined, | |
| 194 | 204 | }); |
| 195 | 205 | } |
| 196 | 206 | 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 |
| 208 | 218 | "libc", try sanitize(arena, file_path), |
| 209 | 219 | }), |
| 210 | 220 | .extra_flags = args.items, |
| 221 | .owner = undefined, | |
| 211 | 222 | }); |
| 212 | 223 | } |
| 213 | 224 | } |
| ... | ... | @@ -224,6 +235,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr |
| 224 | 235 | "libc", try sanitize(arena, file_path), |
| 225 | 236 | }), |
| 226 | 237 | .extra_flags = args.items, |
| 238 | .owner = undefined, | |
| 227 | 239 | }); |
| 228 | 240 | } |
| 229 | 241 | } |
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" { |
| 876 | 876 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 877 | 877 | |
| 878 | 878 | const S = struct { |
| 879 | const CrossTarget = struct { | |
| 880 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 879 | const A = struct { | |
| 880 | c: B = B{}, | |
| 881 | 881 | |
| 882 | pub fn parse() void { | |
| 883 | var result: CrossTarget = .{}; | |
| 884 | result.getCpuArch(); | |
| 882 | pub fn d() void { | |
| 883 | var f: A = .{}; | |
| 884 | f.e(); | |
| 885 | 885 | } |
| 886 | 886 | |
| 887 | pub fn getCpuArch(self: CrossTarget) void { | |
| 888 | _ = self; | |
| 887 | pub fn e(g: A) void { | |
| 888 | _ = g; | |
| 889 | 889 | } |
| 890 | 890 | }; |
| 891 | 891 | |
| 892 | const DynamicLinker = struct { | |
| 892 | const B = struct { | |
| 893 | 893 | buffer: [255]u8 = undefined, |
| 894 | 894 | }; |
| 895 | 895 | }; |
| 896 | 896 | |
| 897 | 897 | comptime { |
| 898 | S.CrossTarget.parse(); | |
| 899 | S.CrossTarget.parse(); | |
| 898 | S.A.d(); | |
| 899 | S.A.d(); | |
| 900 | 900 | } |
| 901 | 901 | } |
| 902 | 902 |
test/cases.zig+5-5| ... | ... | @@ -9,9 +9,9 @@ pub const BuildOptions = struct { |
| 9 | 9 | llvm_has_xtensa: bool, |
| 10 | 10 | }; |
| 11 | 11 | |
| 12 | pub 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); | |
| 12 | pub 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); | |
| 17 | 17 | } |
test/cbe.zig+24-24| ... | ... | @@ -2,16 +2,16 @@ const std = @import("std"); |
| 2 | 2 | const Cases = @import("src/Cases.zig"); |
| 3 | 3 | const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; |
| 4 | 4 | |
| 5 | // These tests should work with all platforms, but we're using linux_x64 for | |
| 6 | // now for consistency. Will be expanded eventually. | |
| 7 | const linux_x64 = std.zig.CrossTarget{ | |
| 8 | .cpu_arch = .x86_64, | |
| 9 | .os_tag = .linux, | |
| 10 | }; | |
| 11 | ||
| 12 | pub fn addCases(ctx: *Cases) !void { | |
| 5 | pub 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 | ||
| 13 | 13 | { |
| 14 | var case = ctx.exeFromCompiledC("hello world with updates", .{}); | |
| 14 | var case = ctx.exeFromCompiledC("hello world with updates", .{}, b); | |
| 15 | 15 | |
| 16 | 16 | // Regular old hello world |
| 17 | 17 | case.addCompareOutput( |
| ... | ... | @@ -59,7 +59,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | { |
| 62 | var case = ctx.exeFromCompiledC("var args", .{}); | |
| 62 | var case = ctx.exeFromCompiledC("var args", .{}, b); | |
| 63 | 63 | |
| 64 | 64 | case.addCompareOutput( |
| 65 | 65 | \\extern fn printf(format: [*:0]const u8, ...) c_int; |
| ... | ... | @@ -72,7 +72,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | { |
| 75 | var case = ctx.exeFromCompiledC("errorFromInt", .{}); | |
| 75 | var case = ctx.exeFromCompiledC("errorFromInt", .{}, b); | |
| 76 | 76 | |
| 77 | 77 | case.addCompareOutput( |
| 78 | 78 | \\pub export fn main() c_int { |
| ... | ... | @@ -108,7 +108,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | { |
| 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); | |
| 112 | 112 | |
| 113 | 113 | // Exit with 0 |
| 114 | 114 | case.addCompareOutput( |
| ... | ... | @@ -202,7 +202,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 202 | 202 | } |
| 203 | 203 | |
| 204 | 204 | { |
| 205 | var case = ctx.exeFromCompiledC("alloc and retptr", .{}); | |
| 205 | var case = ctx.exeFromCompiledC("alloc and retptr", .{}, b); | |
| 206 | 206 | |
| 207 | 207 | case.addCompareOutput( |
| 208 | 208 | \\fn add(a: i32, b: i32) i32 { |
| ... | ... | @@ -220,7 +220,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | { |
| 223 | var case = ctx.exeFromCompiledC("inferred local const and var", .{}); | |
| 223 | var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b); | |
| 224 | 224 | |
| 225 | 225 | case.addCompareOutput( |
| 226 | 226 | \\fn add(a: i32, b: i32) i32 { |
| ... | ... | @@ -236,7 +236,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 236 | 236 | , ""); |
| 237 | 237 | } |
| 238 | 238 | { |
| 239 | var case = ctx.exeFromCompiledC("control flow", .{}); | |
| 239 | var case = ctx.exeFromCompiledC("control flow", .{}, b); | |
| 240 | 240 | |
| 241 | 241 | // Simple while loop |
| 242 | 242 | case.addCompareOutput( |
| ... | ... | @@ -423,7 +423,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 423 | 423 | }); |
| 424 | 424 | } |
| 425 | 425 | //{ |
| 426 | // var case = ctx.exeFromCompiledC("optionals", .{}); | |
| 426 | // var case = ctx.exeFromCompiledC("optionals", .{}, b); | |
| 427 | 427 | |
| 428 | 428 | // // Simple while loop |
| 429 | 429 | // case.addCompareOutput( |
| ... | ... | @@ -451,7 +451,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 451 | 451 | //} |
| 452 | 452 | |
| 453 | 453 | { |
| 454 | var case = ctx.exeFromCompiledC("errors", .{}); | |
| 454 | var case = ctx.exeFromCompiledC("errors", .{}, b); | |
| 455 | 455 | case.addCompareOutput( |
| 456 | 456 | \\pub export fn main() c_int { |
| 457 | 457 | \\ var e1 = error.Foo; |
| ... | ... | @@ -495,7 +495,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 495 | 495 | } |
| 496 | 496 | |
| 497 | 497 | { |
| 498 | var case = ctx.exeFromCompiledC("structs", .{}); | |
| 498 | var case = ctx.exeFromCompiledC("structs", .{}, b); | |
| 499 | 499 | case.addError( |
| 500 | 500 | \\const Point = struct { x: i32, y: i32 }; |
| 501 | 501 | \\pub export fn main() c_int { |
| ... | ... | @@ -562,7 +562,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | 564 | { |
| 565 | var case = ctx.exeFromCompiledC("unions", .{}); | |
| 565 | var case = ctx.exeFromCompiledC("unions", .{}, b); | |
| 566 | 566 | |
| 567 | 567 | case.addError( |
| 568 | 568 | \\const U = union { |
| ... | ... | @@ -596,7 +596,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 596 | 596 | } |
| 597 | 597 | |
| 598 | 598 | { |
| 599 | var case = ctx.exeFromCompiledC("enums", .{}); | |
| 599 | var case = ctx.exeFromCompiledC("enums", .{}, b); | |
| 600 | 600 | |
| 601 | 601 | case.addError( |
| 602 | 602 | \\const E1 = packed enum { a, b, c }; |
| ... | ... | @@ -838,7 +838,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 838 | 838 | } |
| 839 | 839 | |
| 840 | 840 | { |
| 841 | var case = ctx.exeFromCompiledC("shift right and left", .{}); | |
| 841 | var case = ctx.exeFromCompiledC("shift right and left", .{}, b); | |
| 842 | 842 | case.addCompareOutput( |
| 843 | 843 | \\pub export fn main() c_int { |
| 844 | 844 | \\ var i: u32 = 16; |
| ... | ... | @@ -863,7 +863,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 863 | 863 | } |
| 864 | 864 | |
| 865 | 865 | { |
| 866 | var case = ctx.exeFromCompiledC("inferred error sets", .{}); | |
| 866 | var case = ctx.exeFromCompiledC("inferred error sets", .{}, b); | |
| 867 | 867 | |
| 868 | 868 | case.addCompareOutput( |
| 869 | 869 | \\pub export fn main() c_int { |
| ... | ... | @@ -884,7 +884,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 884 | 884 | |
| 885 | 885 | { |
| 886 | 886 | // 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); | |
| 888 | 888 | case.addCompareOutput( |
| 889 | 889 | \\pub export fn main() c_int { |
| 890 | 890 | \\ // Addition |
| ... | ... | @@ -933,7 +933,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 933 | 933 | } |
| 934 | 934 | |
| 935 | 935 | { |
| 936 | var case = ctx.exeFromCompiledC("rem", linux_x64); | |
| 936 | var case = ctx.exeFromCompiledC("rem", linux_x64, b); | |
| 937 | 937 | case.addCompareOutput( |
| 938 | 938 | \\fn assert(ok: bool) void { |
| 939 | 939 | \\ if (!ok) unreachable; |
test/compile_errors.zig+11-11| ... | ... | @@ -2,9 +2,9 @@ const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const Cases = @import("src/Cases.zig"); |
| 4 | 4 | |
| 5 | pub fn addCases(ctx: *Cases) !void { | |
| 5 | pub fn addCases(ctx: *Cases, b: *std.Build) !void { | |
| 6 | 6 | { |
| 7 | const case = ctx.obj("multiline error messages", .{}); | |
| 7 | const case = ctx.obj("multiline error messages", b.host); | |
| 8 | 8 | |
| 9 | 9 | case.addError( |
| 10 | 10 | \\comptime { |
| ... | ... | @@ -39,7 +39,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | { |
| 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); | |
| 43 | 43 | |
| 44 | 44 | case.addError("const foo = \\\\\test\r\r rogue carriage return\n;", &[_][]const u8{ |
| 45 | 45 | ":1:19: error: expected ';' after declaration", |
| ... | ... | @@ -48,7 +48,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | { |
| 51 | const case = ctx.obj("missing semicolon at EOF", .{}); | |
| 51 | const case = ctx.obj("missing semicolon at EOF", b.host); | |
| 52 | 52 | case.addError( |
| 53 | 53 | \\const foo = 1 |
| 54 | 54 | , &[_][]const u8{ |
| ... | ... | @@ -57,7 +57,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | { |
| 60 | const case = ctx.obj("argument causes error", .{}); | |
| 60 | const case = ctx.obj("argument causes error", b.host); | |
| 61 | 61 | |
| 62 | 62 | case.addError( |
| 63 | 63 | \\pub export fn entry() void { |
| ... | ... | @@ -80,7 +80,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | { |
| 83 | const case = ctx.obj("astgen failure in file struct", .{}); | |
| 83 | const case = ctx.obj("astgen failure in file struct", b.host); | |
| 84 | 84 | |
| 85 | 85 | case.addError( |
| 86 | 86 | \\pub export fn entry() void { |
| ... | ... | @@ -95,7 +95,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | { |
| 98 | const case = ctx.obj("invalid store to comptime field", .{}); | |
| 98 | const case = ctx.obj("invalid store to comptime field", b.host); | |
| 99 | 99 | |
| 100 | 100 | case.addError( |
| 101 | 101 | \\const a = @import("a.zig"); |
| ... | ... | @@ -119,7 +119,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 119 | 119 | } |
| 120 | 120 | |
| 121 | 121 | { |
| 122 | const case = ctx.obj("file in multiple modules", .{}); | |
| 122 | const case = ctx.obj("file in multiple modules", b.host); | |
| 123 | 123 | case.addDepModule("foo", "foo.zig"); |
| 124 | 124 | |
| 125 | 125 | case.addError( |
| ... | ... | @@ -138,7 +138,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | { |
| 141 | const case = ctx.obj("wrong same named struct", .{}); | |
| 141 | const case = ctx.obj("wrong same named struct", b.host); | |
| 142 | 142 | |
| 143 | 143 | case.addError( |
| 144 | 144 | \\const a = @import("a.zig"); |
| ... | ... | @@ -172,7 +172,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | 174 | { |
| 175 | const case = ctx.obj("non-printable invalid character", .{}); | |
| 175 | const case = ctx.obj("non-printable invalid character", b.host); | |
| 176 | 176 | |
| 177 | 177 | case.addError("\xff\xfe" ++ |
| 178 | 178 | \\export fn foo() bool { |
| ... | ... | @@ -185,7 +185,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | { |
| 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); | |
| 189 | 189 | |
| 190 | 190 | case.addError( |
| 191 | 191 | \\pub const import = @import("import.zig"); |
test/link/bss/build.zig+1| ... | ... | @@ -7,6 +7,7 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | const exe = b.addExecutable(.{ |
| 8 | 8 | .name = "bss", |
| 9 | 9 | .root_source_file = .{ .path = "main.zig" }, |
| 10 | .target = b.host, | |
| 10 | 11 | .optimize = .Debug, |
| 11 | 12 | }); |
| 12 | 13 |
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 |
| 14 | 14 | const lib_a = b.addStaticLibrary(.{ |
| 15 | 15 | .name = "a", |
| 16 | 16 | .optimize = optimize, |
| 17 | .target = .{}, | |
| 17 | .target = b.host, | |
| 18 | 18 | }); |
| 19 | 19 | lib_a.addCSourceFiles(.{ |
| 20 | 20 | .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 |
| 14 | 14 | const lib_a = b.addStaticLibrary(.{ |
| 15 | 15 | .name = "a", |
| 16 | 16 | .optimize = optimize, |
| 17 | .target = .{}, | |
| 17 | .target = b.host, | |
| 18 | 18 | }); |
| 19 | 19 | lib_a.addCSourceFiles(.{ |
| 20 | 20 | .files = &.{"a.c"}, |
test/link/elf.zig+664-446| ... | ... | @@ -5,20 +5,20 @@ |
| 5 | 5 | pub fn testAll(b: *Build) *Step { |
| 6 | 6 | const elf_step = b.step("test-elf", "Run ELF tests"); |
| 7 | 7 | |
| 8 | const default_target = CrossTarget{ | |
| 8 | const default_target = b.resolveTargetQuery(.{ | |
| 9 | 9 | .cpu_arch = .x86_64, // TODO relax this once ELF linker is able to handle other archs |
| 10 | 10 | .os_tag = .linux, |
| 11 | }; | |
| 12 | const musl_target = CrossTarget{ | |
| 11 | }); | |
| 12 | const musl_target = b.resolveTargetQuery(.{ | |
| 13 | 13 | .cpu_arch = .x86_64, |
| 14 | 14 | .os_tag = .linux, |
| 15 | 15 | .abi = .musl, |
| 16 | }; | |
| 17 | const glibc_target = CrossTarget{ | |
| 16 | }); | |
| 17 | const glibc_target = b.resolveTargetQuery(.{ | |
| 18 | 18 | .cpu_arch = .x86_64, |
| 19 | 19 | .os_tag = .linux, |
| 20 | 20 | .abi = .gnu, |
| 21 | }; | |
| 21 | }); | |
| 22 | 22 | |
| 23 | 23 | // Exercise linker in -r mode |
| 24 | 24 | elf_step.dependOn(testEmitRelocatable(b, .{ .use_llvm = false, .target = musl_target })); |
| ... | ... | @@ -132,14 +132,18 @@ pub fn testAll(b: *Build) *Step { |
| 132 | 132 | fn testAbsSymbols(b: *Build, opts: Options) *Step { |
| 133 | 133 | const test_step = addTestStep(b, "abs-symbols", opts); |
| 134 | 134 | |
| 135 | const obj = addObject(b, "obj", opts); | |
| 136 | addAsmSourceBytes(obj, | |
| 135 | const obj = addObject(b, opts, .{ | |
| 136 | .name = "obj", | |
| 137 | .asm_source_bytes = | |
| 137 | 138 | \\.globl foo |
| 138 | 139 | \\foo = 0x800008 |
| 139 | ); | |
| 140 | \\ | |
| 141 | , | |
| 142 | }); | |
| 140 | 143 | |
| 141 | const exe = addExecutable(b, "test", opts); | |
| 142 | addCSourceBytes(exe, | |
| 144 | const exe = addExecutable(b, opts, .{ | |
| 145 | .name = "test", | |
| 146 | .c_source_bytes = | |
| 143 | 147 | \\#include <signal.h> |
| 144 | 148 | \\#include <stdio.h> |
| 145 | 149 | \\#include <stdlib.h> |
| ... | ... | @@ -159,7 +163,8 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step { |
| 159 | 163 | \\ foo = 5; |
| 160 | 164 | \\ return 0; |
| 161 | 165 | \\} |
| 162 | , &.{}); | |
| 166 | , | |
| 167 | }); | |
| 163 | 168 | exe.addObject(obj); |
| 164 | 169 | exe.linkLibC(); |
| 165 | 170 | |
| ... | ... | @@ -173,31 +178,36 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step { |
| 173 | 178 | fn testAsNeeded(b: *Build, opts: Options) *Step { |
| 174 | 179 | const test_step = addTestStep(b, "as-needed", opts); |
| 175 | 180 | |
| 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 = | |
| 178 | 184 | \\#include <stdio.h> |
| 179 | 185 | \\int baz(); |
| 180 | 186 | \\int main() { |
| 181 | 187 | \\ printf("%d\n", baz()); |
| 182 | 188 | \\ return 0; |
| 183 | 189 | \\} |
| 184 | , &.{}); | |
| 190 | \\ | |
| 191 | , | |
| 192 | }); | |
| 185 | 193 | main_o.linkLibC(); |
| 186 | 194 | |
| 187 | const libfoo = addSharedLibrary(b, "foo", opts); | |
| 195 | const libfoo = addSharedLibrary(b, opts, .{ .name = "foo" }); | |
| 188 | 196 | addCSourceBytes(libfoo, "int foo() { return 42; }", &.{}); |
| 189 | 197 | |
| 190 | const libbar = addSharedLibrary(b, "bar", opts); | |
| 198 | const libbar = addSharedLibrary(b, opts, .{ .name = "bar" }); | |
| 191 | 199 | addCSourceBytes(libbar, "int bar() { return 42; }", &.{}); |
| 192 | 200 | |
| 193 | const libbaz = addSharedLibrary(b, "baz", opts); | |
| 201 | const libbaz = addSharedLibrary(b, opts, .{ .name = "baz" }); | |
| 194 | 202 | addCSourceBytes(libbaz, |
| 195 | 203 | \\int foo(); |
| 196 | 204 | \\int baz() { return foo(); } |
| 197 | 205 | , &.{}); |
| 198 | 206 | |
| 199 | 207 | { |
| 200 | const exe = addExecutable(b, "test", opts); | |
| 208 | const exe = addExecutable(b, opts, .{ | |
| 209 | .name = "test", | |
| 210 | }); | |
| 201 | 211 | exe.addObject(main_o); |
| 202 | 212 | exe.linkSystemLibrary2("foo", .{ .needed = true }); |
| 203 | 213 | exe.addLibraryPath(libfoo.getEmittedBinDirectory()); |
| ... | ... | @@ -225,7 +235,9 @@ fn testAsNeeded(b: *Build, opts: Options) *Step { |
| 225 | 235 | } |
| 226 | 236 | |
| 227 | 237 | { |
| 228 | const exe = addExecutable(b, "test", opts); | |
| 238 | const exe = addExecutable(b, opts, .{ | |
| 239 | .name = "test", | |
| 240 | }); | |
| 229 | 241 | exe.addObject(main_o); |
| 230 | 242 | exe.linkSystemLibrary2("foo", .{ .needed = false }); |
| 231 | 243 | exe.addLibraryPath(libfoo.getEmittedBinDirectory()); |
| ... | ... | @@ -259,7 +271,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step { |
| 259 | 271 | fn testCanonicalPlt(b: *Build, opts: Options) *Step { |
| 260 | 272 | const test_step = addTestStep(b, "canonical-plt", opts); |
| 261 | 273 | |
| 262 | const dso = addSharedLibrary(b, "a", opts); | |
| 274 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 263 | 275 | addCSourceBytes(dso, |
| 264 | 276 | \\void *foo() { |
| 265 | 277 | \\ return foo; |
| ... | ... | @@ -269,17 +281,21 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { |
| 269 | 281 | \\} |
| 270 | 282 | , &.{}); |
| 271 | 283 | |
| 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 = | |
| 274 | 287 | \\void *bar(); |
| 275 | 288 | \\void *baz() { |
| 276 | 289 | \\ return bar; |
| 277 | 290 | \\} |
| 278 | , &.{}); | |
| 279 | b_o.force_pic = true; | |
| 291 | \\ | |
| 292 | , | |
| 293 | .pic = true, | |
| 294 | }); | |
| 280 | 295 | |
| 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 = | |
| 283 | 299 | \\#include <assert.h> |
| 284 | 300 | \\void *foo(); |
| 285 | 301 | \\void *bar(); |
| ... | ... | @@ -290,11 +306,15 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { |
| 290 | 306 | \\ assert(bar == baz()); |
| 291 | 307 | \\ return 0; |
| 292 | 308 | \\} |
| 293 | , &.{}); | |
| 309 | \\ | |
| 310 | , | |
| 311 | .pic = false, | |
| 312 | }); | |
| 294 | 313 | main_o.linkLibC(); |
| 295 | main_o.force_pic = false; | |
| 296 | 314 | |
| 297 | const exe = addExecutable(b, "main", opts); | |
| 315 | const exe = addExecutable(b, opts, .{ | |
| 316 | .name = "main", | |
| 317 | }); | |
| 298 | 318 | exe.addObject(main_o); |
| 299 | 319 | exe.addObject(b_o); |
| 300 | 320 | exe.linkLibrary(dso); |
| ... | ... | @@ -311,7 +331,9 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { |
| 311 | 331 | fn testCommonSymbols(b: *Build, opts: Options) *Step { |
| 312 | 332 | const test_step = addTestStep(b, "common-symbols", opts); |
| 313 | 333 | |
| 314 | const exe = addExecutable(b, "test", opts); | |
| 334 | const exe = addExecutable(b, opts, .{ | |
| 335 | .name = "test", | |
| 336 | }); | |
| 315 | 337 | addCSourceBytes(exe, |
| 316 | 338 | \\int foo; |
| 317 | 339 | \\int bar; |
| ... | ... | @@ -338,8 +360,9 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step { |
| 338 | 360 | fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 339 | 361 | const test_step = addTestStep(b, "common-symbols-in-archive", opts); |
| 340 | 362 | |
| 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 = | |
| 343 | 366 | \\#include <stdio.h> |
| 344 | 367 | \\int foo; |
| 345 | 368 | \\int bar; |
| ... | ... | @@ -348,28 +371,43 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 348 | 371 | \\int main() { |
| 349 | 372 | \\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1); |
| 350 | 373 | \\} |
| 351 | , &.{"-fcommon"}); | |
| 374 | \\ | |
| 375 | , | |
| 376 | .c_source_flags = &.{"-fcommon"}, | |
| 377 | }); | |
| 352 | 378 | a_o.linkLibC(); |
| 353 | 379 | |
| 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 | }); | |
| 356 | 385 | |
| 357 | 386 | { |
| 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 = | |
| 360 | 390 | \\int bar; |
| 361 | 391 | \\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" }); | |
| 368 | 404 | lib.addObject(b_o); |
| 369 | 405 | lib.addObject(c_o); |
| 370 | 406 | lib.addObject(d_o); |
| 371 | 407 | |
| 372 | const exe = addExecutable(b, "test", opts); | |
| 408 | const exe = addExecutable(b, opts, .{ | |
| 409 | .name = "test", | |
| 410 | }); | |
| 373 | 411 | exe.addObject(a_o); |
| 374 | 412 | exe.linkLibrary(lib); |
| 375 | 413 | exe.linkLibC(); |
| ... | ... | @@ -380,18 +418,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 380 | 418 | } |
| 381 | 419 | |
| 382 | 420 | { |
| 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 = | |
| 385 | 424 | \\int bar = 0; |
| 386 | 425 | \\int baz = 7; |
| 387 | 426 | \\int two() { return 2; } |
| 388 | , &.{"-fcommon"}); | |
| 427 | , | |
| 428 | .c_source_flags = &.{"-fcommon"}, | |
| 429 | }); | |
| 389 | 430 | |
| 390 | const lib = addStaticLibrary(b, "lib", opts); | |
| 431 | const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); | |
| 391 | 432 | lib.addObject(b_o); |
| 392 | 433 | lib.addObject(e_o); |
| 393 | 434 | |
| 394 | const exe = addExecutable(b, "test", opts); | |
| 435 | const exe = addExecutable(b, opts, .{ | |
| 436 | .name = "test", | |
| 437 | }); | |
| 395 | 438 | exe.addObject(a_o); |
| 396 | 439 | exe.linkLibrary(lib); |
| 397 | 440 | exe.linkLibC(); |
| ... | ... | @@ -407,21 +450,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { |
| 407 | 450 | fn testCopyrel(b: *Build, opts: Options) *Step { |
| 408 | 451 | const test_step = addTestStep(b, "copyrel", opts); |
| 409 | 452 | |
| 410 | const dso = addSharedLibrary(b, "a", opts); | |
| 453 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 411 | 454 | addCSourceBytes(dso, |
| 412 | 455 | \\int foo = 3; |
| 413 | 456 | \\int bar = 5; |
| 414 | 457 | , &.{}); |
| 415 | 458 | |
| 416 | const exe = addExecutable(b, "main", opts); | |
| 417 | addCSourceBytes(exe, | |
| 459 | const exe = addExecutable(b, opts, .{ | |
| 460 | .name = "main", | |
| 461 | .c_source_bytes = | |
| 418 | 462 | \\#include<stdio.h> |
| 419 | 463 | \\extern int foo, bar; |
| 420 | 464 | \\int main() { |
| 421 | 465 | \\ printf("%d %d\n", foo, bar); |
| 422 | 466 | \\ return 0; |
| 423 | 467 | \\} |
| 424 | , &.{}); | |
| 468 | , | |
| 469 | }); | |
| 425 | 470 | exe.linkLibrary(dso); |
| 426 | 471 | exe.linkLibC(); |
| 427 | 472 | // https://github.com/ziglang/zig/issues/17619 |
| ... | ... | @@ -437,7 +482,7 @@ fn testCopyrel(b: *Build, opts: Options) *Step { |
| 437 | 482 | fn testCopyrelAlias(b: *Build, opts: Options) *Step { |
| 438 | 483 | const test_step = addTestStep(b, "copyrel-alias", opts); |
| 439 | 484 | |
| 440 | const dso = addSharedLibrary(b, "a", opts); | |
| 485 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 441 | 486 | addCSourceBytes(dso, |
| 442 | 487 | \\int bruh = 31; |
| 443 | 488 | \\int foo = 42; |
| ... | ... | @@ -445,7 +490,10 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { |
| 445 | 490 | \\extern int baz __attribute__((alias("foo"))); |
| 446 | 491 | , &.{}); |
| 447 | 492 | |
| 448 | const exe = addExecutable(b, "main", opts); | |
| 493 | const exe = addExecutable(b, opts, .{ | |
| 494 | .name = "main", | |
| 495 | .pic = false, | |
| 496 | }); | |
| 449 | 497 | addCSourceBytes(exe, |
| 450 | 498 | \\#include<stdio.h> |
| 451 | 499 | \\extern int foo; |
| ... | ... | @@ -461,7 +509,6 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { |
| 461 | 509 | , &.{}); |
| 462 | 510 | exe.linkLibrary(dso); |
| 463 | 511 | exe.linkLibC(); |
| 464 | exe.force_pic = false; | |
| 465 | 512 | exe.pie = false; |
| 466 | 513 | |
| 467 | 514 | const run = addRunArtifact(exe); |
| ... | ... | @@ -474,28 +521,31 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { |
| 474 | 521 | fn testCopyrelAlignment(b: *Build, opts: Options) *Step { |
| 475 | 522 | const test_step = addTestStep(b, "copyrel-alignment", opts); |
| 476 | 523 | |
| 477 | const a_so = addSharedLibrary(b, "a", opts); | |
| 524 | const a_so = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 478 | 525 | addCSourceBytes(a_so, "__attribute__((aligned(32))) int foo = 5;", &.{}); |
| 479 | 526 | |
| 480 | const b_so = addSharedLibrary(b, "b", opts); | |
| 527 | const b_so = addSharedLibrary(b, opts, .{ .name = "b" }); | |
| 481 | 528 | addCSourceBytes(b_so, "__attribute__((aligned(8))) int foo = 5;", &.{}); |
| 482 | 529 | |
| 483 | const c_so = addSharedLibrary(b, "c", opts); | |
| 530 | const c_so = addSharedLibrary(b, opts, .{ .name = "c" }); | |
| 484 | 531 | addCSourceBytes(c_so, "__attribute__((aligned(256))) int foo = 5;", &.{}); |
| 485 | 532 | |
| 486 | const obj = addObject(b, "main", opts); | |
| 487 | addCSourceBytes(obj, | |
| 533 | const obj = addObject(b, opts, .{ | |
| 534 | .name = "main", | |
| 535 | .c_source_bytes = | |
| 488 | 536 | \\#include <stdio.h> |
| 489 | 537 | \\extern int foo; |
| 490 | 538 | \\int main() { printf("%d\n", foo); } |
| 491 | , &.{}); | |
| 539 | \\ | |
| 540 | , | |
| 541 | .pic = false, | |
| 542 | }); | |
| 492 | 543 | obj.linkLibC(); |
| 493 | obj.force_pic = false; | |
| 494 | 544 | |
| 495 | 545 | const exp_stdout = "5\n"; |
| 496 | 546 | |
| 497 | 547 | { |
| 498 | const exe = addExecutable(b, "main", opts); | |
| 548 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 499 | 549 | exe.addObject(obj); |
| 500 | 550 | exe.linkLibrary(a_so); |
| 501 | 551 | exe.linkLibC(); |
| ... | ... | @@ -514,7 +564,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { |
| 514 | 564 | } |
| 515 | 565 | |
| 516 | 566 | { |
| 517 | const exe = addExecutable(b, "main", opts); | |
| 567 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 518 | 568 | exe.addObject(obj); |
| 519 | 569 | exe.linkLibrary(b_so); |
| 520 | 570 | exe.linkLibC(); |
| ... | ... | @@ -533,7 +583,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { |
| 533 | 583 | } |
| 534 | 584 | |
| 535 | 585 | { |
| 536 | const exe = addExecutable(b, "main", opts); | |
| 586 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 537 | 587 | exe.addObject(obj); |
| 538 | 588 | exe.linkLibrary(c_so); |
| 539 | 589 | exe.linkLibC(); |
| ... | ... | @@ -557,7 +607,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { |
| 557 | 607 | fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 558 | 608 | const test_step = addTestStep(b, "dso-plt", opts); |
| 559 | 609 | |
| 560 | const dso = addSharedLibrary(b, "dso", opts); | |
| 610 | const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); | |
| 561 | 611 | addCSourceBytes(dso, |
| 562 | 612 | \\#include<stdio.h> |
| 563 | 613 | \\void world() { |
| ... | ... | @@ -573,7 +623,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 573 | 623 | , &.{}); |
| 574 | 624 | dso.linkLibC(); |
| 575 | 625 | |
| 576 | const exe = addExecutable(b, "test", opts); | |
| 626 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 577 | 627 | addCSourceBytes(exe, |
| 578 | 628 | \\#include<stdio.h> |
| 579 | 629 | \\void world() { |
| ... | ... | @@ -599,7 +649,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { |
| 599 | 649 | fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 600 | 650 | const test_step = addTestStep(b, "dso-undef", opts); |
| 601 | 651 | |
| 602 | const dso = addSharedLibrary(b, "dso", opts); | |
| 652 | const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); | |
| 603 | 653 | addCSourceBytes(dso, |
| 604 | 654 | \\extern int foo; |
| 605 | 655 | \\int bar = 5; |
| ... | ... | @@ -607,13 +657,15 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 607 | 657 | , &.{}); |
| 608 | 658 | dso.linkLibC(); |
| 609 | 659 | |
| 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 | }); | |
| 612 | 664 | |
| 613 | const lib = addStaticLibrary(b, "lib", opts); | |
| 665 | const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); | |
| 614 | 666 | lib.addObject(obj); |
| 615 | 667 | |
| 616 | const exe = addExecutable(b, "test", opts); | |
| 668 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 617 | 669 | exe.linkLibrary(dso); |
| 618 | 670 | exe.linkLibrary(lib); |
| 619 | 671 | addCSourceBytes(exe, |
| ... | ... | @@ -641,8 +693,9 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { |
| 641 | 693 | fn testEmitRelocatable(b: *Build, opts: Options) *Step { |
| 642 | 694 | const test_step = addTestStep(b, "emit-relocatable", opts); |
| 643 | 695 | |
| 644 | const obj1 = addObject(b, "obj1", opts); | |
| 645 | addZigSourceBytes(obj1, | |
| 696 | const obj1 = addObject(b, opts, .{ | |
| 697 | .name = "obj1", | |
| 698 | .zig_source_bytes = | |
| 646 | 699 | \\const std = @import("std"); |
| 647 | 700 | \\extern var bar: i32; |
| 648 | 701 | \\export fn foo() i32 { |
| ... | ... | @@ -651,18 +704,20 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { |
| 651 | 704 | \\export fn printFoo() void { |
| 652 | 705 | \\ std.debug.print("foo={d}\n", .{foo()}); |
| 653 | 706 | \\} |
| 654 | ); | |
| 655 | addCSourceBytes(obj1, | |
| 707 | , | |
| 708 | .c_source_bytes = | |
| 656 | 709 | \\#include <stdio.h> |
| 657 | 710 | \\int bar = 42; |
| 658 | 711 | \\void printBar() { |
| 659 | 712 | \\ fprintf(stderr, "bar=%d\n", bar); |
| 660 | 713 | \\} |
| 661 | , &.{}); | |
| 714 | , | |
| 715 | }); | |
| 662 | 716 | obj1.linkLibC(); |
| 663 | 717 | |
| 664 | const exe = addExecutable(b, "test", opts); | |
| 665 | addZigSourceBytes(exe, | |
| 718 | const exe = addExecutable(b, opts, .{ | |
| 719 | .name = "test", | |
| 720 | .zig_source_bytes = | |
| 666 | 721 | \\const std = @import("std"); |
| 667 | 722 | \\extern fn printFoo() void; |
| 668 | 723 | \\extern fn printBar() void; |
| ... | ... | @@ -670,7 +725,8 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { |
| 670 | 725 | \\ printFoo(); |
| 671 | 726 | \\ printBar(); |
| 672 | 727 | \\} |
| 673 | ); | |
| 728 | , | |
| 729 | }); | |
| 674 | 730 | exe.addObject(obj1); |
| 675 | 731 | exe.linkLibC(); |
| 676 | 732 | |
| ... | ... | @@ -688,20 +744,26 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { |
| 688 | 744 | fn testEmitStaticLib(b: *Build, opts: Options) *Step { |
| 689 | 745 | const test_step = addTestStep(b, "emit-static-lib", opts); |
| 690 | 746 | |
| 691 | const obj1 = addObject(b, "obj1", opts); | |
| 692 | addCSourceBytes(obj1, | |
| 747 | const obj1 = addObject(b, opts, .{ | |
| 748 | .name = "obj1", | |
| 749 | .c_source_bytes = | |
| 693 | 750 | \\int foo = 0; |
| 694 | 751 | \\int bar = 2; |
| 695 | 752 | \\int fooBar() { |
| 696 | 753 | \\ return foo + bar; |
| 697 | 754 | \\} |
| 698 | , &.{}); | |
| 755 | , | |
| 756 | }); | |
| 699 | 757 | |
| 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 | }); | |
| 702 | 763 | |
| 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 = | |
| 705 | 767 | \\fn weakFoo() callconv(.C) usize { |
| 706 | 768 | \\ return 42; |
| 707 | 769 | \\} |
| ... | ... | @@ -710,9 +772,10 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step { |
| 710 | 772 | \\ @export(weakFoo, .{ .name = "weakFoo", .linkage = .Weak }); |
| 711 | 773 | \\ @export(strongBar, .{ .name = "strongBarAlias", .linkage = .Strong }); |
| 712 | 774 | \\} |
| 713 | ); | |
| 775 | , | |
| 776 | }); | |
| 714 | 777 | |
| 715 | const lib = addStaticLibrary(b, "lib", opts); | |
| 778 | const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); | |
| 716 | 779 | lib.addObject(obj1); |
| 717 | 780 | lib.addObject(obj2); |
| 718 | 781 | lib.addObject(obj3); |
| ... | ... | @@ -747,30 +810,36 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step { |
| 747 | 810 | fn testEmitStaticLibZig(b: *Build, opts: Options) *Step { |
| 748 | 811 | const test_step = addTestStep(b, "emit-static-lib-zig", opts); |
| 749 | 812 | |
| 750 | const obj1 = addObject(b, "obj1", opts); | |
| 751 | addZigSourceBytes(obj1, | |
| 813 | const obj1 = addObject(b, opts, .{ | |
| 814 | .name = "obj1", | |
| 815 | .zig_source_bytes = | |
| 752 | 816 | \\export var foo: i32 = 42; |
| 753 | 817 | \\export var bar: i32 = 2; |
| 754 | ); | |
| 818 | , | |
| 819 | }); | |
| 755 | 820 | |
| 756 | const lib = addStaticLibrary(b, "lib", opts); | |
| 757 | addZigSourceBytes(lib, | |
| 821 | const lib = addStaticLibrary(b, opts, .{ | |
| 822 | .name = "lib", | |
| 823 | .zig_source_bytes = | |
| 758 | 824 | \\extern var foo: i32; |
| 759 | 825 | \\extern var bar: i32; |
| 760 | 826 | \\export fn fooBar() i32 { |
| 761 | 827 | \\ return foo + bar; |
| 762 | 828 | \\} |
| 763 | ); | |
| 829 | , | |
| 830 | }); | |
| 764 | 831 | lib.addObject(obj1); |
| 765 | 832 | |
| 766 | const exe = addExecutable(b, "test", opts); | |
| 767 | addZigSourceBytes(exe, | |
| 833 | const exe = addExecutable(b, opts, .{ | |
| 834 | .name = "test", | |
| 835 | .zig_source_bytes = | |
| 768 | 836 | \\const std = @import("std"); |
| 769 | 837 | \\extern fn fooBar() i32; |
| 770 | 838 | \\pub fn main() void { |
| 771 | 839 | \\ std.debug.print("{d}", .{fooBar()}); |
| 772 | 840 | \\} |
| 773 | ); | |
| 841 | , | |
| 842 | }); | |
| 774 | 843 | exe.linkLibrary(lib); |
| 775 | 844 | |
| 776 | 845 | const run = addRunArtifact(exe); |
| ... | ... | @@ -783,7 +852,7 @@ fn testEmitStaticLibZig(b: *Build, opts: Options) *Step { |
| 783 | 852 | fn testEmptyObject(b: *Build, opts: Options) *Step { |
| 784 | 853 | const test_step = addTestStep(b, "empty-object", opts); |
| 785 | 854 | |
| 786 | const exe = addExecutable(b, "test", opts); | |
| 855 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 787 | 856 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 788 | 857 | addCSourceBytes(exe, "", &.{}); |
| 789 | 858 | exe.linkLibC(); |
| ... | ... | @@ -798,18 +867,23 @@ fn testEmptyObject(b: *Build, opts: Options) *Step { |
| 798 | 867 | fn testEntryPoint(b: *Build, opts: Options) *Step { |
| 799 | 868 | const test_step = addTestStep(b, "entry-point", opts); |
| 800 | 869 | |
| 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 = | |
| 803 | 873 | \\.globl foo, bar |
| 804 | 874 | \\foo = 0x1000 |
| 805 | 875 | \\bar = 0x2000 |
| 806 | ); | |
| 876 | \\ | |
| 877 | , | |
| 878 | }); | |
| 807 | 879 | |
| 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 | }); | |
| 810 | 884 | |
| 811 | 885 | { |
| 812 | const exe = addExecutable(b, "main", opts); | |
| 886 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 813 | 887 | exe.addObject(a_o); |
| 814 | 888 | exe.addObject(b_o); |
| 815 | 889 | exe.entry = .{ .symbol_name = "foo" }; |
| ... | ... | @@ -825,7 +899,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step { |
| 825 | 899 | // TODO looks like not assigning a unique name to this executable will |
| 826 | 900 | // cause an artifact collision taking the cached executable from the above |
| 827 | 901 | // step instead of generating a new one. |
| 828 | const exe = addExecutable(b, "other", opts); | |
| 902 | const exe = addExecutable(b, opts, .{ .name = "other" }); | |
| 829 | 903 | exe.addObject(a_o); |
| 830 | 904 | exe.addObject(b_o); |
| 831 | 905 | exe.entry = .{ .symbol_name = "bar" }; |
| ... | ... | @@ -843,8 +917,9 @@ fn testEntryPoint(b: *Build, opts: Options) *Step { |
| 843 | 917 | fn testExportDynamic(b: *Build, opts: Options) *Step { |
| 844 | 918 | const test_step = addTestStep(b, "export-dynamic", opts); |
| 845 | 919 | |
| 846 | const obj = addObject(b, "obj", opts); | |
| 847 | addAsmSourceBytes(obj, | |
| 920 | const obj = addObject(b, opts, .{ | |
| 921 | .name = "obj", | |
| 922 | .asm_source_bytes = | |
| 848 | 923 | \\.text |
| 849 | 924 | \\ .globl foo |
| 850 | 925 | \\ .hidden foo |
| ... | ... | @@ -856,12 +931,14 @@ fn testExportDynamic(b: *Build, opts: Options) *Step { |
| 856 | 931 | \\ .globl _start |
| 857 | 932 | \\_start: |
| 858 | 933 | \\ nop |
| 859 | ); | |
| 934 | \\ | |
| 935 | , | |
| 936 | }); | |
| 860 | 937 | |
| 861 | const dso = addSharedLibrary(b, "a", opts); | |
| 938 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 862 | 939 | addCSourceBytes(dso, "int baz = 10;", &.{}); |
| 863 | 940 | |
| 864 | const exe = addExecutable(b, "main", opts); | |
| 941 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 865 | 942 | addCSourceBytes(exe, |
| 866 | 943 | \\extern int baz; |
| 867 | 944 | \\int callBaz() { |
| ... | ... | @@ -885,7 +962,7 @@ fn testExportDynamic(b: *Build, opts: Options) *Step { |
| 885 | 962 | fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { |
| 886 | 963 | const test_step = addTestStep(b, "export-symbols-from-exe", opts); |
| 887 | 964 | |
| 888 | const dso = addSharedLibrary(b, "a", opts); | |
| 965 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 889 | 966 | addCSourceBytes(dso, |
| 890 | 967 | \\void expfn1(); |
| 891 | 968 | \\void expfn2() {} |
| ... | ... | @@ -895,7 +972,7 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { |
| 895 | 972 | \\} |
| 896 | 973 | , &.{}); |
| 897 | 974 | |
| 898 | const exe = addExecutable(b, "main", opts); | |
| 975 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 899 | 976 | addCSourceBytes(exe, |
| 900 | 977 | \\void expfn1() {} |
| 901 | 978 | \\void expfn2() {} |
| ... | ... | @@ -923,10 +1000,10 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { |
| 923 | 1000 | fn testFuncAddress(b: *Build, opts: Options) *Step { |
| 924 | 1001 | const test_step = addTestStep(b, "func-address", opts); |
| 925 | 1002 | |
| 926 | const dso = addSharedLibrary(b, "a", opts); | |
| 1003 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 927 | 1004 | addCSourceBytes(dso, "void fn() {}", &.{}); |
| 928 | 1005 | |
| 929 | const exe = addExecutable(b, "main", opts); | |
| 1006 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 930 | 1007 | addCSourceBytes(exe, |
| 931 | 1008 | \\#include <assert.h> |
| 932 | 1009 | \\typedef void Func(); |
| ... | ... | @@ -937,7 +1014,7 @@ fn testFuncAddress(b: *Build, opts: Options) *Step { |
| 937 | 1014 | \\} |
| 938 | 1015 | , &.{}); |
| 939 | 1016 | exe.linkLibrary(dso); |
| 940 | exe.force_pic = false; | |
| 1017 | exe.root_module.pic = false; | |
| 941 | 1018 | exe.pie = false; |
| 942 | 1019 | |
| 943 | 1020 | const run = addRunArtifact(exe); |
| ... | ... | @@ -950,8 +1027,9 @@ fn testFuncAddress(b: *Build, opts: Options) *Step { |
| 950 | 1027 | fn testGcSections(b: *Build, opts: Options) *Step { |
| 951 | 1028 | const test_step = addTestStep(b, "gc-sections", opts); |
| 952 | 1029 | |
| 953 | const obj = addObject(b, "obj", opts); | |
| 954 | addCppSourceBytes(obj, | |
| 1030 | const obj = addObject(b, opts, .{ | |
| 1031 | .name = "obj", | |
| 1032 | .cpp_source_bytes = | |
| 955 | 1033 | \\#include <stdio.h> |
| 956 | 1034 | \\int two() { return 2; } |
| 957 | 1035 | \\int live_var1 = 1; |
| ... | ... | @@ -966,14 +1044,15 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 966 | 1044 | \\ printf("%d %d\n", live_var1, live_var2); |
| 967 | 1045 | \\ live_fn2(); |
| 968 | 1046 | \\} |
| 969 | , &.{}); | |
| 1047 | , | |
| 1048 | }); | |
| 970 | 1049 | obj.link_function_sections = true; |
| 971 | 1050 | obj.link_data_sections = true; |
| 972 | 1051 | obj.linkLibC(); |
| 973 | 1052 | obj.linkLibCpp(); |
| 974 | 1053 | |
| 975 | 1054 | { |
| 976 | const exe = addExecutable(b, "test", opts); | |
| 1055 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 977 | 1056 | exe.addObject(obj); |
| 978 | 1057 | exe.link_gc_sections = false; |
| 979 | 1058 | exe.linkLibC(); |
| ... | ... | @@ -1004,7 +1083,7 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 1004 | 1083 | } |
| 1005 | 1084 | |
| 1006 | 1085 | { |
| 1007 | const exe = addExecutable(b, "test", opts); | |
| 1086 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 1008 | 1087 | exe.addObject(obj); |
| 1009 | 1088 | exe.link_gc_sections = true; |
| 1010 | 1089 | exe.linkLibC(); |
| ... | ... | @@ -1040,11 +1119,12 @@ fn testGcSections(b: *Build, opts: Options) *Step { |
| 1040 | 1119 | fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1041 | 1120 | const test_step = addTestStep(b, "gc-sections-zig", opts); |
| 1042 | 1121 | |
| 1043 | const obj = addObject(b, "obj", .{ | |
| 1122 | const obj = addObject(b, .{ | |
| 1044 | 1123 | .target = opts.target, |
| 1045 | 1124 | .use_llvm = true, |
| 1046 | }); | |
| 1047 | addCSourceBytes(obj, | |
| 1125 | }, .{ | |
| 1126 | .name = "obj", | |
| 1127 | .c_source_bytes = | |
| 1048 | 1128 | \\int live_var1 = 1; |
| 1049 | 1129 | \\int live_var2 = 2; |
| 1050 | 1130 | \\int dead_var1 = 3; |
| ... | ... | @@ -1053,13 +1133,15 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1053 | 1133 | \\void live_fn2() { live_fn1(); } |
| 1054 | 1134 | \\void dead_fn1() {} |
| 1055 | 1135 | \\void dead_fn2() { dead_fn1(); } |
| 1056 | , &.{}); | |
| 1136 | , | |
| 1137 | }); | |
| 1057 | 1138 | obj.link_function_sections = true; |
| 1058 | 1139 | obj.link_data_sections = true; |
| 1059 | 1140 | |
| 1060 | 1141 | { |
| 1061 | const exe = addExecutable(b, "test1", opts); | |
| 1062 | addZigSourceBytes(exe, | |
| 1142 | const exe = addExecutable(b, opts, .{ | |
| 1143 | .name = "test1", | |
| 1144 | .zig_source_bytes = | |
| 1063 | 1145 | \\const std = @import("std"); |
| 1064 | 1146 | \\extern var live_var1: i32; |
| 1065 | 1147 | \\extern var live_var2: i32; |
| ... | ... | @@ -1069,7 +1151,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1069 | 1151 | \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; |
| 1070 | 1152 | \\ live_fn2(); |
| 1071 | 1153 | \\} |
| 1072 | ); | |
| 1154 | , | |
| 1155 | }); | |
| 1073 | 1156 | exe.addObject(obj); |
| 1074 | 1157 | exe.link_gc_sections = false; |
| 1075 | 1158 | |
| ... | ... | @@ -1098,8 +1181,9 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1098 | 1181 | } |
| 1099 | 1182 | |
| 1100 | 1183 | { |
| 1101 | const exe = addExecutable(b, "test2", opts); | |
| 1102 | addZigSourceBytes(exe, | |
| 1184 | const exe = addExecutable(b, opts, .{ | |
| 1185 | .name = "test2", | |
| 1186 | .zig_source_bytes = | |
| 1103 | 1187 | \\const std = @import("std"); |
| 1104 | 1188 | \\extern var live_var1: i32; |
| 1105 | 1189 | \\extern var live_var2: i32; |
| ... | ... | @@ -1109,7 +1193,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1109 | 1193 | \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; |
| 1110 | 1194 | \\ live_fn2(); |
| 1111 | 1195 | \\} |
| 1112 | ); | |
| 1196 | , | |
| 1197 | }); | |
| 1113 | 1198 | exe.addObject(obj); |
| 1114 | 1199 | exe.link_gc_sections = true; |
| 1115 | 1200 | |
| ... | ... | @@ -1143,7 +1228,7 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { |
| 1143 | 1228 | fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { |
| 1144 | 1229 | const test_step = addTestStep(b, "hidden-weak-undef", opts); |
| 1145 | 1230 | |
| 1146 | const dso = addSharedLibrary(b, "a", opts); | |
| 1231 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 1147 | 1232 | addCSourceBytes(dso, |
| 1148 | 1233 | \\__attribute__((weak, visibility("hidden"))) void foo(); |
| 1149 | 1234 | \\void bar() { foo(); } |
| ... | ... | @@ -1162,7 +1247,7 @@ fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { |
| 1162 | 1247 | fn testIFuncAlias(b: *Build, opts: Options) *Step { |
| 1163 | 1248 | const test_step = addTestStep(b, "ifunc-alias", opts); |
| 1164 | 1249 | |
| 1165 | const exe = addExecutable(b, "main", opts); | |
| 1250 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1166 | 1251 | addCSourceBytes(exe, |
| 1167 | 1252 | \\#include <assert.h> |
| 1168 | 1253 | \\void foo() {} |
| ... | ... | @@ -1173,7 +1258,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step { |
| 1173 | 1258 | \\ assert(bar == bar2); |
| 1174 | 1259 | \\} |
| 1175 | 1260 | , &.{}); |
| 1176 | exe.force_pic = true; | |
| 1261 | exe.root_module.pic = true; | |
| 1177 | 1262 | exe.linkLibC(); |
| 1178 | 1263 | // https://github.com/ziglang/zig/issues/17619 |
| 1179 | 1264 | exe.pie = true; |
| ... | ... | @@ -1188,7 +1273,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step { |
| 1188 | 1273 | fn testIFuncDlopen(b: *Build, opts: Options) *Step { |
| 1189 | 1274 | const test_step = addTestStep(b, "ifunc-dlopen", opts); |
| 1190 | 1275 | |
| 1191 | const dso = addSharedLibrary(b, "a", opts); | |
| 1276 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 1192 | 1277 | addCSourceBytes(dso, |
| 1193 | 1278 | \\__attribute__((ifunc("resolve_foo"))) |
| 1194 | 1279 | \\void foo(void); |
| ... | ... | @@ -1200,7 +1285,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { |
| 1200 | 1285 | \\} |
| 1201 | 1286 | , &.{}); |
| 1202 | 1287 | |
| 1203 | const exe = addExecutable(b, "main", opts); | |
| 1288 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1204 | 1289 | addCSourceBytes(exe, |
| 1205 | 1290 | \\#include <dlfcn.h> |
| 1206 | 1291 | \\#include <assert.h> |
| ... | ... | @@ -1219,7 +1304,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { |
| 1219 | 1304 | exe.linkLibrary(dso); |
| 1220 | 1305 | exe.linkLibC(); |
| 1221 | 1306 | exe.linkSystemLibrary2("dl", .{}); |
| 1222 | exe.force_pic = false; | |
| 1307 | exe.root_module.pic = false; | |
| 1223 | 1308 | exe.pie = false; |
| 1224 | 1309 | |
| 1225 | 1310 | const run = addRunArtifact(exe); |
| ... | ... | @@ -1232,8 +1317,9 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { |
| 1232 | 1317 | fn testIFuncDso(b: *Build, opts: Options) *Step { |
| 1233 | 1318 | const test_step = addTestStep(b, "ifunc-dso", opts); |
| 1234 | 1319 | |
| 1235 | const dso = addSharedLibrary(b, "a", opts); | |
| 1236 | addCSourceBytes(dso, | |
| 1320 | const dso = addSharedLibrary(b, opts, .{ | |
| 1321 | .name = "a", | |
| 1322 | .c_source_bytes = | |
| 1237 | 1323 | \\#include<stdio.h> |
| 1238 | 1324 | \\__attribute__((ifunc("resolve_foobar"))) |
| 1239 | 1325 | \\void foobar(void); |
| ... | ... | @@ -1244,16 +1330,19 @@ fn testIFuncDso(b: *Build, opts: Options) *Step { |
| 1244 | 1330 | \\static Func *resolve_foobar(void) { |
| 1245 | 1331 | \\ return real_foobar; |
| 1246 | 1332 | \\} |
| 1247 | , &.{}); | |
| 1333 | , | |
| 1334 | }); | |
| 1248 | 1335 | dso.linkLibC(); |
| 1249 | 1336 | |
| 1250 | const exe = addExecutable(b, "main", opts); | |
| 1251 | addCSourceBytes(exe, | |
| 1337 | const exe = addExecutable(b, opts, .{ | |
| 1338 | .name = "main", | |
| 1339 | .c_source_bytes = | |
| 1252 | 1340 | \\void foobar(void); |
| 1253 | 1341 | \\int main() { |
| 1254 | 1342 | \\ foobar(); |
| 1255 | 1343 | \\} |
| 1256 | , &.{}); | |
| 1344 | , | |
| 1345 | }); | |
| 1257 | 1346 | exe.linkLibrary(dso); |
| 1258 | 1347 | |
| 1259 | 1348 | const run = addRunArtifact(exe); |
| ... | ... | @@ -1283,7 +1372,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { |
| 1283 | 1372 | ; |
| 1284 | 1373 | |
| 1285 | 1374 | { |
| 1286 | const exe = addExecutable(b, "main", opts); | |
| 1375 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1287 | 1376 | addCSourceBytes(exe, main_c, &.{}); |
| 1288 | 1377 | exe.linkLibC(); |
| 1289 | 1378 | exe.link_z_lazy = true; |
| ... | ... | @@ -1295,7 +1384,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { |
| 1295 | 1384 | test_step.dependOn(&run.step); |
| 1296 | 1385 | } |
| 1297 | 1386 | { |
| 1298 | const exe = addExecutable(b, "other", opts); | |
| 1387 | const exe = addExecutable(b, opts, .{ .name = "other" }); | |
| 1299 | 1388 | addCSourceBytes(exe, main_c, &.{}); |
| 1300 | 1389 | exe.linkLibC(); |
| 1301 | 1390 | // https://github.com/ziglang/zig/issues/17619 |
| ... | ... | @@ -1312,7 +1401,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { |
| 1312 | 1401 | fn testIFuncExport(b: *Build, opts: Options) *Step { |
| 1313 | 1402 | const test_step = addTestStep(b, "ifunc-export", opts); |
| 1314 | 1403 | |
| 1315 | const dso = addSharedLibrary(b, "a", opts); | |
| 1404 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 1316 | 1405 | addCSourceBytes(dso, |
| 1317 | 1406 | \\#include <stdio.h> |
| 1318 | 1407 | \\__attribute__((ifunc("resolve_foobar"))) |
| ... | ... | @@ -1338,7 +1427,7 @@ fn testIFuncExport(b: *Build, opts: Options) *Step { |
| 1338 | 1427 | fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { |
| 1339 | 1428 | const test_step = addTestStep(b, "ifunc-func-ptr", opts); |
| 1340 | 1429 | |
| 1341 | const exe = addExecutable(b, "main", opts); | |
| 1430 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1342 | 1431 | addCSourceBytes(exe, |
| 1343 | 1432 | \\typedef int Fn(); |
| 1344 | 1433 | \\int foo() __attribute__((ifunc("resolve_foo"))); |
| ... | ... | @@ -1361,7 +1450,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { |
| 1361 | 1450 | \\ printf("%d\n", f()); |
| 1362 | 1451 | \\} |
| 1363 | 1452 | , &.{}); |
| 1364 | exe.force_pic = true; | |
| 1453 | exe.root_module.pic = true; | |
| 1365 | 1454 | exe.linkLibC(); |
| 1366 | 1455 | // https://github.com/ziglang/zig/issues/17619 |
| 1367 | 1456 | exe.pie = true; |
| ... | ... | @@ -1376,7 +1465,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { |
| 1376 | 1465 | fn testIFuncNoPlt(b: *Build, opts: Options) *Step { |
| 1377 | 1466 | const test_step = addTestStep(b, "ifunc-noplt", opts); |
| 1378 | 1467 | |
| 1379 | const exe = addExecutable(b, "main", opts); | |
| 1468 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1380 | 1469 | addCSourceBytes(exe, |
| 1381 | 1470 | \\#include <stdio.h> |
| 1382 | 1471 | \\__attribute__((ifunc("resolve_foo"))) |
| ... | ... | @@ -1392,7 +1481,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step { |
| 1392 | 1481 | \\ foo(); |
| 1393 | 1482 | \\} |
| 1394 | 1483 | , &.{"-fno-plt"}); |
| 1395 | exe.force_pic = true; | |
| 1484 | exe.root_module.pic = true; | |
| 1396 | 1485 | exe.linkLibC(); |
| 1397 | 1486 | // https://github.com/ziglang/zig/issues/17619 |
| 1398 | 1487 | exe.pie = true; |
| ... | ... | @@ -1407,7 +1496,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step { |
| 1407 | 1496 | fn testIFuncStatic(b: *Build, opts: Options) *Step { |
| 1408 | 1497 | const test_step = addTestStep(b, "ifunc-static", opts); |
| 1409 | 1498 | |
| 1410 | const exe = addExecutable(b, "main", opts); | |
| 1499 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1411 | 1500 | addCSourceBytes(exe, |
| 1412 | 1501 | \\#include <stdio.h> |
| 1413 | 1502 | \\void foo() __attribute__((ifunc("resolve_foo"))); |
| ... | ... | @@ -1435,7 +1524,7 @@ fn testIFuncStatic(b: *Build, opts: Options) *Step { |
| 1435 | 1524 | fn testIFuncStaticPie(b: *Build, opts: Options) *Step { |
| 1436 | 1525 | const test_step = addTestStep(b, "ifunc-static-pie", opts); |
| 1437 | 1526 | |
| 1438 | const exe = addExecutable(b, "main", opts); | |
| 1527 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1439 | 1528 | addCSourceBytes(exe, |
| 1440 | 1529 | \\#include <stdio.h> |
| 1441 | 1530 | \\void foo() __attribute__((ifunc("resolve_foo"))); |
| ... | ... | @@ -1451,7 +1540,7 @@ fn testIFuncStaticPie(b: *Build, opts: Options) *Step { |
| 1451 | 1540 | \\} |
| 1452 | 1541 | , &.{}); |
| 1453 | 1542 | exe.linkage = .static; |
| 1454 | exe.force_pic = true; | |
| 1543 | exe.root_module.pic = true; | |
| 1455 | 1544 | exe.pie = true; |
| 1456 | 1545 | exe.linkLibC(); |
| 1457 | 1546 | |
| ... | ... | @@ -1478,7 +1567,7 @@ fn testImageBase(b: *Build, opts: Options) *Step { |
| 1478 | 1567 | const test_step = addTestStep(b, "image-base", opts); |
| 1479 | 1568 | |
| 1480 | 1569 | { |
| 1481 | const exe = addExecutable(b, "main1", opts); | |
| 1570 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 1482 | 1571 | addCSourceBytes(exe, |
| 1483 | 1572 | \\#include <stdio.h> |
| 1484 | 1573 | \\int main() { |
| ... | ... | @@ -1502,7 +1591,7 @@ fn testImageBase(b: *Build, opts: Options) *Step { |
| 1502 | 1591 | } |
| 1503 | 1592 | |
| 1504 | 1593 | { |
| 1505 | const exe = addExecutable(b, "main2", opts); | |
| 1594 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 1506 | 1595 | addCSourceBytes(exe, "void _start() {}", &.{}); |
| 1507 | 1596 | exe.image_base = 0xffffffff8000000; |
| 1508 | 1597 | |
| ... | ... | @@ -1520,22 +1609,26 @@ fn testImageBase(b: *Build, opts: Options) *Step { |
| 1520 | 1609 | fn testImportingDataDynamic(b: *Build, opts: Options) *Step { |
| 1521 | 1610 | const test_step = addTestStep(b, "importing-data-dynamic", opts); |
| 1522 | 1611 | |
| 1523 | const dso = addSharedLibrary(b, "a", .{ | |
| 1612 | const dso = addSharedLibrary(b, .{ | |
| 1524 | 1613 | .target = opts.target, |
| 1525 | 1614 | .optimize = opts.optimize, |
| 1526 | 1615 | .use_llvm = true, |
| 1616 | }, .{ | |
| 1617 | .name = "a", | |
| 1618 | .c_source_bytes = "int foo = 42;", | |
| 1527 | 1619 | }); |
| 1528 | addCSourceBytes(dso, "int foo = 42;", &.{}); | |
| 1529 | 1620 | |
| 1530 | const main = addExecutable(b, "main", opts); | |
| 1531 | addZigSourceBytes(main, | |
| 1621 | const main = addExecutable(b, opts, .{ | |
| 1622 | .name = "main", | |
| 1623 | .zig_source_bytes = | |
| 1532 | 1624 | \\extern var foo: i32; |
| 1533 | 1625 | \\pub fn main() void { |
| 1534 | 1626 | \\ @import("std").debug.print("{d}\n", .{foo}); |
| 1535 | 1627 | \\} |
| 1536 | ); | |
| 1628 | , | |
| 1629 | .strip = true, // TODO temp hack | |
| 1630 | }); | |
| 1537 | 1631 | main.pie = true; |
| 1538 | main.strip = true; // TODO temp hack | |
| 1539 | 1632 | main.linkLibrary(dso); |
| 1540 | 1633 | main.linkLibC(); |
| 1541 | 1634 | |
| ... | ... | @@ -1549,28 +1642,34 @@ fn testImportingDataDynamic(b: *Build, opts: Options) *Step { |
| 1549 | 1642 | fn testImportingDataStatic(b: *Build, opts: Options) *Step { |
| 1550 | 1643 | const test_step = addTestStep(b, "importing-data-static", opts); |
| 1551 | 1644 | |
| 1552 | const obj = addObject(b, "a", .{ | |
| 1645 | const obj = addObject(b, .{ | |
| 1553 | 1646 | .target = opts.target, |
| 1554 | 1647 | .optimize = opts.optimize, |
| 1555 | 1648 | .use_llvm = true, |
| 1649 | }, .{ | |
| 1650 | .name = "a", | |
| 1651 | .c_source_bytes = "int foo = 42;", | |
| 1556 | 1652 | }); |
| 1557 | addCSourceBytes(obj, "int foo = 42;", &.{}); | |
| 1558 | 1653 | |
| 1559 | const lib = addStaticLibrary(b, "a", .{ | |
| 1654 | const lib = addStaticLibrary(b, .{ | |
| 1560 | 1655 | .target = opts.target, |
| 1561 | 1656 | .optimize = opts.optimize, |
| 1562 | 1657 | .use_llvm = true, |
| 1658 | }, .{ | |
| 1659 | .name = "a", | |
| 1563 | 1660 | }); |
| 1564 | 1661 | lib.addObject(obj); |
| 1565 | 1662 | |
| 1566 | const main = addExecutable(b, "main", opts); | |
| 1567 | addZigSourceBytes(main, | |
| 1663 | const main = addExecutable(b, opts, .{ | |
| 1664 | .name = "main", | |
| 1665 | .zig_source_bytes = | |
| 1568 | 1666 | \\extern var foo: i32; |
| 1569 | 1667 | \\pub fn main() void { |
| 1570 | 1668 | \\ @import("std").debug.print("{d}\n", .{foo}); |
| 1571 | 1669 | \\} |
| 1572 | ); | |
| 1573 | main.strip = true; // TODO temp hack | |
| 1670 | , | |
| 1671 | .strip = true, // TODO temp hack | |
| 1672 | }); | |
| 1574 | 1673 | main.linkLibrary(lib); |
| 1575 | 1674 | main.linkLibC(); |
| 1576 | 1675 | |
| ... | ... | @@ -1584,63 +1683,76 @@ fn testImportingDataStatic(b: *Build, opts: Options) *Step { |
| 1584 | 1683 | fn testInitArrayOrder(b: *Build, opts: Options) *Step { |
| 1585 | 1684 | const test_step = addTestStep(b, "init-array-order", opts); |
| 1586 | 1685 | |
| 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 = | |
| 1589 | 1689 | \\#include <stdio.h> |
| 1590 | 1690 | \\__attribute__((constructor(10000))) void init4() { printf("1"); } |
| 1591 | , &.{}); | |
| 1691 | , | |
| 1692 | }); | |
| 1592 | 1693 | a_o.linkLibC(); |
| 1593 | 1694 | |
| 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 = | |
| 1596 | 1698 | \\#include <stdio.h> |
| 1597 | 1699 | \\__attribute__((constructor(1000))) void init3() { printf("2"); } |
| 1598 | , &.{}); | |
| 1700 | , | |
| 1701 | }); | |
| 1599 | 1702 | b_o.linkLibC(); |
| 1600 | 1703 | |
| 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 = | |
| 1603 | 1707 | \\#include <stdio.h> |
| 1604 | 1708 | \\__attribute__((constructor)) void init1() { printf("3"); } |
| 1605 | , &.{}); | |
| 1709 | , | |
| 1710 | }); | |
| 1606 | 1711 | c_o.linkLibC(); |
| 1607 | 1712 | |
| 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 = | |
| 1610 | 1716 | \\#include <stdio.h> |
| 1611 | 1717 | \\__attribute__((constructor)) void init2() { printf("4"); } |
| 1612 | , &.{}); | |
| 1718 | , | |
| 1719 | }); | |
| 1613 | 1720 | d_o.linkLibC(); |
| 1614 | 1721 | |
| 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 = | |
| 1617 | 1725 | \\#include <stdio.h> |
| 1618 | 1726 | \\__attribute__((destructor(10000))) void fini4() { printf("5"); } |
| 1619 | , &.{}); | |
| 1727 | , | |
| 1728 | }); | |
| 1620 | 1729 | e_o.linkLibC(); |
| 1621 | 1730 | |
| 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 = | |
| 1624 | 1734 | \\#include <stdio.h> |
| 1625 | 1735 | \\__attribute__((destructor(1000))) void fini3() { printf("6"); } |
| 1626 | , &.{}); | |
| 1736 | , | |
| 1737 | }); | |
| 1627 | 1738 | f_o.linkLibC(); |
| 1628 | 1739 | |
| 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 = | |
| 1631 | 1743 | \\#include <stdio.h> |
| 1632 | 1744 | \\__attribute__((destructor)) void fini1() { printf("7"); } |
| 1633 | , &.{}); | |
| 1745 | , | |
| 1746 | }); | |
| 1634 | 1747 | g_o.linkLibC(); |
| 1635 | 1748 | |
| 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 | }); | |
| 1641 | 1753 | h_o.linkLibC(); |
| 1642 | 1754 | |
| 1643 | const exe = addExecutable(b, "main", opts); | |
| 1755 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1644 | 1756 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 1645 | 1757 | exe.addObject(a_o); |
| 1646 | 1758 | exe.addObject(b_o); |
| ... | ... | @@ -1651,7 +1763,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step { |
| 1651 | 1763 | exe.addObject(g_o); |
| 1652 | 1764 | exe.addObject(h_o); |
| 1653 | 1765 | |
| 1654 | if (opts.target.isGnuLibC()) { | |
| 1766 | if (opts.target.result.isGnuLibC()) { | |
| 1655 | 1767 | // TODO I think we need to clarify our use of `-fPIC -fPIE` flags for different targets |
| 1656 | 1768 | exe.pie = true; |
| 1657 | 1769 | } |
| ... | ... | @@ -1666,7 +1778,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step { |
| 1666 | 1778 | fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 1667 | 1779 | const test_step = addTestStep(b, "large-alignment-dso", opts); |
| 1668 | 1780 | |
| 1669 | const dso = addSharedLibrary(b, "dso", opts); | |
| 1781 | const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); | |
| 1670 | 1782 | addCSourceBytes(dso, |
| 1671 | 1783 | \\#include <stdio.h> |
| 1672 | 1784 | \\#include <stdint.h> |
| ... | ... | @@ -1695,7 +1807,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 1695 | 1807 | check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } }); |
| 1696 | 1808 | test_step.dependOn(&check.step); |
| 1697 | 1809 | |
| 1698 | const exe = addExecutable(b, "test", opts); | |
| 1810 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 1699 | 1811 | addCSourceBytes(exe, |
| 1700 | 1812 | \\void greet(); |
| 1701 | 1813 | \\int main() { greet(); } |
| ... | ... | @@ -1715,7 +1827,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { |
| 1715 | 1827 | fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { |
| 1716 | 1828 | const test_step = addTestStep(b, "large-alignment-exe", opts); |
| 1717 | 1829 | |
| 1718 | const exe = addExecutable(b, "test", opts); | |
| 1830 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 1719 | 1831 | addCSourceBytes(exe, |
| 1720 | 1832 | \\#include <stdio.h> |
| 1721 | 1833 | \\#include <stdint.h> |
| ... | ... | @@ -1760,7 +1872,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { |
| 1760 | 1872 | fn testLargeBss(b: *Build, opts: Options) *Step { |
| 1761 | 1873 | const test_step = addTestStep(b, "large-bss", opts); |
| 1762 | 1874 | |
| 1763 | const exe = addExecutable(b, "main", opts); | |
| 1875 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1764 | 1876 | addCSourceBytes(exe, |
| 1765 | 1877 | \\char arr[0x100000000]; |
| 1766 | 1878 | \\int main() { |
| ... | ... | @@ -1781,27 +1893,31 @@ fn testLargeBss(b: *Build, opts: Options) *Step { |
| 1781 | 1893 | fn testLinkOrder(b: *Build, opts: Options) *Step { |
| 1782 | 1894 | const test_step = addTestStep(b, "link-order", opts); |
| 1783 | 1895 | |
| 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 | }); | |
| 1787 | 1901 | |
| 1788 | const dso = addSharedLibrary(b, "a", opts); | |
| 1902 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 1789 | 1903 | dso.addObject(obj); |
| 1790 | 1904 | |
| 1791 | const lib = addStaticLibrary(b, "b", opts); | |
| 1905 | const lib = addStaticLibrary(b, opts, .{ .name = "b" }); | |
| 1792 | 1906 | lib.addObject(obj); |
| 1793 | 1907 | |
| 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 = | |
| 1796 | 1911 | \\void foo(); |
| 1797 | 1912 | \\int main() { |
| 1798 | 1913 | \\ foo(); |
| 1799 | 1914 | \\} |
| 1800 | , &.{}); | |
| 1915 | , | |
| 1916 | }); | |
| 1801 | 1917 | |
| 1802 | 1918 | // https://github.com/ziglang/zig/issues/17450 |
| 1803 | 1919 | // { |
| 1804 | // const exe = addExecutable(b, "main1", opts); | |
| 1920 | // const exe = addExecutable(b, opts, .{ .name = "main1"}); | |
| 1805 | 1921 | // exe.addObject(main_o); |
| 1806 | 1922 | // exe.linkSystemLibrary2("a", .{}); |
| 1807 | 1923 | // exe.addLibraryPath(dso.getEmittedBinDirectory()); |
| ... | ... | @@ -1818,7 +1934,7 @@ fn testLinkOrder(b: *Build, opts: Options) *Step { |
| 1818 | 1934 | // } |
| 1819 | 1935 | |
| 1820 | 1936 | { |
| 1821 | const exe = addExecutable(b, "main2", opts); | |
| 1937 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 1822 | 1938 | exe.addObject(main_o); |
| 1823 | 1939 | exe.linkSystemLibrary2("b", .{}); |
| 1824 | 1940 | exe.addLibraryPath(lib.getEmittedBinDirectory()); |
| ... | ... | @@ -1840,14 +1956,14 @@ fn testLinkOrder(b: *Build, opts: Options) *Step { |
| 1840 | 1956 | fn testLdScript(b: *Build, opts: Options) *Step { |
| 1841 | 1957 | const test_step = addTestStep(b, "ld-script", opts); |
| 1842 | 1958 | |
| 1843 | const dso = addSharedLibrary(b, "bar", opts); | |
| 1959 | const dso = addSharedLibrary(b, opts, .{ .name = "bar" }); | |
| 1844 | 1960 | addCSourceBytes(dso, "int foo() { return 42; }", &.{}); |
| 1845 | 1961 | |
| 1846 | 1962 | const scripts = WriteFile.create(b); |
| 1847 | 1963 | _ = scripts.add("liba.so", "INPUT(libfoo.so)"); |
| 1848 | 1964 | _ = scripts.add("libfoo.so", "GROUP(AS_NEEDED(-lbar))"); |
| 1849 | 1965 | |
| 1850 | const exe = addExecutable(b, "main", opts); | |
| 1966 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1851 | 1967 | addCSourceBytes(exe, |
| 1852 | 1968 | \\int foo(); |
| 1853 | 1969 | \\int main() { |
| ... | ... | @@ -1875,7 +1991,7 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { |
| 1875 | 1991 | const scripts = WriteFile.create(b); |
| 1876 | 1992 | _ = scripts.add("liba.so", "INPUT(libfoo.so)"); |
| 1877 | 1993 | |
| 1878 | const exe = addExecutable(b, "main", opts); | |
| 1994 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1879 | 1995 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 1880 | 1996 | exe.linkSystemLibrary2("a", .{}); |
| 1881 | 1997 | exe.addLibraryPath(scripts.getDirectory()); |
| ... | ... | @@ -1895,13 +2011,15 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { |
| 1895 | 2011 | fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { |
| 1896 | 2012 | const test_step = addTestStep(b, "mismatched-cpu-architecture-error", opts); |
| 1897 | 2013 | |
| 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, | |
| 1900 | 2020 | }); |
| 1901 | addCSourceBytes(obj, "int foo;", &.{}); | |
| 1902 | obj.strip = true; | |
| 1903 | 2021 | |
| 1904 | const exe = addExecutable(b, "main", opts); | |
| 2022 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 1905 | 2023 | addCSourceBytes(exe, |
| 1906 | 2024 | \\extern int foo; |
| 1907 | 2025 | \\int main() { |
| ... | ... | @@ -1922,7 +2040,7 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { |
| 1922 | 2040 | fn testLinkingC(b: *Build, opts: Options) *Step { |
| 1923 | 2041 | const test_step = addTestStep(b, "linking-c", opts); |
| 1924 | 2042 | |
| 1925 | const exe = addExecutable(b, "test", opts); | |
| 2043 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 1926 | 2044 | addCSourceBytes(exe, |
| 1927 | 2045 | \\#include <stdio.h> |
| 1928 | 2046 | \\int main() { |
| ... | ... | @@ -1951,7 +2069,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step { |
| 1951 | 2069 | fn testLinkingCpp(b: *Build, opts: Options) *Step { |
| 1952 | 2070 | const test_step = addTestStep(b, "linking-cpp", opts); |
| 1953 | 2071 | |
| 1954 | const exe = addExecutable(b, "test", opts); | |
| 2072 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 1955 | 2073 | addCppSourceBytes(exe, |
| 1956 | 2074 | \\#include <iostream> |
| 1957 | 2075 | \\int main() { |
| ... | ... | @@ -1981,24 +2099,28 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step { |
| 1981 | 2099 | fn testLinkingObj(b: *Build, opts: Options) *Step { |
| 1982 | 2100 | const test_step = addTestStep(b, "linking-obj", opts); |
| 1983 | 2101 | |
| 1984 | const obj = addObject(b, "aobj", opts); | |
| 1985 | addZigSourceBytes(obj, | |
| 2102 | const obj = addObject(b, opts, .{ | |
| 2103 | .name = "aobj", | |
| 2104 | .zig_source_bytes = | |
| 1986 | 2105 | \\extern var mod: usize; |
| 1987 | 2106 | \\export fn callMe() usize { |
| 1988 | 2107 | \\ return me * mod; |
| 1989 | 2108 | \\} |
| 1990 | 2109 | \\var me: usize = 42; |
| 1991 | ); | |
| 2110 | , | |
| 2111 | }); | |
| 1992 | 2112 | |
| 1993 | const exe = addExecutable(b, "testobj", opts); | |
| 1994 | addZigSourceBytes(exe, | |
| 2113 | const exe = addExecutable(b, opts, .{ | |
| 2114 | .name = "testobj", | |
| 2115 | .zig_source_bytes = | |
| 1995 | 2116 | \\const std = @import("std"); |
| 1996 | 2117 | \\extern fn callMe() usize; |
| 1997 | 2118 | \\export var mod: usize = 2; |
| 1998 | 2119 | \\pub fn main() void { |
| 1999 | 2120 | \\ std.debug.print("{d}\n", .{callMe()}); |
| 2000 | 2121 | \\} |
| 2001 | ); | |
| 2122 | , | |
| 2123 | }); | |
| 2002 | 2124 | exe.addObject(obj); |
| 2003 | 2125 | |
| 2004 | 2126 | const run = addRunArtifact(exe); |
| ... | ... | @@ -2011,26 +2133,32 @@ fn testLinkingObj(b: *Build, opts: Options) *Step { |
| 2011 | 2133 | fn testLinkingStaticLib(b: *Build, opts: Options) *Step { |
| 2012 | 2134 | const test_step = addTestStep(b, "linking-static-lib", opts); |
| 2013 | 2135 | |
| 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 | }); | |
| 2016 | 2140 | |
| 2017 | const lib = addStaticLibrary(b, "alib", opts); | |
| 2018 | addZigSourceBytes(lib, | |
| 2141 | const lib = addStaticLibrary(b, opts, .{ | |
| 2142 | .name = "alib", | |
| 2143 | .zig_source_bytes = | |
| 2019 | 2144 | \\export fn foo() i32 { |
| 2020 | 2145 | \\ return 42; |
| 2021 | 2146 | \\} |
| 2022 | ); | |
| 2147 | , | |
| 2148 | }); | |
| 2023 | 2149 | lib.addObject(obj); |
| 2024 | 2150 | |
| 2025 | const exe = addExecutable(b, "testlib", opts); | |
| 2026 | addZigSourceBytes(exe, | |
| 2151 | const exe = addExecutable(b, opts, .{ | |
| 2152 | .name = "testlib", | |
| 2153 | .zig_source_bytes = | |
| 2027 | 2154 | \\const std = @import("std"); |
| 2028 | 2155 | \\extern fn foo() i32; |
| 2029 | 2156 | \\extern var bar: i32; |
| 2030 | 2157 | \\pub fn main() void { |
| 2031 | 2158 | \\ std.debug.print("{d}\n", .{foo() + bar}); |
| 2032 | 2159 | \\} |
| 2033 | ); | |
| 2160 | , | |
| 2161 | }); | |
| 2034 | 2162 | exe.linkLibrary(lib); |
| 2035 | 2163 | |
| 2036 | 2164 | const run = addRunArtifact(exe); |
| ... | ... | @@ -2043,12 +2171,14 @@ fn testLinkingStaticLib(b: *Build, opts: Options) *Step { |
| 2043 | 2171 | fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 2044 | 2172 | const test_step = addTestStep(b, "linking-zig-static", opts); |
| 2045 | 2173 | |
| 2046 | const exe = addExecutable(b, "test", opts); | |
| 2047 | addZigSourceBytes(exe, | |
| 2174 | const exe = addExecutable(b, opts, .{ | |
| 2175 | .name = "test", | |
| 2176 | .zig_source_bytes = | |
| 2048 | 2177 | \\pub fn main() void { |
| 2049 | 2178 | \\ @import("std").debug.print("Hello World!\n", .{}); |
| 2050 | 2179 | \\} |
| 2051 | ); | |
| 2180 | , | |
| 2181 | }); | |
| 2052 | 2182 | |
| 2053 | 2183 | const run = addRunArtifact(exe); |
| 2054 | 2184 | run.expectStdErrEqual("Hello World!\n"); |
| ... | ... | @@ -2069,7 +2199,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { |
| 2069 | 2199 | fn testNoEhFrameHdr(b: *Build, opts: Options) *Step { |
| 2070 | 2200 | const test_step = addTestStep(b, "no-eh-frame-hdr", opts); |
| 2071 | 2201 | |
| 2072 | const exe = addExecutable(b, "main", opts); | |
| 2202 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2073 | 2203 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 2074 | 2204 | exe.link_eh_frame_hdr = false; |
| 2075 | 2205 | exe.linkLibC(); |
| ... | ... | @@ -2086,7 +2216,7 @@ fn testNoEhFrameHdr(b: *Build, opts: Options) *Step { |
| 2086 | 2216 | fn testPie(b: *Build, opts: Options) *Step { |
| 2087 | 2217 | const test_step = addTestStep(b, "hello-pie", opts); |
| 2088 | 2218 | |
| 2089 | const exe = addExecutable(b, "main", opts); | |
| 2219 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2090 | 2220 | addCSourceBytes(exe, |
| 2091 | 2221 | \\#include <stdio.h> |
| 2092 | 2222 | \\int main() { |
| ... | ... | @@ -2095,7 +2225,7 @@ fn testPie(b: *Build, opts: Options) *Step { |
| 2095 | 2225 | \\} |
| 2096 | 2226 | , &.{}); |
| 2097 | 2227 | exe.linkLibC(); |
| 2098 | exe.force_pic = true; | |
| 2228 | exe.root_module.pic = true; | |
| 2099 | 2229 | exe.pie = true; |
| 2100 | 2230 | |
| 2101 | 2231 | const run = addRunArtifact(exe); |
| ... | ... | @@ -2117,7 +2247,7 @@ fn testPie(b: *Build, opts: Options) *Step { |
| 2117 | 2247 | fn testPltGot(b: *Build, opts: Options) *Step { |
| 2118 | 2248 | const test_step = addTestStep(b, "plt-got", opts); |
| 2119 | 2249 | |
| 2120 | const dso = addSharedLibrary(b, "a", opts); | |
| 2250 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2121 | 2251 | addCSourceBytes(dso, |
| 2122 | 2252 | \\#include <stdio.h> |
| 2123 | 2253 | \\void ignore(void *foo) {} |
| ... | ... | @@ -2127,7 +2257,7 @@ fn testPltGot(b: *Build, opts: Options) *Step { |
| 2127 | 2257 | , &.{}); |
| 2128 | 2258 | dso.linkLibC(); |
| 2129 | 2259 | |
| 2130 | const exe = addExecutable(b, "main", opts); | |
| 2260 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2131 | 2261 | addCSourceBytes(exe, |
| 2132 | 2262 | \\void ignore(void *); |
| 2133 | 2263 | \\int hello(); |
| ... | ... | @@ -2135,7 +2265,7 @@ fn testPltGot(b: *Build, opts: Options) *Step { |
| 2135 | 2265 | \\int main() { hello(); } |
| 2136 | 2266 | , &.{}); |
| 2137 | 2267 | exe.linkLibrary(dso); |
| 2138 | exe.force_pic = true; | |
| 2268 | exe.root_module.pic = true; | |
| 2139 | 2269 | exe.linkLibC(); |
| 2140 | 2270 | // https://github.com/ziglang/zig/issues/17619 |
| 2141 | 2271 | exe.pie = true; |
| ... | ... | @@ -2151,10 +2281,12 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { |
| 2151 | 2281 | const test_step = addTestStep(b, "preinit-array", opts); |
| 2152 | 2282 | |
| 2153 | 2283 | { |
| 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 | }); | |
| 2156 | 2288 | |
| 2157 | const exe = addExecutable(b, "main1", opts); | |
| 2289 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2158 | 2290 | exe.addObject(obj); |
| 2159 | 2291 | |
| 2160 | 2292 | const check = exe.checkObject(); |
| ... | ... | @@ -2163,7 +2295,7 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { |
| 2163 | 2295 | } |
| 2164 | 2296 | |
| 2165 | 2297 | { |
| 2166 | const exe = addExecutable(b, "main2", opts); | |
| 2298 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2167 | 2299 | addCSourceBytes(exe, |
| 2168 | 2300 | \\void preinit_fn() {} |
| 2169 | 2301 | \\int main() {} |
| ... | ... | @@ -2183,38 +2315,48 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { |
| 2183 | 2315 | fn testRelocatableArchive(b: *Build, opts: Options) *Step { |
| 2184 | 2316 | const test_step = addTestStep(b, "relocatable-archive", opts); |
| 2185 | 2317 | |
| 2186 | const obj1 = addObject(b, "obj1", opts); | |
| 2187 | addCSourceBytes(obj1, | |
| 2318 | const obj1 = addObject(b, opts, .{ | |
| 2319 | .name = "obj1", | |
| 2320 | .c_source_bytes = | |
| 2188 | 2321 | \\void bar(); |
| 2189 | 2322 | \\void foo() { |
| 2190 | 2323 | \\ bar(); |
| 2191 | 2324 | \\} |
| 2192 | , &.{}); | |
| 2325 | , | |
| 2326 | }); | |
| 2193 | 2327 | |
| 2194 | const obj2 = addObject(b, "obj2", opts); | |
| 2195 | addCSourceBytes(obj2, | |
| 2328 | const obj2 = addObject(b, opts, .{ | |
| 2329 | .name = "obj2", | |
| 2330 | .c_source_bytes = | |
| 2196 | 2331 | \\void bar() {} |
| 2197 | , &.{}); | |
| 2332 | , | |
| 2333 | }); | |
| 2198 | 2334 | |
| 2199 | const obj3 = addObject(b, "obj3", opts); | |
| 2200 | addCSourceBytes(obj3, | |
| 2335 | const obj3 = addObject(b, opts, .{ | |
| 2336 | .name = "obj3", | |
| 2337 | .c_source_bytes = | |
| 2201 | 2338 | \\void baz(); |
| 2202 | , &.{}); | |
| 2339 | , | |
| 2340 | }); | |
| 2203 | 2341 | |
| 2204 | const obj4 = addObject(b, "obj4", opts); | |
| 2205 | addCSourceBytes(obj4, | |
| 2342 | const obj4 = addObject(b, opts, .{ | |
| 2343 | .name = "obj4", | |
| 2344 | .c_source_bytes = | |
| 2206 | 2345 | \\void foo(); |
| 2207 | 2346 | \\int main() { |
| 2208 | 2347 | \\ foo(); |
| 2209 | 2348 | \\} |
| 2210 | , &.{}); | |
| 2349 | , | |
| 2350 | }); | |
| 2211 | 2351 | |
| 2212 | const lib = addStaticLibrary(b, "lib", opts); | |
| 2352 | const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); | |
| 2213 | 2353 | lib.addObject(obj1); |
| 2214 | 2354 | lib.addObject(obj2); |
| 2215 | 2355 | lib.addObject(obj3); |
| 2216 | 2356 | |
| 2217 | const obj5 = addObject(b, "obj5", opts); | |
| 2357 | const obj5 = addObject(b, opts, .{ | |
| 2358 | .name = "obj5", | |
| 2359 | }); | |
| 2218 | 2360 | obj5.addObject(obj4); |
| 2219 | 2361 | obj5.linkLibrary(lib); |
| 2220 | 2362 | |
| ... | ... | @@ -2234,13 +2376,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { |
| 2234 | 2376 | const test_step = addTestStep(b, "relocatable-eh-frame", opts); |
| 2235 | 2377 | |
| 2236 | 2378 | { |
| 2237 | const obj = addObject(b, "obj1", opts); | |
| 2238 | addCppSourceBytes(obj, | |
| 2379 | const obj = addObject(b, opts, .{ | |
| 2380 | .name = "obj1", | |
| 2381 | .cpp_source_bytes = | |
| 2239 | 2382 | \\#include <stdexcept> |
| 2240 | 2383 | \\int try_me() { |
| 2241 | 2384 | \\ throw std::runtime_error("Oh no!"); |
| 2242 | 2385 | \\} |
| 2243 | , &.{}); | |
| 2386 | , | |
| 2387 | }); | |
| 2244 | 2388 | addCppSourceBytes(obj, |
| 2245 | 2389 | \\extern int try_me(); |
| 2246 | 2390 | \\int try_again() { |
| ... | ... | @@ -2249,7 +2393,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { |
| 2249 | 2393 | , &.{}); |
| 2250 | 2394 | obj.linkLibCpp(); |
| 2251 | 2395 | |
| 2252 | const exe = addExecutable(b, "test1", opts); | |
| 2396 | const exe = addExecutable(b, opts, .{ .name = "test1" }); | |
| 2253 | 2397 | addCppSourceBytes(exe, |
| 2254 | 2398 | \\#include <iostream> |
| 2255 | 2399 | \\#include <stdexcept> |
| ... | ... | @@ -2273,13 +2417,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { |
| 2273 | 2417 | |
| 2274 | 2418 | { |
| 2275 | 2419 | // 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 = | |
| 2278 | 2423 | \\#include <stdexcept> |
| 2279 | 2424 | \\int try_me() { |
| 2280 | 2425 | \\ throw std::runtime_error("Oh no!"); |
| 2281 | 2426 | \\} |
| 2282 | , &.{}); | |
| 2427 | , | |
| 2428 | }); | |
| 2283 | 2429 | addCppSourceBytes(obj, |
| 2284 | 2430 | \\extern int try_me(); |
| 2285 | 2431 | \\int try_again() { |
| ... | ... | @@ -2301,7 +2447,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { |
| 2301 | 2447 | , &.{}); |
| 2302 | 2448 | obj.linkLibCpp(); |
| 2303 | 2449 | |
| 2304 | const exe = addExecutable(b, "test2", opts); | |
| 2450 | const exe = addExecutable(b, opts, .{ .name = "test2" }); | |
| 2305 | 2451 | exe.addObject(obj); |
| 2306 | 2452 | exe.linkLibCpp(); |
| 2307 | 2453 | |
| ... | ... | @@ -2316,13 +2462,18 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { |
| 2316 | 2462 | fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step { |
| 2317 | 2463 | const test_step = addTestStep(b, "relocatable-no-eh-frame", opts); |
| 2318 | 2464 | |
| 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 | }, | |
| 2323 | 2472 | }); |
| 2324 | 2473 | |
| 2325 | const obj2 = addObject(b, "obj2", opts); | |
| 2474 | const obj2 = addObject(b, opts, .{ | |
| 2475 | .name = "obj2", | |
| 2476 | }); | |
| 2326 | 2477 | obj2.addObject(obj1); |
| 2327 | 2478 | |
| 2328 | 2479 | const check1 = obj1.checkObject(); |
| ... | ... | @@ -2343,23 +2494,25 @@ fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step { |
| 2343 | 2494 | fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { |
| 2344 | 2495 | const test_step = addTestStep(b, "shared-abs-symbol", opts); |
| 2345 | 2496 | |
| 2346 | const dso = addSharedLibrary(b, "a", opts); | |
| 2497 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2347 | 2498 | addAsmSourceBytes(dso, |
| 2348 | 2499 | \\.globl foo |
| 2349 | 2500 | \\foo = 3; |
| 2350 | 2501 | ); |
| 2351 | 2502 | |
| 2352 | const obj = addObject(b, "obj", opts); | |
| 2353 | addCSourceBytes(obj, | |
| 2503 | const obj = addObject(b, opts, .{ | |
| 2504 | .name = "obj", | |
| 2505 | .c_source_bytes = | |
| 2354 | 2506 | \\#include <stdio.h> |
| 2355 | 2507 | \\extern char foo; |
| 2356 | 2508 | \\int main() { printf("foo=%p\n", &foo); } |
| 2357 | , &.{}); | |
| 2358 | obj.force_pic = true; | |
| 2509 | , | |
| 2510 | .pic = true, | |
| 2511 | }); | |
| 2359 | 2512 | obj.linkLibC(); |
| 2360 | 2513 | |
| 2361 | 2514 | { |
| 2362 | const exe = addExecutable(b, "main1", opts); | |
| 2515 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2363 | 2516 | exe.addObject(obj); |
| 2364 | 2517 | exe.linkLibrary(dso); |
| 2365 | 2518 | exe.pie = true; |
| ... | ... | @@ -2380,7 +2533,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { |
| 2380 | 2533 | |
| 2381 | 2534 | // https://github.com/ziglang/zig/issues/17430 |
| 2382 | 2535 | // { |
| 2383 | // const exe = addExecutable(b, "main2", opts); | |
| 2536 | // const exe = addExecutable(b, opts, .{ .name = "main2"}); | |
| 2384 | 2537 | // exe.addObject(obj); |
| 2385 | 2538 | // exe.linkLibrary(dso); |
| 2386 | 2539 | // exe.pie = false; |
| ... | ... | @@ -2405,20 +2558,22 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { |
| 2405 | 2558 | fn testStrip(b: *Build, opts: Options) *Step { |
| 2406 | 2559 | const test_step = addTestStep(b, "strip", opts); |
| 2407 | 2560 | |
| 2408 | const obj = addObject(b, "obj", opts); | |
| 2409 | addCSourceBytes(obj, | |
| 2561 | const obj = addObject(b, opts, .{ | |
| 2562 | .name = "obj", | |
| 2563 | .c_source_bytes = | |
| 2410 | 2564 | \\#include <stdio.h> |
| 2411 | 2565 | \\int main() { |
| 2412 | 2566 | \\ printf("Hello!\n"); |
| 2413 | 2567 | \\ return 0; |
| 2414 | 2568 | \\} |
| 2415 | , &.{}); | |
| 2569 | , | |
| 2570 | }); | |
| 2416 | 2571 | obj.linkLibC(); |
| 2417 | 2572 | |
| 2418 | 2573 | { |
| 2419 | const exe = addExecutable(b, "main1", opts); | |
| 2574 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2420 | 2575 | exe.addObject(obj); |
| 2421 | exe.strip = false; | |
| 2576 | exe.root_module.strip = false; | |
| 2422 | 2577 | exe.linkLibC(); |
| 2423 | 2578 | |
| 2424 | 2579 | const check = exe.checkObject(); |
| ... | ... | @@ -2429,9 +2584,9 @@ fn testStrip(b: *Build, opts: Options) *Step { |
| 2429 | 2584 | } |
| 2430 | 2585 | |
| 2431 | 2586 | { |
| 2432 | const exe = addExecutable(b, "main2", opts); | |
| 2587 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2433 | 2588 | exe.addObject(obj); |
| 2434 | exe.strip = true; | |
| 2589 | exe.root_module.strip = true; | |
| 2435 | 2590 | exe.linkLibC(); |
| 2436 | 2591 | |
| 2437 | 2592 | const check = exe.checkObject(); |
| ... | ... | @@ -2447,16 +2602,19 @@ fn testStrip(b: *Build, opts: Options) *Step { |
| 2447 | 2602 | fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { |
| 2448 | 2603 | const test_step = addTestStep(b, "tls-df-static-tls", opts); |
| 2449 | 2604 | |
| 2450 | const obj = addObject(b, "obj", opts); | |
| 2451 | addCSourceBytes(obj, | |
| 2605 | const obj = addObject(b, opts, .{ | |
| 2606 | .name = "obj", | |
| 2607 | .c_source_bytes = | |
| 2452 | 2608 | \\static _Thread_local int foo = 5; |
| 2453 | 2609 | \\void mutate() { ++foo; } |
| 2454 | 2610 | \\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 | }); | |
| 2457 | 2615 | |
| 2458 | 2616 | { |
| 2459 | const dso = addSharedLibrary(b, "a", opts); | |
| 2617 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2460 | 2618 | dso.addObject(obj); |
| 2461 | 2619 | // dso.link_relax = true; |
| 2462 | 2620 | |
| ... | ... | @@ -2468,7 +2626,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { |
| 2468 | 2626 | |
| 2469 | 2627 | // TODO add -Wl,--no-relax |
| 2470 | 2628 | // { |
| 2471 | // const dso = addSharedLibrary(b, "a", opts); | |
| 2629 | // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); | |
| 2472 | 2630 | // dso.addObject(obj); |
| 2473 | 2631 | // dso.link_relax = false; |
| 2474 | 2632 | |
| ... | ... | @@ -2484,7 +2642,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { |
| 2484 | 2642 | fn testTlsDso(b: *Build, opts: Options) *Step { |
| 2485 | 2643 | const test_step = addTestStep(b, "tls-dso", opts); |
| 2486 | 2644 | |
| 2487 | const dso = addSharedLibrary(b, "a", opts); | |
| 2645 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2488 | 2646 | addCSourceBytes(dso, |
| 2489 | 2647 | \\extern _Thread_local int foo; |
| 2490 | 2648 | \\_Thread_local int bar; |
| ... | ... | @@ -2492,7 +2650,7 @@ fn testTlsDso(b: *Build, opts: Options) *Step { |
| 2492 | 2650 | \\int get_bar1() { return bar; } |
| 2493 | 2651 | , &.{}); |
| 2494 | 2652 | |
| 2495 | const exe = addExecutable(b, "main", opts); | |
| 2653 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2496 | 2654 | addCSourceBytes(exe, |
| 2497 | 2655 | \\#include <stdio.h> |
| 2498 | 2656 | \\_Thread_local int foo; |
| ... | ... | @@ -2526,8 +2684,9 @@ fn testTlsDso(b: *Build, opts: Options) *Step { |
| 2526 | 2684 | fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2527 | 2685 | const test_step = addTestStep(b, "tls-gd", opts); |
| 2528 | 2686 | |
| 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 = | |
| 2531 | 2690 | \\#include <stdio.h> |
| 2532 | 2691 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; |
| 2533 | 2692 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2; |
| ... | ... | @@ -2540,37 +2699,42 @@ fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2540 | 2699 | \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6()); |
| 2541 | 2700 | \\ return 0; |
| 2542 | 2701 | \\} |
| 2543 | , &.{}); | |
| 2702 | , | |
| 2703 | .pic = true, | |
| 2704 | }); | |
| 2544 | 2705 | main_o.linkLibC(); |
| 2545 | main_o.force_pic = true; | |
| 2546 | 2706 | |
| 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 = | |
| 2549 | 2710 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3; |
| 2550 | 2711 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5; |
| 2551 | 2712 | \\int get_x5() { return x5; } |
| 2552 | , &.{}); | |
| 2553 | a_o.force_pic = true; | |
| 2713 | , | |
| 2714 | .pic = true, | |
| 2715 | }); | |
| 2554 | 2716 | |
| 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 = | |
| 2557 | 2720 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4; |
| 2558 | 2721 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6; |
| 2559 | 2722 | \\int get_x6() { return x6; } |
| 2560 | , &.{}); | |
| 2561 | b_o.force_pic = true; | |
| 2723 | , | |
| 2724 | .pic = true, | |
| 2725 | }); | |
| 2562 | 2726 | |
| 2563 | 2727 | const exp_stdout = "1 2 3 4 5 6\n"; |
| 2564 | 2728 | |
| 2565 | const dso1 = addSharedLibrary(b, "a", opts); | |
| 2729 | const dso1 = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2566 | 2730 | dso1.addObject(a_o); |
| 2567 | 2731 | |
| 2568 | const dso2 = addSharedLibrary(b, "b", opts); | |
| 2732 | const dso2 = addSharedLibrary(b, opts, .{ .name = "b" }); | |
| 2569 | 2733 | dso2.addObject(b_o); |
| 2570 | 2734 | // dso2.link_relax = false; // TODO |
| 2571 | 2735 | |
| 2572 | 2736 | { |
| 2573 | const exe = addExecutable(b, "main1", opts); | |
| 2737 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2574 | 2738 | exe.addObject(main_o); |
| 2575 | 2739 | exe.linkLibrary(dso1); |
| 2576 | 2740 | exe.linkLibrary(dso2); |
| ... | ... | @@ -2581,7 +2745,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2581 | 2745 | } |
| 2582 | 2746 | |
| 2583 | 2747 | { |
| 2584 | const exe = addExecutable(b, "main2", opts); | |
| 2748 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2585 | 2749 | exe.addObject(main_o); |
| 2586 | 2750 | // exe.link_relax = false; // TODO |
| 2587 | 2751 | exe.linkLibrary(dso1); |
| ... | ... | @@ -2594,7 +2758,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2594 | 2758 | |
| 2595 | 2759 | // https://github.com/ziglang/zig/issues/17430 ?? |
| 2596 | 2760 | // { |
| 2597 | // const exe = addExecutable(b, "main3", opts); | |
| 2761 | // const exe = addExecutable(b, opts, .{ .name = "main3"}); | |
| 2598 | 2762 | // exe.addObject(main_o); |
| 2599 | 2763 | // exe.linkLibrary(dso1); |
| 2600 | 2764 | // exe.linkLibrary(dso2); |
| ... | ... | @@ -2606,7 +2770,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2606 | 2770 | // } |
| 2607 | 2771 | |
| 2608 | 2772 | // { |
| 2609 | // const exe = addExecutable(b, "main4", opts); | |
| 2773 | // const exe = addExecutable(b, opts, .{ .name = "main4"}); | |
| 2610 | 2774 | // exe.addObject(main_o); |
| 2611 | 2775 | // // exe.link_relax = false; // TODO |
| 2612 | 2776 | // exe.linkLibrary(dso1); |
| ... | ... | @@ -2624,8 +2788,9 @@ fn testTlsGd(b: *Build, opts: Options) *Step { |
| 2624 | 2788 | fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { |
| 2625 | 2789 | const test_step = addTestStep(b, "tls-gd-no-plt", opts); |
| 2626 | 2790 | |
| 2627 | const obj = addObject(b, "obj", opts); | |
| 2628 | addCSourceBytes(obj, | |
| 2791 | const obj = addObject(b, opts, .{ | |
| 2792 | .name = "obj", | |
| 2793 | .c_source_bytes = | |
| 2629 | 2794 | \\#include <stdio.h> |
| 2630 | 2795 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; |
| 2631 | 2796 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2; |
| ... | ... | @@ -2639,18 +2804,20 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { |
| 2639 | 2804 | \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6()); |
| 2640 | 2805 | \\ return 0; |
| 2641 | 2806 | \\} |
| 2642 | , &.{"-fno-plt"}); | |
| 2643 | obj.force_pic = true; | |
| 2807 | , | |
| 2808 | .c_source_flags = &.{"-fno-plt"}, | |
| 2809 | .pic = true, | |
| 2810 | }); | |
| 2644 | 2811 | obj.linkLibC(); |
| 2645 | 2812 | |
| 2646 | const a_so = addSharedLibrary(b, "a", opts); | |
| 2813 | const a_so = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2647 | 2814 | addCSourceBytes(a_so, |
| 2648 | 2815 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3; |
| 2649 | 2816 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5; |
| 2650 | 2817 | \\int get_x5() { return x5; } |
| 2651 | 2818 | , &.{"-fno-plt"}); |
| 2652 | 2819 | |
| 2653 | const b_so = addSharedLibrary(b, "b", opts); | |
| 2820 | const b_so = addSharedLibrary(b, opts, .{ .name = "b" }); | |
| 2654 | 2821 | addCSourceBytes(b_so, |
| 2655 | 2822 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4; |
| 2656 | 2823 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6; |
| ... | ... | @@ -2659,7 +2826,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { |
| 2659 | 2826 | // b_so.link_relax = false; // TODO |
| 2660 | 2827 | |
| 2661 | 2828 | { |
| 2662 | const exe = addExecutable(b, "main1", opts); | |
| 2829 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2663 | 2830 | exe.addObject(obj); |
| 2664 | 2831 | exe.linkLibrary(a_so); |
| 2665 | 2832 | exe.linkLibrary(b_so); |
| ... | ... | @@ -2673,7 +2840,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { |
| 2673 | 2840 | } |
| 2674 | 2841 | |
| 2675 | 2842 | { |
| 2676 | const exe = addExecutable(b, "main2", opts); | |
| 2843 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2677 | 2844 | exe.addObject(obj); |
| 2678 | 2845 | exe.linkLibrary(a_so); |
| 2679 | 2846 | exe.linkLibrary(b_so); |
| ... | ... | @@ -2693,8 +2860,9 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { |
| 2693 | 2860 | fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2694 | 2861 | const test_step = addTestStep(b, "tls-gd-to-ie", opts); |
| 2695 | 2862 | |
| 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 = | |
| 2698 | 2866 | \\#include <stdio.h> |
| 2699 | 2867 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; |
| 2700 | 2868 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x2 = 2; |
| ... | ... | @@ -2705,22 +2873,25 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2705 | 2873 | \\ printf("%d %d %d\n", x1, x2, x3); |
| 2706 | 2874 | \\ return 0; |
| 2707 | 2875 | \\} |
| 2708 | , &.{}); | |
| 2876 | , | |
| 2877 | .pic = true, | |
| 2878 | }); | |
| 2709 | 2879 | a_o.linkLibC(); |
| 2710 | a_o.force_pic = true; | |
| 2711 | 2880 | |
| 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 = | |
| 2714 | 2884 | \\int foo(); |
| 2715 | 2885 | \\int main() { foo(); } |
| 2716 | , &.{}); | |
| 2717 | b_o.force_pic = true; | |
| 2886 | , | |
| 2887 | .pic = true, | |
| 2888 | }); | |
| 2718 | 2889 | |
| 2719 | 2890 | { |
| 2720 | const dso = addSharedLibrary(b, "a1", opts); | |
| 2891 | const dso = addSharedLibrary(b, opts, .{ .name = "a1" }); | |
| 2721 | 2892 | dso.addObject(a_o); |
| 2722 | 2893 | |
| 2723 | const exe = addExecutable(b, "main1", opts); | |
| 2894 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2724 | 2895 | exe.addObject(b_o); |
| 2725 | 2896 | exe.linkLibrary(dso); |
| 2726 | 2897 | exe.linkLibC(); |
| ... | ... | @@ -2733,11 +2904,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2733 | 2904 | } |
| 2734 | 2905 | |
| 2735 | 2906 | { |
| 2736 | const dso = addSharedLibrary(b, "a2", opts); | |
| 2907 | const dso = addSharedLibrary(b, opts, .{ .name = "a2" }); | |
| 2737 | 2908 | dso.addObject(a_o); |
| 2738 | 2909 | // dso.link_relax = false; // TODO |
| 2739 | 2910 | |
| 2740 | const exe = addExecutable(b, "main2", opts); | |
| 2911 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2741 | 2912 | exe.addObject(b_o); |
| 2742 | 2913 | exe.linkLibrary(dso); |
| 2743 | 2914 | exe.linkLibC(); |
| ... | ... | @@ -2750,11 +2921,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2750 | 2921 | } |
| 2751 | 2922 | |
| 2752 | 2923 | // { |
| 2753 | // const dso = addSharedLibrary(b, "a", opts); | |
| 2924 | // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); | |
| 2754 | 2925 | // dso.addObject(a_o); |
| 2755 | 2926 | // dso.link_z_nodlopen = true; |
| 2756 | 2927 | |
| 2757 | // const exe = addExecutable(b, "main", opts); | |
| 2928 | // const exe = addExecutable(b, opts, .{ .name = "main"}); | |
| 2758 | 2929 | // exe.addObject(b_o); |
| 2759 | 2930 | // exe.linkLibrary(dso); |
| 2760 | 2931 | |
| ... | ... | @@ -2764,12 +2935,12 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2764 | 2935 | // } |
| 2765 | 2936 | |
| 2766 | 2937 | // { |
| 2767 | // const dso = addSharedLibrary(b, "a", opts); | |
| 2938 | // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); | |
| 2768 | 2939 | // dso.addObject(a_o); |
| 2769 | 2940 | // dso.link_relax = false; |
| 2770 | 2941 | // dso.link_z_nodlopen = true; |
| 2771 | 2942 | |
| 2772 | // const exe = addExecutable(b, "main", opts); | |
| 2943 | // const exe = addExecutable(b, opts, .{ .name = "main"}); | |
| 2773 | 2944 | // exe.addObject(b_o); |
| 2774 | 2945 | // exe.linkLibrary(dso); |
| 2775 | 2946 | |
| ... | ... | @@ -2784,7 +2955,7 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { |
| 2784 | 2955 | fn testTlsIe(b: *Build, opts: Options) *Step { |
| 2785 | 2956 | const test_step = addTestStep(b, "tls-ie", opts); |
| 2786 | 2957 | |
| 2787 | const dso = addSharedLibrary(b, "a", opts); | |
| 2958 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2788 | 2959 | addCSourceBytes(dso, |
| 2789 | 2960 | \\#include <stdio.h> |
| 2790 | 2961 | \\__attribute__((tls_model("initial-exec"))) static _Thread_local int foo; |
| ... | ... | @@ -2799,8 +2970,9 @@ fn testTlsIe(b: *Build, opts: Options) *Step { |
| 2799 | 2970 | , &.{}); |
| 2800 | 2971 | dso.linkLibC(); |
| 2801 | 2972 | |
| 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 = | |
| 2804 | 2976 | \\#include <stdio.h> |
| 2805 | 2977 | \\_Thread_local int baz; |
| 2806 | 2978 | \\void set(); |
| ... | ... | @@ -2812,13 +2984,14 @@ fn testTlsIe(b: *Build, opts: Options) *Step { |
| 2812 | 2984 | \\ print(); |
| 2813 | 2985 | \\ printf("%d\n", baz); |
| 2814 | 2986 | \\} |
| 2815 | , &.{}); | |
| 2987 | , | |
| 2988 | }); | |
| 2816 | 2989 | main_o.linkLibC(); |
| 2817 | 2990 | |
| 2818 | 2991 | const exp_stdout = "0 0 3 5 7\n"; |
| 2819 | 2992 | |
| 2820 | 2993 | { |
| 2821 | const exe = addExecutable(b, "main1", opts); | |
| 2994 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2822 | 2995 | exe.addObject(main_o); |
| 2823 | 2996 | exe.linkLibrary(dso); |
| 2824 | 2997 | exe.linkLibC(); |
| ... | ... | @@ -2831,7 +3004,7 @@ fn testTlsIe(b: *Build, opts: Options) *Step { |
| 2831 | 3004 | } |
| 2832 | 3005 | |
| 2833 | 3006 | { |
| 2834 | const exe = addExecutable(b, "main2", opts); | |
| 3007 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 2835 | 3008 | exe.addObject(main_o); |
| 2836 | 3009 | exe.linkLibrary(dso); |
| 2837 | 3010 | exe.linkLibC(); |
| ... | ... | @@ -2850,38 +3023,46 @@ fn testTlsIe(b: *Build, opts: Options) *Step { |
| 2850 | 3023 | fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { |
| 2851 | 3024 | const test_step = addTestStep(b, "tls-large-alignment", opts); |
| 2852 | 3025 | |
| 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 = | |
| 2855 | 3029 | \\__attribute__((section(".tdata1"))) |
| 2856 | 3030 | \\_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 | }); | |
| 2859 | 3035 | |
| 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 = | |
| 2862 | 3039 | \\__attribute__((section(".tdata2"))) |
| 2863 | 3040 | \\_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 | }); | |
| 2866 | 3045 | |
| 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 = | |
| 2869 | 3049 | \\#include <stdio.h> |
| 2870 | 3050 | \\extern _Thread_local int x; |
| 2871 | 3051 | \\extern _Thread_local int y[]; |
| 2872 | 3052 | \\int main() { |
| 2873 | 3053 | \\ printf("%d %d %d %d\n", x, y[0], y[1], y[2]); |
| 2874 | 3054 | \\} |
| 2875 | , &.{}); | |
| 2876 | c_o.force_pic = true; | |
| 3055 | , | |
| 3056 | .pic = true, | |
| 3057 | }); | |
| 2877 | 3058 | c_o.linkLibC(); |
| 2878 | 3059 | |
| 2879 | 3060 | { |
| 2880 | const dso = addSharedLibrary(b, "a", opts); | |
| 3061 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 2881 | 3062 | dso.addObject(a_o); |
| 2882 | 3063 | dso.addObject(b_o); |
| 2883 | 3064 | |
| 2884 | const exe = addExecutable(b, "main", opts); | |
| 3065 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2885 | 3066 | exe.addObject(c_o); |
| 2886 | 3067 | exe.linkLibrary(dso); |
| 2887 | 3068 | exe.linkLibC(); |
| ... | ... | @@ -2894,7 +3075,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { |
| 2894 | 3075 | } |
| 2895 | 3076 | |
| 2896 | 3077 | { |
| 2897 | const exe = addExecutable(b, "main", opts); | |
| 3078 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2898 | 3079 | exe.addObject(a_o); |
| 2899 | 3080 | exe.addObject(b_o); |
| 2900 | 3081 | exe.addObject(c_o); |
| ... | ... | @@ -2913,7 +3094,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { |
| 2913 | 3094 | fn testTlsLargeTbss(b: *Build, opts: Options) *Step { |
| 2914 | 3095 | const test_step = addTestStep(b, "tls-large-tbss", opts); |
| 2915 | 3096 | |
| 2916 | const exe = addExecutable(b, "main", opts); | |
| 3097 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2917 | 3098 | addAsmSourceBytes(exe, |
| 2918 | 3099 | \\.globl x, y |
| 2919 | 3100 | \\.section .tbss,"awT",@nobits |
| ... | ... | @@ -2947,7 +3128,7 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step { |
| 2947 | 3128 | fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { |
| 2948 | 3129 | const test_step = addTestStep(b, "tls-large-static-image", opts); |
| 2949 | 3130 | |
| 2950 | const exe = addExecutable(b, "main", opts); | |
| 3131 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 2951 | 3132 | addCSourceBytes(exe, "_Thread_local int x[] = { 1, 2, 3, [10000] = 5 };", &.{}); |
| 2952 | 3133 | addCSourceBytes(exe, |
| 2953 | 3134 | \\#include <stdio.h> |
| ... | ... | @@ -2956,7 +3137,7 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { |
| 2956 | 3137 | \\ printf("%d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[10000]); |
| 2957 | 3138 | \\} |
| 2958 | 3139 | , &.{}); |
| 2959 | exe.force_pic = true; | |
| 3140 | exe.root_module.pic = true; | |
| 2960 | 3141 | exe.linkLibC(); |
| 2961 | 3142 | // https://github.com/ziglang/zig/issues/17619 |
| 2962 | 3143 | exe.pie = true; |
| ... | ... | @@ -2971,8 +3152,9 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { |
| 2971 | 3152 | fn testTlsLd(b: *Build, opts: Options) *Step { |
| 2972 | 3153 | const test_step = addTestStep(b, "tls-ld", opts); |
| 2973 | 3154 | |
| 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 = | |
| 2976 | 3158 | \\#include <stdio.h> |
| 2977 | 3159 | \\extern _Thread_local int foo; |
| 2978 | 3160 | \\static _Thread_local int bar; |
| ... | ... | @@ -2983,18 +3165,23 @@ fn testTlsLd(b: *Build, opts: Options) *Step { |
| 2983 | 3165 | \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); |
| 2984 | 3166 | \\ return 0; |
| 2985 | 3167 | \\} |
| 2986 | , &.{"-ftls-model=local-dynamic"}); | |
| 2987 | main_o.force_pic = true; | |
| 3168 | , | |
| 3169 | .c_source_flags = &.{"-ftls-model=local-dynamic"}, | |
| 3170 | .pic = true, | |
| 3171 | }); | |
| 2988 | 3172 | main_o.linkLibC(); |
| 2989 | 3173 | |
| 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 | }); | |
| 2993 | 3180 | |
| 2994 | 3181 | const exp_stdout = "3 5 3 5\n"; |
| 2995 | 3182 | |
| 2996 | 3183 | { |
| 2997 | const exe = addExecutable(b, "main1", opts); | |
| 3184 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 2998 | 3185 | exe.addObject(main_o); |
| 2999 | 3186 | exe.addObject(a_o); |
| 3000 | 3187 | exe.linkLibC(); |
| ... | ... | @@ -3007,7 +3194,7 @@ fn testTlsLd(b: *Build, opts: Options) *Step { |
| 3007 | 3194 | } |
| 3008 | 3195 | |
| 3009 | 3196 | { |
| 3010 | const exe = addExecutable(b, "main2", opts); | |
| 3197 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 3011 | 3198 | exe.addObject(main_o); |
| 3012 | 3199 | exe.addObject(a_o); |
| 3013 | 3200 | exe.linkLibC(); |
| ... | ... | @@ -3026,14 +3213,14 @@ fn testTlsLd(b: *Build, opts: Options) *Step { |
| 3026 | 3213 | fn testTlsLdDso(b: *Build, opts: Options) *Step { |
| 3027 | 3214 | const test_step = addTestStep(b, "tls-ld-dso", opts); |
| 3028 | 3215 | |
| 3029 | const dso = addSharedLibrary(b, "a", opts); | |
| 3216 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3030 | 3217 | addCSourceBytes(dso, |
| 3031 | 3218 | \\static _Thread_local int def, def1; |
| 3032 | 3219 | \\int f0() { return ++def; } |
| 3033 | 3220 | \\int f1() { return ++def1 + def; } |
| 3034 | 3221 | , &.{"-ftls-model=local-dynamic"}); |
| 3035 | 3222 | |
| 3036 | const exe = addExecutable(b, "main", opts); | |
| 3223 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3037 | 3224 | addCSourceBytes(exe, |
| 3038 | 3225 | \\#include <stdio.h> |
| 3039 | 3226 | \\extern int f0(); |
| ... | ... | @@ -3060,8 +3247,9 @@ fn testTlsLdDso(b: *Build, opts: Options) *Step { |
| 3060 | 3247 | fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { |
| 3061 | 3248 | const test_step = addTestStep(b, "tls-ld-no-plt", opts); |
| 3062 | 3249 | |
| 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 = | |
| 3065 | 3253 | \\#include <stdio.h> |
| 3066 | 3254 | \\extern _Thread_local int foo; |
| 3067 | 3255 | \\static _Thread_local int bar; |
| ... | ... | @@ -3073,16 +3261,21 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { |
| 3073 | 3261 | \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); |
| 3074 | 3262 | \\ return 0; |
| 3075 | 3263 | \\} |
| 3076 | , &.{ "-ftls-model=local-dynamic", "-fno-plt" }); | |
| 3264 | , | |
| 3265 | .c_source_flags = &.{ "-ftls-model=local-dynamic", "-fno-plt" }, | |
| 3266 | .pic = true, | |
| 3267 | }); | |
| 3077 | 3268 | a_o.linkLibC(); |
| 3078 | a_o.force_pic = true; | |
| 3079 | 3269 | |
| 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 | }); | |
| 3083 | 3276 | |
| 3084 | 3277 | { |
| 3085 | const exe = addExecutable(b, "main1", opts); | |
| 3278 | const exe = addExecutable(b, opts, .{ .name = "main1" }); | |
| 3086 | 3279 | exe.addObject(a_o); |
| 3087 | 3280 | exe.addObject(b_o); |
| 3088 | 3281 | exe.linkLibC(); |
| ... | ... | @@ -3095,7 +3288,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { |
| 3095 | 3288 | } |
| 3096 | 3289 | |
| 3097 | 3290 | { |
| 3098 | const exe = addExecutable(b, "main2", opts); | |
| 3291 | const exe = addExecutable(b, opts, .{ .name = "main2" }); | |
| 3099 | 3292 | exe.addObject(a_o); |
| 3100 | 3293 | exe.addObject(b_o); |
| 3101 | 3294 | exe.linkLibC(); |
| ... | ... | @@ -3114,7 +3307,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { |
| 3114 | 3307 | fn testTlsNoPic(b: *Build, opts: Options) *Step { |
| 3115 | 3308 | const test_step = addTestStep(b, "tls-no-pic", opts); |
| 3116 | 3309 | |
| 3117 | const exe = addExecutable(b, "main", opts); | |
| 3310 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3118 | 3311 | addCSourceBytes(exe, |
| 3119 | 3312 | \\#include <stdio.h> |
| 3120 | 3313 | \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo; |
| ... | ... | @@ -3132,7 +3325,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step { |
| 3132 | 3325 | addCSourceBytes(exe, |
| 3133 | 3326 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo; |
| 3134 | 3327 | , &.{}); |
| 3135 | exe.force_pic = false; | |
| 3328 | exe.root_module.pic = false; | |
| 3136 | 3329 | exe.linkLibC(); |
| 3137 | 3330 | |
| 3138 | 3331 | const run = addRunArtifact(exe); |
| ... | ... | @@ -3145,7 +3338,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step { |
| 3145 | 3338 | fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { |
| 3146 | 3339 | const test_step = addTestStep(b, "tls-offset-alignment", opts); |
| 3147 | 3340 | |
| 3148 | const dso = addSharedLibrary(b, "a", opts); | |
| 3341 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3149 | 3342 | addCSourceBytes(dso, |
| 3150 | 3343 | \\#include <assert.h> |
| 3151 | 3344 | \\#include <stdlib.h> |
| ... | ... | @@ -3163,7 +3356,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { |
| 3163 | 3356 | , &.{}); |
| 3164 | 3357 | dso.linkLibC(); |
| 3165 | 3358 | |
| 3166 | const exe = addExecutable(b, "main", opts); | |
| 3359 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3167 | 3360 | addCSourceBytes(exe, |
| 3168 | 3361 | \\#include <pthread.h> |
| 3169 | 3362 | \\#include <dlfcn.h> |
| ... | ... | @@ -3186,7 +3379,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { |
| 3186 | 3379 | , &.{}); |
| 3187 | 3380 | exe.addRPath(dso.getEmittedBinDirectory()); |
| 3188 | 3381 | exe.linkLibC(); |
| 3189 | exe.force_pic = true; | |
| 3382 | exe.root_module.pic = true; | |
| 3190 | 3383 | // https://github.com/ziglang/zig/issues/17619 |
| 3191 | 3384 | exe.pie = true; |
| 3192 | 3385 | |
| ... | ... | @@ -3200,8 +3393,9 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { |
| 3200 | 3393 | fn testTlsPic(b: *Build, opts: Options) *Step { |
| 3201 | 3394 | const test_step = addTestStep(b, "tls-pic", opts); |
| 3202 | 3395 | |
| 3203 | const obj = addObject(b, "obj", opts); | |
| 3204 | addCSourceBytes(obj, | |
| 3396 | const obj = addObject(b, opts, .{ | |
| 3397 | .name = "obj", | |
| 3398 | .c_source_bytes = | |
| 3205 | 3399 | \\#include <stdio.h> |
| 3206 | 3400 | \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo; |
| 3207 | 3401 | \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int bar; |
| ... | ... | @@ -3213,11 +3407,12 @@ fn testTlsPic(b: *Build, opts: Options) *Step { |
| 3213 | 3407 | \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); |
| 3214 | 3408 | \\ return 0; |
| 3215 | 3409 | \\} |
| 3216 | , &.{}); | |
| 3410 | , | |
| 3411 | .pic = true, | |
| 3412 | }); | |
| 3217 | 3413 | obj.linkLibC(); |
| 3218 | obj.force_pic = true; | |
| 3219 | 3414 | |
| 3220 | const exe = addExecutable(b, "main", opts); | |
| 3415 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3221 | 3416 | addCSourceBytes(exe, |
| 3222 | 3417 | \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo = 3; |
| 3223 | 3418 | , &.{}); |
| ... | ... | @@ -3236,30 +3431,38 @@ fn testTlsPic(b: *Build, opts: Options) *Step { |
| 3236 | 3431 | fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { |
| 3237 | 3432 | const test_step = addTestStep(b, "tls-small-alignment", opts); |
| 3238 | 3433 | |
| 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 = | |
| 3241 | 3437 | \\.text |
| 3242 | 3438 | \\.byte 0 |
| 3243 | ); | |
| 3244 | a_o.force_pic = true; | |
| 3439 | \\ | |
| 3440 | , | |
| 3441 | .pic = true, | |
| 3442 | }); | |
| 3245 | 3443 | |
| 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 | }); | |
| 3249 | 3450 | |
| 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 = | |
| 3252 | 3454 | \\#include <stdio.h> |
| 3253 | 3455 | \\extern _Thread_local char x; |
| 3254 | 3456 | \\int main() { |
| 3255 | 3457 | \\ printf("%d\n", x); |
| 3256 | 3458 | \\} |
| 3257 | , &.{}); | |
| 3459 | , | |
| 3460 | .pic = true, | |
| 3461 | }); | |
| 3258 | 3462 | c_o.linkLibC(); |
| 3259 | c_o.force_pic = true; | |
| 3260 | 3463 | |
| 3261 | 3464 | { |
| 3262 | const exe = addExecutable(b, "main", opts); | |
| 3465 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3263 | 3466 | exe.addObject(a_o); |
| 3264 | 3467 | exe.addObject(b_o); |
| 3265 | 3468 | exe.addObject(c_o); |
| ... | ... | @@ -3273,11 +3476,11 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { |
| 3273 | 3476 | } |
| 3274 | 3477 | |
| 3275 | 3478 | { |
| 3276 | const dso = addSharedLibrary(b, "a", opts); | |
| 3479 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3277 | 3480 | dso.addObject(a_o); |
| 3278 | 3481 | dso.addObject(b_o); |
| 3279 | 3482 | |
| 3280 | const exe = addExecutable(b, "main", opts); | |
| 3483 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3281 | 3484 | exe.addObject(c_o); |
| 3282 | 3485 | exe.linkLibrary(dso); |
| 3283 | 3486 | exe.linkLibC(); |
| ... | ... | @@ -3295,7 +3498,7 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { |
| 3295 | 3498 | fn testTlsStatic(b: *Build, opts: Options) *Step { |
| 3296 | 3499 | const test_step = addTestStep(b, "tls-static", opts); |
| 3297 | 3500 | |
| 3298 | const exe = addExecutable(b, "test", opts); | |
| 3501 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 3299 | 3502 | addCSourceBytes(exe, |
| 3300 | 3503 | \\#include <stdio.h> |
| 3301 | 3504 | \\_Thread_local int a = 10; |
| ... | ... | @@ -3326,12 +3529,14 @@ fn testTlsStatic(b: *Build, opts: Options) *Step { |
| 3326 | 3529 | fn testUnknownFileTypeError(b: *Build, opts: Options) *Step { |
| 3327 | 3530 | const test_step = addTestStep(b, "unknown-file-type-error", opts); |
| 3328 | 3531 | |
| 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;", | |
| 3331 | 3537 | }); |
| 3332 | addZigSourceBytes(dylib, "export var foo: i32 = 0;"); | |
| 3333 | 3538 | |
| 3334 | const exe = addExecutable(b, "main", opts); | |
| 3539 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3335 | 3540 | addCSourceBytes(exe, |
| 3336 | 3541 | \\extern int foo; |
| 3337 | 3542 | \\int main() { |
| ... | ... | @@ -3354,28 +3559,34 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step { |
| 3354 | 3559 | fn testUnresolvedError(b: *Build, opts: Options) *Step { |
| 3355 | 3560 | const test_step = addTestStep(b, "unresolved-error", opts); |
| 3356 | 3561 | |
| 3357 | const obj1 = addObject(b, "a", opts); | |
| 3358 | addCSourceBytes(obj1, | |
| 3562 | const obj1 = addObject(b, opts, .{ | |
| 3563 | .name = "a", | |
| 3564 | .c_source_bytes = | |
| 3359 | 3565 | \\#include <stdio.h> |
| 3360 | 3566 | \\int foo(); |
| 3361 | 3567 | \\int bar() { |
| 3362 | 3568 | \\ return foo() + 1; |
| 3363 | 3569 | \\} |
| 3364 | , &.{"-ffunction-sections"}); | |
| 3570 | , | |
| 3571 | .c_source_flags = &.{"-ffunction-sections"}, | |
| 3572 | }); | |
| 3365 | 3573 | obj1.linkLibC(); |
| 3366 | 3574 | |
| 3367 | const obj2 = addObject(b, "b", opts); | |
| 3368 | addCSourceBytes(obj2, | |
| 3575 | const obj2 = addObject(b, opts, .{ | |
| 3576 | .name = "b", | |
| 3577 | .c_source_bytes = | |
| 3369 | 3578 | \\#include <stdio.h> |
| 3370 | 3579 | \\int foo(); |
| 3371 | 3580 | \\int bar(); |
| 3372 | 3581 | \\int main() { |
| 3373 | 3582 | \\ return foo() + bar(); |
| 3374 | 3583 | \\} |
| 3375 | , &.{"-ffunction-sections"}); | |
| 3584 | , | |
| 3585 | .c_source_flags = &.{"-ffunction-sections"}, | |
| 3586 | }); | |
| 3376 | 3587 | obj2.linkLibC(); |
| 3377 | 3588 | |
| 3378 | const exe = addExecutable(b, "main", opts); | |
| 3589 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3379 | 3590 | exe.addObject(obj1); |
| 3380 | 3591 | exe.addObject(obj2); |
| 3381 | 3592 | exe.linkLibC(); |
| ... | ... | @@ -3392,19 +3603,21 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step { |
| 3392 | 3603 | fn testWeakExports(b: *Build, opts: Options) *Step { |
| 3393 | 3604 | const test_step = addTestStep(b, "weak-exports", opts); |
| 3394 | 3605 | |
| 3395 | const obj = addObject(b, "obj", opts); | |
| 3396 | addCSourceBytes(obj, | |
| 3606 | const obj = addObject(b, opts, .{ | |
| 3607 | .name = "obj", | |
| 3608 | .c_source_bytes = | |
| 3397 | 3609 | \\#include <stdio.h> |
| 3398 | 3610 | \\__attribute__((weak)) int foo(); |
| 3399 | 3611 | \\int main() { |
| 3400 | 3612 | \\ printf("%d\n", foo ? foo() : 3); |
| 3401 | 3613 | \\} |
| 3402 | , &.{}); | |
| 3614 | , | |
| 3615 | .pic = true, | |
| 3616 | }); | |
| 3403 | 3617 | obj.linkLibC(); |
| 3404 | obj.force_pic = true; | |
| 3405 | 3618 | |
| 3406 | 3619 | { |
| 3407 | const dso = addSharedLibrary(b, "a", opts); | |
| 3620 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3408 | 3621 | dso.addObject(obj); |
| 3409 | 3622 | dso.linkLibC(); |
| 3410 | 3623 | |
| ... | ... | @@ -3415,7 +3628,7 @@ fn testWeakExports(b: *Build, opts: Options) *Step { |
| 3415 | 3628 | } |
| 3416 | 3629 | |
| 3417 | 3630 | { |
| 3418 | const exe = addExecutable(b, "main", opts); | |
| 3631 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3419 | 3632 | exe.addObject(obj); |
| 3420 | 3633 | exe.linkLibC(); |
| 3421 | 3634 | // https://github.com/ziglang/zig/issues/17619 |
| ... | ... | @@ -3437,14 +3650,14 @@ fn testWeakExports(b: *Build, opts: Options) *Step { |
| 3437 | 3650 | fn testWeakUndefsDso(b: *Build, opts: Options) *Step { |
| 3438 | 3651 | const test_step = addTestStep(b, "weak-undef-dso", opts); |
| 3439 | 3652 | |
| 3440 | const dso = addSharedLibrary(b, "a", opts); | |
| 3653 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3441 | 3654 | addCSourceBytes(dso, |
| 3442 | 3655 | \\__attribute__((weak)) int foo(); |
| 3443 | 3656 | \\int bar() { return foo ? foo() : -1; } |
| 3444 | 3657 | , &.{}); |
| 3445 | 3658 | |
| 3446 | 3659 | { |
| 3447 | const exe = addExecutable(b, "main", opts); | |
| 3660 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3448 | 3661 | addCSourceBytes(exe, |
| 3449 | 3662 | \\#include <stdio.h> |
| 3450 | 3663 | \\int bar(); |
| ... | ... | @@ -3461,7 +3674,7 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step { |
| 3461 | 3674 | } |
| 3462 | 3675 | |
| 3463 | 3676 | { |
| 3464 | const exe = addExecutable(b, "main", opts); | |
| 3677 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3465 | 3678 | addCSourceBytes(exe, |
| 3466 | 3679 | \\#include <stdio.h> |
| 3467 | 3680 | \\int foo() { return 5; } |
| ... | ... | @@ -3484,12 +3697,14 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step { |
| 3484 | 3697 | fn testZNow(b: *Build, opts: Options) *Step { |
| 3485 | 3698 | const test_step = addTestStep(b, "z-now", opts); |
| 3486 | 3699 | |
| 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 | }); | |
| 3490 | 3705 | |
| 3491 | 3706 | { |
| 3492 | const dso = addSharedLibrary(b, "a", opts); | |
| 3707 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3493 | 3708 | dso.addObject(obj); |
| 3494 | 3709 | |
| 3495 | 3710 | const check = dso.checkObject(); |
| ... | ... | @@ -3499,7 +3714,7 @@ fn testZNow(b: *Build, opts: Options) *Step { |
| 3499 | 3714 | } |
| 3500 | 3715 | |
| 3501 | 3716 | { |
| 3502 | const dso = addSharedLibrary(b, "a", opts); | |
| 3717 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3503 | 3718 | dso.addObject(obj); |
| 3504 | 3719 | dso.link_z_lazy = true; |
| 3505 | 3720 | |
| ... | ... | @@ -3515,7 +3730,7 @@ fn testZNow(b: *Build, opts: Options) *Step { |
| 3515 | 3730 | fn testZStackSize(b: *Build, opts: Options) *Step { |
| 3516 | 3731 | const test_step = addTestStep(b, "z-stack-size", opts); |
| 3517 | 3732 | |
| 3518 | const exe = addExecutable(b, "main", opts); | |
| 3733 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3519 | 3734 | addCSourceBytes(exe, "int main() { return 0; }", &.{}); |
| 3520 | 3735 | exe.stack_size = 0x800000; |
| 3521 | 3736 | exe.linkLibC(); |
| ... | ... | @@ -3540,8 +3755,9 @@ fn testZText(b: *Build, opts: Options) *Step { |
| 3540 | 3755 | // musl supports only a very limited number of text relocations and only in DSOs (and |
| 3541 | 3756 | // rightly so!). |
| 3542 | 3757 | |
| 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 = | |
| 3545 | 3761 | \\.globl fn1 |
| 3546 | 3762 | \\fn1: |
| 3547 | 3763 | \\ sub $8, %rsp |
| ... | ... | @@ -3549,10 +3765,13 @@ fn testZText(b: *Build, opts: Options) *Step { |
| 3549 | 3765 | \\ call *%rax |
| 3550 | 3766 | \\ add $8, %rsp |
| 3551 | 3767 | \\ ret |
| 3552 | ); | |
| 3768 | \\ | |
| 3769 | , | |
| 3770 | }); | |
| 3553 | 3771 | |
| 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 = | |
| 3556 | 3775 | \\int fn1(); |
| 3557 | 3776 | \\int fn2() { |
| 3558 | 3777 | \\ return 3; |
| ... | ... | @@ -3561,15 +3780,16 @@ fn testZText(b: *Build, opts: Options) *Step { |
| 3561 | 3780 | \\int fnn() { |
| 3562 | 3781 | \\ return fn1(); |
| 3563 | 3782 | \\} |
| 3564 | , &.{}); | |
| 3565 | b_o.force_pic = true; | |
| 3783 | , | |
| 3784 | .pic = true, | |
| 3785 | }); | |
| 3566 | 3786 | |
| 3567 | const dso = addSharedLibrary(b, "a", opts); | |
| 3787 | const dso = addSharedLibrary(b, opts, .{ .name = "a" }); | |
| 3568 | 3788 | dso.addObject(a_o); |
| 3569 | 3789 | dso.addObject(b_o); |
| 3570 | 3790 | dso.link_z_notext = true; |
| 3571 | 3791 | |
| 3572 | const exe = addExecutable(b, "main", opts); | |
| 3792 | const exe = addExecutable(b, opts, .{ .name = "main" }); | |
| 3573 | 3793 | addCSourceBytes(exe, |
| 3574 | 3794 | \\#include <stdio.h> |
| 3575 | 3795 | \\int fnn(); |
| ... | ... | @@ -3608,13 +3828,11 @@ const addObject = link.addObject; |
| 3608 | 3828 | const addRunArtifact = link.addRunArtifact; |
| 3609 | 3829 | const addSharedLibrary = link.addSharedLibrary; |
| 3610 | 3830 | const addStaticLibrary = link.addStaticLibrary; |
| 3611 | const addZigSourceBytes = link.addZigSourceBytes; | |
| 3612 | 3831 | const expectLinkErrors = link.expectLinkErrors; |
| 3613 | 3832 | const link = @import("link.zig"); |
| 3614 | 3833 | const std = @import("std"); |
| 3615 | 3834 | |
| 3616 | 3835 | const Build = std.Build; |
| 3617 | const CrossTarget = std.zig.CrossTarget; | |
| 3618 | 3836 | const Options = link.Options; |
| 3619 | 3837 | const Step = Build.Step; |
| 3620 | 3838 | const WriteFile = Step.WriteFile; |
test/link/glibc_compat/build.zig+3-3| ... | ... | @@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | for ([_][]const u8{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| { |
| 8 | 8 | const exe = b.addExecutable(.{ |
| 9 | 9 | .name = t, |
| 10 | .root_source_file = .{ .path = "main.c" }, | |
| 11 | .target = std.zig.CrossTarget.parse( | |
| 10 | .target = b.resolveTargetQuery(std.Target.Query.parse( | |
| 12 | 11 | .{ .arch_os_abi = t }, |
| 13 | ) catch unreachable, | |
| 12 | ) catch unreachable), | |
| 14 | 13 | }); |
| 14 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" } }); | |
| 15 | 15 | exe.linkLibC(); |
| 16 | 16 | // TODO: actually test the output |
| 17 | 17 | _ = 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 |
| 14 | 14 | const lib_a = b.addStaticLibrary(.{ |
| 15 | 15 | .name = "a", |
| 16 | 16 | .optimize = optimize, |
| 17 | .target = .{}, | |
| 17 | .target = b.host, | |
| 18 | 18 | }); |
| 19 | 19 | lib_a.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &[_][]const u8{} }); |
| 20 | 20 | lib_a.addIncludePath(.{ .path = "." }); |
| ... | ... | @@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 22 | 22 | const lib_b = b.addStaticLibrary(.{ |
| 23 | 23 | .name = "b", |
| 24 | 24 | .optimize = optimize, |
| 25 | .target = .{}, | |
| 25 | .target = b.host, | |
| 26 | 26 | }); |
| 27 | 27 | lib_b.addCSourceFile(.{ .file = .{ .path = "b.c" }, .flags = &[_][]const u8{} }); |
| 28 | 28 | lib_b.addIncludePath(.{ .path = "." }); |
test/link/link.zig+133-43| ... | ... | @@ -7,62 +7,160 @@ pub fn build(b: *Build) void { |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | pub const Options = struct { |
| 10 | target: CrossTarget, | |
| 10 | target: std.Build.ResolvedTarget, | |
| 11 | 11 | optimize: std.builtin.OptimizeMode = .Debug, |
| 12 | 12 | use_llvm: bool = true, |
| 13 | 13 | use_lld: bool = false, |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | pub fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { | |
| 17 | const target = opts.target.zigTriple(b.allocator) catch @panic("OOM"); | |
| 16 | pub fn addTestStep(b: *Build, prefix: []const u8, opts: Options) *Step { | |
| 17 | const target = opts.target.result.zigTriple(b.allocator) catch @panic("OOM"); | |
| 18 | 18 | const optimize = @tagName(opts.optimize); |
| 19 | 19 | 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, | |
| 24 | 22 | }) catch @panic("OOM"); |
| 25 | 23 | return b.step(name, ""); |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | pub 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, | |
| 26 | const 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 | ||
| 38 | pub 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, | |
| 35 | 51 | }); |
| 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; | |
| 36 | 68 | } |
| 37 | 69 | |
| 38 | pub 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, | |
| 70 | pub 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, | |
| 45 | 83 | }); |
| 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; | |
| 46 | 100 | } |
| 47 | 101 | |
| 48 | pub 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, | |
| 102 | pub 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, | |
| 55 | 115 | }); |
| 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; | |
| 56 | 132 | } |
| 57 | 133 | |
| 58 | pub 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, | |
| 134 | pub 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, | |
| 65 | 147 | }); |
| 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; | |
| 66 | 164 | } |
| 67 | 165 | |
| 68 | 166 | pub fn addRunArtifact(comp: *Compile) *Run { |
| ... | ... | @@ -72,13 +170,6 @@ pub fn addRunArtifact(comp: *Compile) *Run { |
| 72 | 170 | return run; |
| 73 | 171 | } |
| 74 | 172 | |
| 75 | pub 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 | ||
| 82 | 173 | pub fn addCSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void { |
| 83 | 174 | const b = comp.step.owner; |
| 84 | 175 | const file = WriteFile.create(b).add("a.c", bytes); |
| ... | ... | @@ -108,7 +199,6 @@ const std = @import("std"); |
| 108 | 199 | |
| 109 | 200 | const Build = std.Build; |
| 110 | 201 | const Compile = Step.Compile; |
| 111 | const CrossTarget = std.zig.CrossTarget; | |
| 112 | 202 | const Run = Step.Run; |
| 113 | 203 | const Step = Build.Step; |
| 114 | 204 | const WriteFile = Step.WriteFile; |
test/link/macho.zig+32-29| ... | ... | @@ -1,26 +1,29 @@ |
| 1 | 1 | //! Here we test our MachO linker for correctness and functionality. |
| 2 | 2 | //! TODO migrate standalone tests from test/link/macho/* to here. |
| 3 | 3 | |
| 4 | pub fn testAll(b: *Build) *Step { | |
| 4 | pub fn testAll(b: *std.Build) *Step { | |
| 5 | 5 | const macho_step = b.step("test-macho", "Run MachO tests"); |
| 6 | 6 | |
| 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 | })); | |
| 10 | 10 | |
| 11 | 11 | return macho_step; |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { | |
| 14 | fn testResolvingBoundarySymbols(b: *std.Build, opts: Options) *Step { | |
| 15 | 15 | const test_step = addTestStep(b, "macho-resolving-boundary-symbols", opts); |
| 16 | 16 | |
| 17 | const obj1 = addObject(b, "obj1", opts); | |
| 18 | addCppSourceBytes(obj1, | |
| 17 | const obj1 = addObject(b, opts, .{ | |
| 18 | .name = "obj1", | |
| 19 | .cpp_source_bytes = | |
| 19 | 20 | \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST,__message_ptr"))) = "codebase"; |
| 20 | , &.{}); | |
| 21 | , | |
| 22 | }); | |
| 21 | 23 | |
| 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 = | |
| 24 | 27 | \\const std = @import("std"); |
| 25 | 28 | \\extern fn interop() [*:0]const u8; |
| 26 | 29 | \\pub fn main() !void { |
| ... | ... | @@ -28,23 +31,27 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { |
| 28 | 31 | \\ std.mem.span(interop()), |
| 29 | 32 | \\ }); |
| 30 | 33 | \\} |
| 31 | ); | |
| 34 | , | |
| 35 | }); | |
| 32 | 36 | |
| 33 | 37 | { |
| 34 | const obj2 = addObject(b, "obj2", opts); | |
| 35 | addCppSourceBytes(obj2, | |
| 38 | const obj2 = addObject(b, opts, .{ | |
| 39 | .name = "obj2", | |
| 40 | .cpp_source_bytes = | |
| 36 | 41 | \\extern const char* message_pointer __asm("section$start$__DATA_CONST$__message_ptr"); |
| 37 | 42 | \\extern "C" const char* interop() { |
| 38 | 43 | \\ return message_pointer; |
| 39 | 44 | \\} |
| 40 | , &.{}); | |
| 45 | , | |
| 46 | }); | |
| 41 | 47 | |
| 42 | const exe = addExecutable(b, "test", opts); | |
| 48 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 43 | 49 | exe.addObject(obj1); |
| 44 | 50 | exe.addObject(obj2); |
| 45 | 51 | exe.addObject(main_o); |
| 46 | 52 | |
| 47 | const run = addRunArtifact(exe); | |
| 53 | const run = b.addRunArtifact(exe); | |
| 54 | run.skip_foreign_checks = true; | |
| 48 | 55 | run.expectStdErrEqual("All your codebase are belong to us.\n"); |
| 49 | 56 | test_step.dependOn(&run.step); |
| 50 | 57 | |
| ... | ... | @@ -55,15 +62,17 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { |
| 55 | 62 | } |
| 56 | 63 | |
| 57 | 64 | { |
| 58 | const obj3 = addObject(b, "obj3", opts); | |
| 59 | addCppSourceBytes(obj3, | |
| 65 | const obj3 = addObject(b, opts, .{ | |
| 66 | .name = "obj3", | |
| 67 | .cpp_source_bytes = | |
| 60 | 68 | \\extern const char* message_pointer __asm("section$start$__DATA$__message_ptr"); |
| 61 | 69 | \\extern "C" const char* interop() { |
| 62 | 70 | \\ return message_pointer; |
| 63 | 71 | \\} |
| 64 | , &.{}); | |
| 72 | , | |
| 73 | }); | |
| 65 | 74 | |
| 66 | const exe = addExecutable(b, "test", opts); | |
| 75 | const exe = addExecutable(b, opts, .{ .name = "test" }); | |
| 67 | 76 | exe.addObject(obj1); |
| 68 | 77 | exe.addObject(obj3); |
| 69 | 78 | exe.addObject(main_o); |
| ... | ... | @@ -77,20 +86,14 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { |
| 77 | 86 | return test_step; |
| 78 | 87 | } |
| 79 | 88 | |
| 80 | fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { | |
| 89 | fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step { | |
| 81 | 90 | return link.addTestStep(b, "macho-" ++ prefix, opts); |
| 82 | 91 | } |
| 83 | 92 | |
| 84 | const addCppSourceBytes = link.addCppSourceBytes; | |
| 85 | const addExecutable = link.addExecutable; | |
| 86 | 93 | const addObject = link.addObject; |
| 87 | const addRunArtifact = link.addRunArtifact; | |
| 88 | const addZigSourceBytes = link.addZigSourceBytes; | |
| 94 | const addExecutable = link.addExecutable; | |
| 89 | 95 | const expectLinkErrors = link.expectLinkErrors; |
| 90 | 96 | const link = @import("link.zig"); |
| 91 | 97 | const std = @import("std"); |
| 92 | ||
| 93 | const Build = std.Build; | |
| 94 | const CrossTarget = std.zig.CrossTarget; | |
| 95 | 98 | const Options = link.Options; |
| 96 | const Step = Build.Step; | |
| 99 | const Step = std.Build.Step; |
test/link/macho/bugs/13056/build.zig+3-3| ... | ... | @@ -14,14 +14,14 @@ pub fn build(b: *std.Build) void { |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | fn 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 | |
| 20 | 19 | @panic("macOS SDK is required to run the test"); |
| 21 | 20 | |
| 22 | 21 | const exe = b.addExecutable(.{ |
| 23 | 22 | .name = "test", |
| 24 | 23 | .optimize = optimize, |
| 24 | .target = b.host, | |
| 25 | 25 | }); |
| 26 | 26 | exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) }); |
| 27 | 27 | 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 { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const exe = b.addExecutable(.{ |
| 19 | 19 | .name = "test", |
test/link/macho/bugs/16308/build.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | const test_step = b.step("test", "Test it"); |
| 7 | 7 | b.default_step = test_step; |
| 8 | 8 | |
| 9 | const target: std.zig.CrossTarget = .{ .os_tag = .macos }; | |
| 9 | const target = b.resolveTargetQuery(.{ .os_tag = .macos }); | |
| 10 | 10 | |
| 11 | 11 | const lib = b.addSharedLibrary(.{ |
| 12 | 12 | .name = "a", |
test/link/macho/bugs/16628/build.zig+1-1| ... | ... | @@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void { |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | fn 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 }); | |
| 19 | 19 | |
| 20 | 20 | const exe = b.addExecutable(.{ |
| 21 | 21 | .name = "test", |
test/link/macho/dead_strip/build.zig+2-2| ... | ... | @@ -4,7 +4,7 @@ pub const requires_symlinks = true; |
| 4 | 4 | |
| 5 | 5 | pub fn build(b: *std.Build) void { |
| 6 | 6 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 7 | const target: std.zig.CrossTarget = .{ .os_tag = .macos }; | |
| 7 | const target = b.resolveTargetQuery(.{ .os_tag = .macos }); | |
| 8 | 8 | |
| 9 | 9 | const test_step = b.step("test", "Test the program"); |
| 10 | 10 | b.default_step = test_step; |
| ... | ... | @@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void { |
| 44 | 44 | fn createScenario( |
| 45 | 45 | b: *std.Build, |
| 46 | 46 | optimize: std.builtin.OptimizeMode, |
| 47 | target: std.zig.CrossTarget, | |
| 47 | target: std.Build.ResolvedTarget, | |
| 48 | 48 | name: []const u8, |
| 49 | 49 | ) *std.Build.Step.Compile { |
| 50 | 50 | const exe = b.addExecutable(.{ |
test/link/macho/dead_strip_dylibs/build.zig+1| ... | ... | @@ -52,6 +52,7 @@ fn createScenario( |
| 52 | 52 | const exe = b.addExecutable(.{ |
| 53 | 53 | .name = name, |
| 54 | 54 | .optimize = optimize, |
| 55 | .target = b.host, | |
| 55 | 56 | }); |
| 56 | 57 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); |
| 57 | 58 | exe.linkLibC(); |
test/link/macho/dylib/build.zig+2-2| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const dylib = b.addSharedLibrary(.{ |
| 19 | 19 | .name = "a", |
| ... | ... | @@ -55,7 +55,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 55 | 55 | |
| 56 | 56 | check_exe.checkInHeaders(); |
| 57 | 57 | check_exe.checkExact("cmd RPATH"); |
| 58 | check_exe.checkExactPath("path", dylib.getOutputDirectorySource()); | |
| 58 | check_exe.checkExactPath("path", dylib.getEmittedBinDirectory()); | |
| 59 | 59 | test_step.dependOn(&check_exe.step); |
| 60 | 60 | |
| 61 | 61 | const run = b.addRunArtifact(exe); |
test/link/macho/empty/build.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const exe = b.addExecutable(.{ |
| 19 | 19 | .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 |
| 16 | 16 | const exe = b.addExecutable(.{ |
| 17 | 17 | .name = "main", |
| 18 | 18 | .optimize = optimize, |
| 19 | .target = .{ .os_tag = .macos }, | |
| 19 | .target = b.resolveTargetQuery(.{ .os_tag = .macos }), | |
| 20 | 20 | }); |
| 21 | 21 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); |
| 22 | 22 | 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 |
| 16 | 16 | const lib = b.addStaticLibrary(.{ |
| 17 | 17 | .name = "main", |
| 18 | 18 | .optimize = optimize, |
| 19 | .target = .{ .os_tag = .macos }, | |
| 19 | .target = b.resolveTargetQuery(.{ .os_tag = .macos }), | |
| 20 | 20 | }); |
| 21 | 21 | lib.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); |
| 22 | 22 | lib.linkLibC(); |
| ... | ... | @@ -24,7 +24,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 24 | 24 | const exe = b.addExecutable(.{ |
| 25 | 25 | .name = "main", |
| 26 | 26 | .optimize = optimize, |
| 27 | .target = .{ .os_tag = .macos }, | |
| 27 | .target = b.resolveTargetQuery(.{ .os_tag = .macos }), | |
| 28 | 28 | }); |
| 29 | 29 | exe.linkLibrary(lib); |
| 30 | 30 | 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 |
| 16 | 16 | const lib = b.addSharedLibrary(.{ |
| 17 | 17 | .name = "bootstrap", |
| 18 | 18 | .optimize = optimize, |
| 19 | .target = .{ .os_tag = .macos }, | |
| 19 | .target = b.resolveTargetQuery(.{ .os_tag = .macos }), | |
| 20 | 20 | }); |
| 21 | 21 | lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} }); |
| 22 | 22 | lib.linkLibC(); |
| ... | ... | @@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 25 | 25 | const exe = b.addExecutable(.{ |
| 26 | 26 | .name = "main", |
| 27 | 27 | .optimize = optimize, |
| 28 | .target = .{ .os_tag = .macos }, | |
| 28 | .target = b.resolveTargetQuery(.{ .os_tag = .macos }), | |
| 29 | 29 | }); |
| 30 | 30 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); |
| 31 | 31 | exe.linkLibrary(lib); |
test/link/macho/headerpad/build.zig+1| ... | ... | @@ -112,6 +112,7 @@ fn simpleExe( |
| 112 | 112 | const exe = b.addExecutable(.{ |
| 113 | 113 | .name = name, |
| 114 | 114 | .optimize = optimize, |
| 115 | .target = b.host, | |
| 115 | 116 | }); |
| 116 | 117 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); |
| 117 | 118 | exe.linkLibC(); |
test/link/macho/linksection/build.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const obj = b.addObject(.{ |
| 19 | 19 | .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 |
| 19 | 19 | const exe = b.addExecutable(.{ |
| 20 | 20 | .name = "test", |
| 21 | 21 | .optimize = optimize, |
| 22 | .target = b.host, | |
| 22 | 23 | }); |
| 23 | 24 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); |
| 24 | 25 | exe.linkLibC(); |
test/link/macho/needed_library/build.zig+2-2| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const dylib = b.addSharedLibrary(.{ |
| 19 | 19 | .name = "a", |
| ... | ... | @@ -33,7 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 33 | 33 | }); |
| 34 | 34 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); |
| 35 | 35 | exe.linkLibC(); |
| 36 | exe.linkSystemLibraryNeeded("a"); | |
| 36 | exe.root_module.linkSystemLibrary("a", .{ .needed = true }); | |
| 37 | 37 | exe.addLibraryPath(dylib.getEmittedBinDirectory()); |
| 38 | 38 | exe.addRPath(dylib.getEmittedBinDirectory()); |
| 39 | 39 | 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 |
| 17 | 17 | const exe = b.addExecutable(.{ |
| 18 | 18 | .name = "test", |
| 19 | 19 | .optimize = optimize, |
| 20 | .target = b.host, | |
| 20 | 21 | }); |
| 21 | 22 | exe.addIncludePath(.{ .path = "." }); |
| 22 | 23 | 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 |
| 17 | 17 | const exe = b.addExecutable(.{ |
| 18 | 18 | .name = "test", |
| 19 | 19 | .optimize = optimize, |
| 20 | .target = b.host, | |
| 20 | 21 | }); |
| 21 | 22 | b.default_step.dependOn(&exe.step); |
| 22 | 23 | exe.addIncludePath(.{ .path = "." }); |
test/link/macho/pagezero/build.zig+1-1| ... | ... | @@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | b.default_step = test_step; |
| 8 | 8 | |
| 9 | 9 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 10 | const target: std.zig.CrossTarget = .{ .os_tag = .macos }; | |
| 10 | const target = b.resolveTargetQuery(.{ .os_tag = .macos }); | |
| 11 | 11 | |
| 12 | 12 | { |
| 13 | 13 | const exe = b.addExecutable(.{ |
test/link/macho/reexports/build.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const lib = b.addStaticLibrary(.{ |
| 19 | 19 | .name = "a", |
test/link/macho/search_strategy/build.zig+3-3| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | { |
| 19 | 19 | // -search_dylibs_first |
| ... | ... | @@ -45,9 +45,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 45 | 45 | fn createScenario( |
| 46 | 46 | b: *std.Build, |
| 47 | 47 | optimize: std.builtin.OptimizeMode, |
| 48 | target: std.zig.CrossTarget, | |
| 48 | target: std.Build.ResolvedTarget, | |
| 49 | 49 | name: []const u8, |
| 50 | search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy, | |
| 50 | search_strategy: std.Build.Module.SystemLib.SearchStrategy, | |
| 51 | 51 | ) *std.Build.Step.Compile { |
| 52 | 52 | const static = b.addStaticLibrary(.{ |
| 53 | 53 | .name = name, |
test/link/macho/stack_size/build.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const exe = b.addExecutable(.{ |
| 19 | 19 | .name = "main", |
test/link/macho/strict_validation/build.zig+1-1| ... | ... | @@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void { |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | fn 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 }); | |
| 18 | 18 | |
| 19 | 19 | const exe = b.addExecutable(.{ |
| 20 | 20 | .name = "main", |
test/link/macho/tbdv3/build.zig+1-1| ... | ... | @@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void { |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | 17 | fn 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 }); | |
| 19 | 19 | |
| 20 | 20 | const lib = b.addSharedLibrary(.{ |
| 21 | 21 | .name = "a", |
test/link/macho/tls/build.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const lib = b.addSharedLibrary(.{ |
| 19 | 19 | .name = "a", |
test/link/macho/unwind_info/build.zig+3-3| ... | ... | @@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void { |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | fn 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 }); | |
| 18 | 18 | |
| 19 | 19 | testUnwindInfo(b, test_step, optimize, target, false, "no-dead-strip"); |
| 20 | 20 | testUnwindInfo(b, test_step, optimize, target, true, "yes-dead-strip"); |
| ... | ... | @@ -24,7 +24,7 @@ fn testUnwindInfo( |
| 24 | 24 | b: *std.Build, |
| 25 | 25 | test_step: *std.Build.Step, |
| 26 | 26 | optimize: std.builtin.OptimizeMode, |
| 27 | target: std.zig.CrossTarget, | |
| 27 | target: std.Build.ResolvedTarget, | |
| 28 | 28 | dead_strip: bool, |
| 29 | 29 | name: []const u8, |
| 30 | 30 | ) void { |
| ... | ... | @@ -66,7 +66,7 @@ fn testUnwindInfo( |
| 66 | 66 | fn createScenario( |
| 67 | 67 | b: *std.Build, |
| 68 | 68 | optimize: std.builtin.OptimizeMode, |
| 69 | target: std.zig.CrossTarget, | |
| 69 | target: std.Build.ResolvedTarget, | |
| 70 | 70 | name: []const u8, |
| 71 | 71 | ) *std.Build.Step.Compile { |
| 72 | 72 | 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 |
| 17 | 17 | const exe = b.addExecutable(.{ |
| 18 | 18 | .name = "test", |
| 19 | 19 | .optimize = optimize, |
| 20 | .target = b.host, | |
| 20 | 21 | }); |
| 21 | 22 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); |
| 22 | 23 | exe.linkLibC(); |
test/link/macho/weak_library/build.zig+2-2| ... | ... | @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | fn 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 }); | |
| 17 | 17 | |
| 18 | 18 | const dylib = b.addSharedLibrary(.{ |
| 19 | 19 | .name = "a", |
| ... | ... | @@ -32,7 +32,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 32 | 32 | }); |
| 33 | 33 | exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); |
| 34 | 34 | exe.linkLibC(); |
| 35 | exe.linkSystemLibraryWeak("a"); | |
| 35 | exe.root_module.linkSystemLibrary("a", .{ .weak = true }); | |
| 36 | 36 | exe.addLibraryPath(dylib.getEmittedBinDirectory()); |
| 37 | 37 | exe.addRPath(dylib.getEmittedBinDirectory()); |
| 38 | 38 |
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 |
| 59 | 59 | .name = "test1", |
| 60 | 60 | .root_source_file = .{ .path = "main.zig" }, |
| 61 | 61 | .optimize = optimize, |
| 62 | .target = .{}, | |
| 62 | .target = b.host, | |
| 63 | 63 | }); |
| 64 | 64 | |
| 65 | 65 | for (files) |file| { |
| ... | ... | @@ -77,12 +77,12 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built |
| 77 | 77 | { |
| 78 | 78 | const lib_a = b.addStaticLibrary(.{ |
| 79 | 79 | .name = "test2_a", |
| 80 | .target = .{}, | |
| 80 | .target = b.host, | |
| 81 | 81 | .optimize = optimize, |
| 82 | 82 | }); |
| 83 | 83 | const lib_b = b.addStaticLibrary(.{ |
| 84 | 84 | .name = "test2_b", |
| 85 | .target = .{}, | |
| 85 | .target = b.host, | |
| 86 | 86 | .optimize = optimize, |
| 87 | 87 | }); |
| 88 | 88 | |
| ... | ... | @@ -94,6 +94,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built |
| 94 | 94 | const exe = b.addExecutable(.{ |
| 95 | 95 | .name = "test2", |
| 96 | 96 | .root_source_file = .{ .path = "main.zig" }, |
| 97 | .target = b.host, | |
| 97 | 98 | .optimize = optimize, |
| 98 | 99 | }); |
| 99 | 100 | exe.linkLibrary(lib_a); |
| ... | ... | @@ -110,19 +111,19 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built |
| 110 | 111 | { |
| 111 | 112 | const lib_a = b.addStaticLibrary(.{ |
| 112 | 113 | .name = "test3_a", |
| 113 | .target = .{}, | |
| 114 | .target = b.host, | |
| 114 | 115 | .optimize = optimize, |
| 115 | 116 | }); |
| 116 | 117 | const lib_b = b.addStaticLibrary(.{ |
| 117 | 118 | .name = "test3_b", |
| 118 | .target = .{}, | |
| 119 | .target = b.host, | |
| 119 | 120 | .optimize = optimize, |
| 120 | 121 | }); |
| 121 | 122 | |
| 122 | 123 | for (files, 1..) |file, i| { |
| 123 | 124 | const obj = b.addObject(.{ |
| 124 | 125 | .name = b.fmt("obj_{}", .{i}), |
| 125 | .target = .{}, | |
| 126 | .target = b.host, | |
| 126 | 127 | .optimize = optimize, |
| 127 | 128 | }); |
| 128 | 129 | obj.addCSourceFile(.{ .file = file, .flags = &flags }); |
| ... | ... | @@ -134,6 +135,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built |
| 134 | 135 | const exe = b.addExecutable(.{ |
| 135 | 136 | .name = "test3", |
| 136 | 137 | .root_source_file = .{ .path = "main.zig" }, |
| 138 | .target = b.host, | |
| 137 | 139 | .optimize = optimize, |
| 138 | 140 | }); |
| 139 | 141 | 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 |
| 20 | 20 | .root_source_file = .{ .path = "main.zig" }, |
| 21 | 21 | .optimize = optimize, |
| 22 | 22 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, |
| 23 | .strip = false, | |
| 23 | 24 | }); |
| 24 | 25 | lib.entry = .disabled; |
| 25 | 26 | lib.use_llvm = false; |
| 26 | 27 | lib.use_lld = false; |
| 27 | lib.strip = false; | |
| 28 | 28 | |
| 29 | 29 | const check = lib.checkObject(); |
| 30 | 30 | check.checkInHeaders(); |
test/link/wasm/basic-features/build.zig+2-2| ... | ... | @@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void { |
| 8 | 8 | .name = "lib", |
| 9 | 9 | .root_source_file = .{ .path = "main.zig" }, |
| 10 | 10 | .optimize = .Debug, |
| 11 | .target = .{ | |
| 11 | .target = b.resolveTargetQuery(.{ | |
| 12 | 12 | .cpu_arch = .wasm32, |
| 13 | 13 | .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, |
| 14 | 14 | .cpu_features_add = std.Target.wasm.featureSet(&.{.atomics}), |
| 15 | 15 | .os_tag = .freestanding, |
| 16 | }, | |
| 16 | }), | |
| 17 | 17 | }); |
| 18 | 18 | lib.entry = .disabled; |
| 19 | 19 | 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 |
| 17 | 17 | const lib = b.addExecutable(.{ |
| 18 | 18 | .name = "lib", |
| 19 | 19 | .root_source_file = .{ .path = "lib.zig" }, |
| 20 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 20 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 21 | 21 | .optimize = optimize_mode, |
| 22 | .strip = false, | |
| 22 | 23 | }); |
| 23 | 24 | lib.entry = .disabled; |
| 24 | 25 | lib.use_llvm = false; |
| 25 | 26 | lib.use_lld = false; |
| 26 | lib.strip = false; | |
| 27 | 27 | // to make sure the bss segment is emitted, we must import memory |
| 28 | 28 | lib.import_memory = true; |
| 29 | 29 | lib.link_gc_sections = false; |
| ... | ... | @@ -65,13 +65,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt |
| 65 | 65 | const lib = b.addExecutable(.{ |
| 66 | 66 | .name = "lib", |
| 67 | 67 | .root_source_file = .{ .path = "lib2.zig" }, |
| 68 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 68 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 69 | 69 | .optimize = optimize_mode, |
| 70 | .strip = false, | |
| 70 | 71 | }); |
| 71 | 72 | lib.entry = .disabled; |
| 72 | 73 | lib.use_llvm = false; |
| 73 | 74 | lib.use_lld = false; |
| 74 | lib.strip = false; | |
| 75 | 75 | // to make sure the bss segment is emitted, we must import memory |
| 76 | 76 | lib.import_memory = true; |
| 77 | 77 | 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 { |
| 17 | 17 | }); |
| 18 | 18 | lib.entry = .disabled; |
| 19 | 19 | lib.use_lld = false; |
| 20 | lib.export_symbol_names = &.{ "foo", "bar" }; | |
| 20 | lib.root_module.export_symbol_names = &.{ "foo", "bar" }; | |
| 21 | 21 | lib.global_base = 0; // put data section at address 0 to make data symbols easier to parse |
| 22 | 22 | |
| 23 | 23 | 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 |
| 17 | 17 | .name = "no-export", |
| 18 | 18 | .root_source_file = .{ .path = "main.zig" }, |
| 19 | 19 | .optimize = optimize, |
| 20 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 20 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 21 | 21 | }); |
| 22 | 22 | no_export.entry = .disabled; |
| 23 | 23 | no_export.use_llvm = false; |
| ... | ... | @@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 27 | 27 | .name = "dynamic", |
| 28 | 28 | .root_source_file = .{ .path = "main.zig" }, |
| 29 | 29 | .optimize = optimize, |
| 30 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 30 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 31 | 31 | }); |
| 32 | 32 | dynamic_export.entry = .disabled; |
| 33 | 33 | dynamic_export.rdynamic = true; |
| ... | ... | @@ -38,10 +38,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 38 | 38 | .name = "force", |
| 39 | 39 | .root_source_file = .{ .path = "main.zig" }, |
| 40 | 40 | .optimize = optimize, |
| 41 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 41 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 42 | 42 | }); |
| 43 | 43 | force_export.entry = .disabled; |
| 44 | force_export.export_symbol_names = &.{"foo"}; | |
| 44 | force_export.root_module.export_symbol_names = &.{"foo"}; | |
| 45 | 45 | force_export.use_llvm = false; |
| 46 | 46 | force_export.use_lld = false; |
| 47 | 47 |
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 |
| 14 | 14 | const lib = b.addExecutable(.{ |
| 15 | 15 | .name = "lib", |
| 16 | 16 | .root_source_file = .{ .path = "lib.zig" }, |
| 17 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 17 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 18 | 18 | .optimize = optimize, |
| 19 | 19 | }); |
| 20 | 20 | 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 |
| 17 | 17 | .name = "extern", |
| 18 | 18 | .root_source_file = .{ .path = "main.zig" }, |
| 19 | 19 | .optimize = optimize, |
| 20 | .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi }, | |
| 20 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }), | |
| 21 | 21 | }); |
| 22 | 22 | exe.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} }); |
| 23 | 23 | 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 |
| 16 | 16 | const import_table = b.addExecutable(.{ |
| 17 | 17 | .name = "import_table", |
| 18 | 18 | .root_source_file = .{ .path = "lib.zig" }, |
| 19 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 19 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 20 | 20 | .optimize = optimize, |
| 21 | 21 | }); |
| 22 | 22 | import_table.entry = .disabled; |
| ... | ... | @@ -28,7 +28,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 28 | 28 | const export_table = b.addExecutable(.{ |
| 29 | 29 | .name = "export_table", |
| 30 | 30 | .root_source_file = .{ .path = "lib.zig" }, |
| 31 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 31 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 32 | 32 | .optimize = optimize, |
| 33 | 33 | }); |
| 34 | 34 | export_table.entry = .disabled; |
| ... | ... | @@ -40,7 +40,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize |
| 40 | 40 | const regular_table = b.addExecutable(.{ |
| 41 | 41 | .name = "regular_table", |
| 42 | 42 | .root_source_file = .{ .path = "lib.zig" }, |
| 43 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 43 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 44 | 44 | .optimize = optimize, |
| 45 | 45 | }); |
| 46 | 46 | regular_table.entry = .disabled; |
test/link/wasm/infer-features/build.zig+4-4| ... | ... | @@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | const c_obj = b.addObject(.{ |
| 8 | 8 | .name = "c_obj", |
| 9 | 9 | .optimize = .Debug, |
| 10 | .target = .{ | |
| 10 | .target = b.resolveTargetQuery(.{ | |
| 11 | 11 | .cpu_arch = .wasm32, |
| 12 | 12 | .cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge }, |
| 13 | 13 | .os_tag = .freestanding, |
| 14 | }, | |
| 14 | }), | |
| 15 | 15 | }); |
| 16 | 16 | c_obj.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} }); |
| 17 | 17 | |
| ... | ... | @@ -21,11 +21,11 @@ pub fn build(b: *std.Build) void { |
| 21 | 21 | .name = "lib", |
| 22 | 22 | .root_source_file = .{ .path = "main.zig" }, |
| 23 | 23 | .optimize = .Debug, |
| 24 | .target = .{ | |
| 24 | .target = b.resolveTargetQuery(.{ | |
| 25 | 25 | .cpu_arch = .wasm32, |
| 26 | 26 | .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, |
| 27 | 27 | .os_tag = .freestanding, |
| 28 | }, | |
| 28 | }), | |
| 29 | 29 | }); |
| 30 | 30 | lib.entry = .disabled; |
| 31 | 31 | 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 |
| 17 | 17 | const lib = b.addExecutable(.{ |
| 18 | 18 | .name = "lib", |
| 19 | 19 | .root_source_file = .{ .path = "lib.zig" }, |
| 20 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 20 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 21 | 21 | .optimize = optimize, |
| 22 | .strip = false, | |
| 22 | 23 | }); |
| 23 | 24 | lib.entry = .disabled; |
| 24 | 25 | lib.use_llvm = false; |
| 25 | 26 | lib.use_lld = false; |
| 26 | lib.strip = false; | |
| 27 | 27 | b.installArtifact(lib); |
| 28 | 28 | |
| 29 | 29 | 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 |
| 16 | 16 | const lib = b.addExecutable(.{ |
| 17 | 17 | .name = "lib", |
| 18 | 18 | .root_source_file = .{ .path = "lib.zig" }, |
| 19 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 19 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 20 | 20 | .optimize = optimize, |
| 21 | .strip = false, | |
| 21 | 22 | }); |
| 22 | 23 | lib.entry = .disabled; |
| 23 | 24 | lib.use_llvm = false; |
| 24 | 25 | lib.use_lld = false; |
| 25 | lib.strip = false; | |
| 26 | 26 | lib.link_gc_sections = false; // so data is not garbage collected and we can verify data section |
| 27 | 27 | b.installArtifact(lib); |
| 28 | 28 |
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 |
| 21 | 21 | .os_tag = .freestanding, |
| 22 | 22 | }, |
| 23 | 23 | .optimize = optimize_mode, |
| 24 | .strip = false, | |
| 25 | .single_threaded = false, | |
| 24 | 26 | }); |
| 25 | 27 | lib.entry = .disabled; |
| 26 | 28 | lib.use_lld = false; |
| 27 | lib.strip = false; | |
| 28 | 29 | lib.import_memory = true; |
| 29 | 30 | lib.export_memory = true; |
| 30 | 31 | lib.shared_memory = true; |
| 31 | 32 | lib.max_memory = 67108864; |
| 32 | lib.single_threaded = false; | |
| 33 | lib.export_symbol_names = &.{"foo"}; | |
| 33 | lib.root_module.export_symbol_names = &.{"foo"}; | |
| 34 | 34 | |
| 35 | 35 | const check_lib = lib.checkObject(); |
| 36 | 36 |
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 |
| 16 | 16 | const lib = b.addExecutable(.{ |
| 17 | 17 | .name = "lib", |
| 18 | 18 | .root_source_file = .{ .path = "lib.zig" }, |
| 19 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 19 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 20 | 20 | .optimize = optimize, |
| 21 | .strip = false, | |
| 21 | 22 | }); |
| 22 | 23 | lib.entry = .disabled; |
| 23 | 24 | lib.use_llvm = false; |
| 24 | 25 | lib.use_lld = false; |
| 25 | lib.strip = false; | |
| 26 | 26 | lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size |
| 27 | 27 | lib.link_gc_sections = false; |
| 28 | 28 | 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 |
| 16 | 16 | const lib = b.addExecutable(.{ |
| 17 | 17 | .name = "lib", |
| 18 | 18 | .root_source_file = .{ .path = "lib.zig" }, |
| 19 | .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, | |
| 19 | .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), | |
| 20 | 20 | .optimize = optimize, |
| 21 | .strip = false, | |
| 21 | 22 | }); |
| 22 | 23 | lib.entry = .disabled; |
| 23 | 24 | lib.use_llvm = false; |
| 24 | 25 | lib.use_lld = false; |
| 25 | lib.strip = false; | |
| 26 | 26 | b.installArtifact(lib); |
| 27 | 27 | |
| 28 | 28 | const check_lib = lib.checkObject(); |
test/llvm_targets.zig+9-5| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Cases = @import("src/Cases.zig"); |
| 3 | 3 | |
| 4 | const targets = [_]std.zig.CrossTarget{ | |
| 4 | const targets = [_]std.Target.Query{ | |
| 5 | 5 | .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none }, |
| 6 | 6 | .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none }, |
| 7 | 7 | .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .simulator }, |
| ... | ... | @@ -127,17 +127,21 @@ const targets = [_]std.zig.CrossTarget{ |
| 127 | 127 | .{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none }, |
| 128 | 128 | }; |
| 129 | 129 | |
| 130 | pub fn addCases(ctx: *Cases, build_options: @import("cases.zig").BuildOptions) !void { | |
| 130 | pub fn addCases( | |
| 131 | ctx: *Cases, | |
| 132 | build_options: @import("cases.zig").BuildOptions, | |
| 133 | b: *std.Build, | |
| 134 | ) !void { | |
| 131 | 135 | 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) { | |
| 134 | 138 | .m68k => if (!build_options.llvm_has_m68k) continue, |
| 135 | 139 | .csky => if (!build_options.llvm_has_csky) continue, |
| 136 | 140 | .arc => if (!build_options.llvm_has_arc) continue, |
| 137 | 141 | .xtensa => if (!build_options.llvm_has_xtensa) continue, |
| 138 | 142 | else => {}, |
| 139 | 143 | }; |
| 140 | var case = ctx.noEmitUsingLlvmBackend("llvm_targets", target); | |
| 144 | var case = ctx.noEmitUsingLlvmBackend("llvm_targets", b.resolveTargetQuery(target_query)); | |
| 141 | 145 | case.addCompile(""); |
| 142 | 146 | } |
| 143 | 147 | } |
test/nvptx.zig+12-15| ... | ... | @@ -1,9 +1,14 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Cases = @import("src/Cases.zig"); |
| 3 | 3 | |
| 4 | pub fn addCases(ctx: *Cases) !void { | |
| 4 | pub fn addCases(ctx: *Cases, b: *std.Build) !void { | |
| 5 | const target = b.resolveTargetQuery(.{ | |
| 6 | .cpu_arch = .nvptx64, | |
| 7 | .os_tag = .cuda, | |
| 8 | }); | |
| 9 | ||
| 5 | 10 | { |
| 6 | var case = addPtx(ctx, "simple addition and subtraction"); | |
| 11 | var case = addPtx(ctx, target, "simple addition and subtraction"); | |
| 7 | 12 | |
| 8 | 13 | case.addCompile( |
| 9 | 14 | \\fn add(a: i32, b: i32) i32 { |
| ... | ... | @@ -20,7 +25,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 20 | 25 | } |
| 21 | 26 | |
| 22 | 27 | { |
| 23 | var case = addPtx(ctx, "read special registers"); | |
| 28 | var case = addPtx(ctx, target, "read special registers"); | |
| 24 | 29 | |
| 25 | 30 | case.addCompile( |
| 26 | 31 | \\fn threadIdX() u32 { |
| ... | ... | @@ -37,7 +42,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 37 | 42 | } |
| 38 | 43 | |
| 39 | 44 | { |
| 40 | var case = addPtx(ctx, "address spaces"); | |
| 45 | var case = addPtx(ctx, target, "address spaces"); | |
| 41 | 46 | |
| 42 | 47 | case.addCompile( |
| 43 | 48 | \\var x: i32 addrspace(.global) = 0; |
| ... | ... | @@ -50,7 +55,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 50 | 55 | } |
| 51 | 56 | |
| 52 | 57 | { |
| 53 | var case = addPtx(ctx, "reduce in shared mem"); | |
| 58 | var case = addPtx(ctx, target, "reduce in shared mem"); | |
| 54 | 59 | case.addCompile( |
| 55 | 60 | \\fn threadIdX() u32 { |
| 56 | 61 | \\ return asm ("mov.u32 \t%[r], %tid.x;" |
| ... | ... | @@ -82,18 +87,10 @@ pub fn addCases(ctx: *Cases) !void { |
| 82 | 87 | } |
| 83 | 88 | } |
| 84 | 89 | |
| 85 | const nvptx_target = std.zig.CrossTarget{ | |
| 86 | .cpu_arch = .nvptx64, | |
| 87 | .os_tag = .cuda, | |
| 88 | }; | |
| 89 | ||
| 90 | pub fn addPtx( | |
| 91 | ctx: *Cases, | |
| 92 | name: []const u8, | |
| 93 | ) *Cases.Case { | |
| 90 | fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Cases.Case { | |
| 94 | 91 | ctx.cases.append(.{ |
| 95 | 92 | .name = name, |
| 96 | .target = nvptx_target, | |
| 93 | .target = target, | |
| 97 | 94 | .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator), |
| 98 | 95 | .output_mode = .Obj, |
| 99 | 96 | .deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator), |
test/src/Cases.zig+66-59| ... | ... | @@ -76,7 +76,7 @@ pub const Case = struct { |
| 76 | 76 | name: []const u8, |
| 77 | 77 | /// The platform the test targets. For non-native platforms, an emulator |
| 78 | 78 | /// such as QEMU is required for tests to complete. |
| 79 | target: CrossTarget, | |
| 79 | target: std.Build.ResolvedTarget, | |
| 80 | 80 | /// In order to be able to run e.g. Execution updates, this must be set |
| 81 | 81 | /// to Executable. |
| 82 | 82 | output_mode: std.builtin.OutputMode, |
| ... | ... | @@ -155,7 +155,7 @@ pub const Translate = struct { |
| 155 | 155 | name: []const u8, |
| 156 | 156 | |
| 157 | 157 | input: [:0]const u8, |
| 158 | target: CrossTarget, | |
| 158 | target: std.Build.ResolvedTarget, | |
| 159 | 159 | link_libc: bool, |
| 160 | 160 | c_frontend: CFrontend, |
| 161 | 161 | kind: union(enum) { |
| ... | ... | @@ -171,7 +171,7 @@ pub const Translate = struct { |
| 171 | 171 | pub fn addExe( |
| 172 | 172 | ctx: *Cases, |
| 173 | 173 | name: []const u8, |
| 174 | target: CrossTarget, | |
| 174 | target: std.Build.ResolvedTarget, | |
| 175 | 175 | ) *Case { |
| 176 | 176 | ctx.cases.append(Case{ |
| 177 | 177 | .name = name, |
| ... | ... | @@ -184,16 +184,16 @@ pub fn addExe( |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | /// Adds a test case for Zig input, producing an executable |
| 187 | pub fn exe(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 187 | pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 188 | 188 | return ctx.addExe(name, target); |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 192 | var target_adjusted = target; | |
| 193 | target_adjusted.ofmt = .c; | |
| 191 | pub 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; | |
| 194 | 194 | ctx.cases.append(Case{ |
| 195 | 195 | .name = name, |
| 196 | .target = target_adjusted, | |
| 196 | .target = b.resolveTargetQuery(adjusted_query), | |
| 197 | 197 | .updates = std.ArrayList(Update).init(ctx.cases.allocator), |
| 198 | 198 | .output_mode = .Exe, |
| 199 | 199 | .deps = std.ArrayList(DepModule).init(ctx.arena), |
| ... | ... | @@ -202,7 +202,7 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Cas |
| 202 | 202 | return &ctx.cases.items[ctx.cases.items.len - 1]; |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 205 | pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 206 | 206 | ctx.cases.append(Case{ |
| 207 | 207 | .name = name, |
| 208 | 208 | .target = target, |
| ... | ... | @@ -217,7 +217,7 @@ pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget |
| 217 | 217 | |
| 218 | 218 | /// Adds a test case that uses the LLVM backend to emit an executable. |
| 219 | 219 | /// Currently this implies linking libc, because only then we can generate a testable executable. |
| 220 | pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 220 | pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 221 | 221 | ctx.cases.append(Case{ |
| 222 | 222 | .name = name, |
| 223 | 223 | .target = target, |
| ... | ... | @@ -233,7 +233,7 @@ pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) * |
| 233 | 233 | pub fn addObj( |
| 234 | 234 | ctx: *Cases, |
| 235 | 235 | name: []const u8, |
| 236 | target: CrossTarget, | |
| 236 | target: std.Build.ResolvedTarget, | |
| 237 | 237 | ) *Case { |
| 238 | 238 | ctx.cases.append(Case{ |
| 239 | 239 | .name = name, |
| ... | ... | @@ -248,7 +248,7 @@ pub fn addObj( |
| 248 | 248 | pub fn addTest( |
| 249 | 249 | ctx: *Cases, |
| 250 | 250 | name: []const u8, |
| 251 | target: CrossTarget, | |
| 251 | target: std.Build.ResolvedTarget, | |
| 252 | 252 | ) *Case { |
| 253 | 253 | ctx.cases.append(Case{ |
| 254 | 254 | .name = name, |
| ... | ... | @@ -262,17 +262,17 @@ pub fn addTest( |
| 262 | 262 | } |
| 263 | 263 | |
| 264 | 264 | /// Adds a test case for Zig input, producing an object file. |
| 265 | pub fn obj(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 265 | pub fn obj(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 266 | 266 | return ctx.addObj(name, target); |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | 269 | /// Adds a test case for ZIR input, producing an object file. |
| 270 | pub fn objZIR(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 270 | pub fn objZIR(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 271 | 271 | return ctx.addObj(name, target, .ZIR); |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | 274 | /// Adds a test case for Zig or ZIR input, producing C code. |
| 275 | pub fn addC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { | |
| 275 | pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { | |
| 276 | 276 | var target_adjusted = target; |
| 277 | 277 | target_adjusted.ofmt = std.Target.ObjectFormat.c; |
| 278 | 278 | ctx.cases.append(Case{ |
| ... | ... | @@ -308,7 +308,7 @@ pub fn compareOutput( |
| 308 | 308 | pub fn addTransform( |
| 309 | 309 | ctx: *Cases, |
| 310 | 310 | name: []const u8, |
| 311 | target: CrossTarget, | |
| 311 | target: std.Build.ResolvedTarget, | |
| 312 | 312 | src: [:0]const u8, |
| 313 | 313 | result: [:0]const u8, |
| 314 | 314 | ) void { |
| ... | ... | @@ -320,7 +320,7 @@ pub fn addTransform( |
| 320 | 320 | pub fn transform( |
| 321 | 321 | ctx: *Cases, |
| 322 | 322 | name: []const u8, |
| 323 | target: CrossTarget, | |
| 323 | target: std.Build.ResolvedTarget, | |
| 324 | 324 | src: [:0]const u8, |
| 325 | 325 | result: [:0]const u8, |
| 326 | 326 | ) void { |
| ... | ... | @@ -330,7 +330,7 @@ pub fn transform( |
| 330 | 330 | pub fn addError( |
| 331 | 331 | ctx: *Cases, |
| 332 | 332 | name: []const u8, |
| 333 | target: CrossTarget, | |
| 333 | target: std.Build.ResolvedTarget, | |
| 334 | 334 | src: [:0]const u8, |
| 335 | 335 | expected_errors: []const []const u8, |
| 336 | 336 | ) void { |
| ... | ... | @@ -343,7 +343,7 @@ pub fn addError( |
| 343 | 343 | pub fn compileError( |
| 344 | 344 | ctx: *Cases, |
| 345 | 345 | name: []const u8, |
| 346 | target: CrossTarget, | |
| 346 | target: std.Build.ResolvedTarget, | |
| 347 | 347 | src: [:0]const u8, |
| 348 | 348 | expected_errors: []const []const u8, |
| 349 | 349 | ) void { |
| ... | ... | @@ -355,7 +355,7 @@ pub fn compileError( |
| 355 | 355 | pub fn addCompile( |
| 356 | 356 | ctx: *Cases, |
| 357 | 357 | name: []const u8, |
| 358 | target: CrossTarget, | |
| 358 | target: std.Build.ResolvedTarget, | |
| 359 | 359 | src: [:0]const u8, |
| 360 | 360 | ) void { |
| 361 | 361 | ctx.addObj(name, target).addCompile(src); |
| ... | ... | @@ -368,9 +368,9 @@ pub fn addCompile( |
| 368 | 368 | /// Each file should include a test manifest as a contiguous block of comments at |
| 369 | 369 | /// the end of the file. The first line should be the test type, followed by a set of |
| 370 | 370 | /// key-value config values, followed by a blank line, then the expected output. |
| 371 | pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir) void { | |
| 371 | pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir, b: *std.Build) void { | |
| 372 | 372 | var current_file: []const u8 = "none"; |
| 373 | ctx.addFromDirInner(dir, &current_file) catch |err| { | |
| 373 | ctx.addFromDirInner(dir, &current_file, b) catch |err| { | |
| 374 | 374 | std.debug.panicExtra( |
| 375 | 375 | @errorReturnTrace(), |
| 376 | 376 | @returnAddress(), |
| ... | ... | @@ -386,6 +386,7 @@ fn addFromDirInner( |
| 386 | 386 | /// This is kept up to date with the currently being processed file so |
| 387 | 387 | /// that if any errors occur the caller knows it happened during this file. |
| 388 | 388 | current_file: *[]const u8, |
| 389 | b: *std.Build, | |
| 389 | 390 | ) !void { |
| 390 | 391 | var it = try iterable_dir.walk(ctx.arena); |
| 391 | 392 | var filenames = std.ArrayList([]const u8).init(ctx.arena); |
| ... | ... | @@ -422,7 +423,7 @@ fn addFromDirInner( |
| 422 | 423 | var manifest = try TestManifest.parse(ctx.arena, src); |
| 423 | 424 | |
| 424 | 425 | 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); | |
| 426 | 427 | const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); |
| 427 | 428 | const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 428 | 429 | const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); |
| ... | ... | @@ -430,12 +431,12 @@ fn addFromDirInner( |
| 430 | 431 | |
| 431 | 432 | if (manifest.type == .translate_c) { |
| 432 | 433 | for (c_frontends) |c_frontend| { |
| 433 | for (targets) |target| { | |
| 434 | for (targets) |target_query| { | |
| 434 | 435 | const output = try manifest.trailingLinesSplit(ctx.arena); |
| 435 | 436 | try ctx.translate.append(.{ |
| 436 | 437 | .name = std.fs.path.stem(filename), |
| 437 | 438 | .c_frontend = c_frontend, |
| 438 | .target = target, | |
| 439 | .target = b.resolveTargetQuery(target_query), | |
| 439 | 440 | .link_libc = link_libc, |
| 440 | 441 | .input = src, |
| 441 | 442 | .kind = .{ .translate = output }, |
| ... | ... | @@ -446,12 +447,12 @@ fn addFromDirInner( |
| 446 | 447 | } |
| 447 | 448 | if (manifest.type == .run_translated_c) { |
| 448 | 449 | for (c_frontends) |c_frontend| { |
| 449 | for (targets) |target| { | |
| 450 | for (targets) |target_query| { | |
| 450 | 451 | const output = try manifest.trailingSplit(ctx.arena); |
| 451 | 452 | try ctx.translate.append(.{ |
| 452 | 453 | .name = std.fs.path.stem(filename), |
| 453 | 454 | .c_frontend = c_frontend, |
| 454 | .target = target, | |
| 455 | .target = b.resolveTargetQuery(target_query), | |
| 455 | 456 | .link_libc = link_libc, |
| 456 | 457 | .input = src, |
| 457 | 458 | .kind = .{ .run = output }, |
| ... | ... | @@ -464,16 +465,18 @@ fn addFromDirInner( |
| 464 | 465 | var cases = std.ArrayList(usize).init(ctx.arena); |
| 465 | 466 | |
| 466 | 467 | // 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| { | |
| 469 | 472 | if (backend == .stage2 and |
| 470 | target.getCpuArch() != .wasm32 and target.getCpuArch() != .x86_64) | |
| 473 | target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64) | |
| 471 | 474 | { |
| 472 | 475 | // Other backends don't support new liveness format |
| 473 | 476 | continue; |
| 474 | 477 | } |
| 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) | |
| 477 | 480 | { |
| 478 | 481 | // Rosetta has issues with ZLD |
| 479 | 482 | continue; |
| ... | ... | @@ -482,7 +485,7 @@ fn addFromDirInner( |
| 482 | 485 | const next = ctx.cases.items.len; |
| 483 | 486 | try ctx.cases.append(.{ |
| 484 | 487 | .name = std.fs.path.stem(filename), |
| 485 | .target = target, | |
| 488 | .target = resolved_target, | |
| 486 | 489 | .backend = backend, |
| 487 | 490 | .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator), |
| 488 | 491 | .is_test = is_test, |
| ... | ... | @@ -538,7 +541,7 @@ pub fn lowerToBuildSteps( |
| 538 | 541 | cases_dir_path: []const u8, |
| 539 | 542 | incremental_exe: *std.Build.Step.Compile, |
| 540 | 543 | ) void { |
| 541 | const host = std.zig.system.NativeTargetInfo.detect(.{}) catch |err| | |
| 544 | const host = std.zig.system.resolveTargetQuery(.{}) catch |err| | |
| 542 | 545 | std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)}); |
| 543 | 546 | |
| 544 | 547 | for (self.incremental_cases.items) |incr_case| { |
| ... | ... | @@ -622,8 +625,8 @@ pub fn lowerToBuildSteps( |
| 622 | 625 | } |
| 623 | 626 | |
| 624 | 627 | 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).?, | |
| 627 | 630 | }); |
| 628 | 631 | } |
| 629 | 632 | |
| ... | ... | @@ -644,10 +647,8 @@ pub fn lowerToBuildSteps( |
| 644 | 647 | parent_step.dependOn(&artifact.step); |
| 645 | 648 | }, |
| 646 | 649 | .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) { | |
| 651 | 652 | // We wouldn't be able to run the compiled C code. |
| 652 | 653 | break :no_exec; |
| 653 | 654 | } |
| ... | ... | @@ -666,7 +667,7 @@ pub fn lowerToBuildSteps( |
| 666 | 667 | "--", |
| 667 | 668 | "-lc", |
| 668 | 669 | "-target", |
| 669 | case.target.zigTriple(b.allocator) catch @panic("OOM"), | |
| 670 | case.target.result.zigTriple(b.allocator) catch @panic("OOM"), | |
| 670 | 671 | }); |
| 671 | 672 | run_c.addArtifactArg(artifact); |
| 672 | 673 | break :run_step run_c; |
| ... | ... | @@ -692,9 +693,7 @@ pub fn lowerToBuildSteps( |
| 692 | 693 | continue; // Pass test. |
| 693 | 694 | } |
| 694 | 695 | |
| 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) { | |
| 698 | 697 | // We wouldn't be able to run the compiled C code. |
| 699 | 698 | continue; // Pass test. |
| 700 | 699 | } |
| ... | ... | @@ -1159,9 +1158,9 @@ const TestManifest = struct { |
| 1159 | 1158 | } |
| 1160 | 1159 | |
| 1161 | 1160 | fn getDefaultParser(comptime T: type) ParseFn(T) { |
| 1162 | if (T == CrossTarget) return struct { | |
| 1161 | if (T == std.Target.Query) return struct { | |
| 1163 | 1162 | 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 }); | |
| 1165 | 1164 | } |
| 1166 | 1165 | }.parse; |
| 1167 | 1166 | |
| ... | ... | @@ -1198,7 +1197,8 @@ const builtin = @import("builtin"); |
| 1198 | 1197 | const std = @import("std"); |
| 1199 | 1198 | const assert = std.debug.assert; |
| 1200 | 1199 | const Allocator = std.mem.Allocator; |
| 1201 | const CrossTarget = std.zig.CrossTarget; | |
| 1200 | const getExternalExecutor = std.zig.system.getExternalExecutor; | |
| 1201 | ||
| 1202 | 1202 | const Compilation = @import("../../src/Compilation.zig"); |
| 1203 | 1203 | const zig_h = @import("../../src/link.zig").File.C.zig_h; |
| 1204 | 1204 | const introspect = @import("../../src/introspect.zig"); |
| ... | ... | @@ -1287,7 +1287,7 @@ pub fn main() !void { |
| 1287 | 1287 | |
| 1288 | 1288 | if (cases.items.len == 0) { |
| 1289 | 1289 | 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); | |
| 1291 | 1291 | const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); |
| 1292 | 1292 | const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); |
| 1293 | 1293 | const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); |
| ... | ... | @@ -1295,12 +1295,12 @@ pub fn main() !void { |
| 1295 | 1295 | |
| 1296 | 1296 | if (manifest.type == .translate_c) { |
| 1297 | 1297 | for (c_frontends) |c_frontend| { |
| 1298 | for (targets) |target| { | |
| 1298 | for (targets) |target_query| { | |
| 1299 | 1299 | const output = try manifest.trailingLinesSplit(ctx.arena); |
| 1300 | 1300 | try ctx.translate.append(.{ |
| 1301 | 1301 | .name = std.fs.path.stem(filename), |
| 1302 | 1302 | .c_frontend = c_frontend, |
| 1303 | .target = target, | |
| 1303 | .target = resolveTargetQuery(target_query), | |
| 1304 | 1304 | .is_test = is_test, |
| 1305 | 1305 | .link_libc = link_libc, |
| 1306 | 1306 | .input = src, |
| ... | ... | @@ -1312,12 +1312,12 @@ pub fn main() !void { |
| 1312 | 1312 | } |
| 1313 | 1313 | if (manifest.type == .run_translated_c) { |
| 1314 | 1314 | for (c_frontends) |c_frontend| { |
| 1315 | for (targets) |target| { | |
| 1315 | for (targets) |target_query| { | |
| 1316 | 1316 | const output = try manifest.trailingSplit(ctx.arena); |
| 1317 | 1317 | try ctx.translate.append(.{ |
| 1318 | 1318 | .name = std.fs.path.stem(filename), |
| 1319 | 1319 | .c_frontend = c_frontend, |
| 1320 | .target = target, | |
| 1320 | .target = resolveTargetQuery(target_query), | |
| 1321 | 1321 | .is_test = is_test, |
| 1322 | 1322 | .link_libc = link_libc, |
| 1323 | 1323 | .output = output, |
| ... | ... | @@ -1385,8 +1385,16 @@ pub fn main() !void { |
| 1385 | 1385 | return runCases(&ctx, zig_exe_path); |
| 1386 | 1386 | } |
| 1387 | 1387 | |
| 1388 | fn 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 | ||
| 1388 | 1396 | fn 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(.{}); | |
| 1390 | 1398 | |
| 1391 | 1399 | var progress = std.Progress{}; |
| 1392 | 1400 | const root_node = progress.start("compiler", self.cases.items.len); |
| ... | ... | @@ -1467,7 +1475,7 @@ fn runOneCase( |
| 1467 | 1475 | zig_exe_path: []const u8, |
| 1468 | 1476 | thread_pool: *ThreadPool, |
| 1469 | 1477 | global_cache_directory: Compilation.Directory, |
| 1470 | host: std.zig.system.NativeTargetInfo, | |
| 1478 | host: std.Target, | |
| 1471 | 1479 | ) !void { |
| 1472 | 1480 | const tmp_src_path = "tmp.zig"; |
| 1473 | 1481 | const enable_rosetta = build_options.enable_rosetta; |
| ... | ... | @@ -1477,8 +1485,7 @@ fn runOneCase( |
| 1477 | 1485 | const enable_darling = build_options.enable_darling; |
| 1478 | 1486 | const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir; |
| 1479 | 1487 | |
| 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); | |
| 1482 | 1489 | |
| 1483 | 1490 | var arena_allocator = std.heap.ArenaAllocator.init(allocator); |
| 1484 | 1491 | defer arena_allocator.deinit(); |
| ... | ... | @@ -1568,7 +1575,7 @@ fn runOneCase( |
| 1568 | 1575 | .keep_source_files_loaded = true, |
| 1569 | 1576 | .is_native_os = case.target.isNativeOs(), |
| 1570 | 1577 | .is_native_abi = case.target.isNativeAbi(), |
| 1571 | .dynamic_linker = target_info.dynamic_linker.get(), | |
| 1578 | .dynamic_linker = target.dynamic_linker.get(), | |
| 1572 | 1579 | .link_libc = case.link_libc, |
| 1573 | 1580 | .use_llvm = use_llvm, |
| 1574 | 1581 | .self_exe_path = zig_exe_path, |
| ... | ... | @@ -1704,7 +1711,7 @@ fn runOneCase( |
| 1704 | 1711 | .{ &tmp.sub_path, bin_name }, |
| 1705 | 1712 | ); |
| 1706 | 1713 | 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) { | |
| 1708 | 1715 | // We wouldn't be able to run the compiled C code. |
| 1709 | 1716 | continue :update; // Pass test. |
| 1710 | 1717 | } |
| ... | ... | @@ -1723,7 +1730,7 @@ fn runOneCase( |
| 1723 | 1730 | if (zig_lib_directory.path) |p| { |
| 1724 | 1731 | try argv.appendSlice(&.{ "-I", p }); |
| 1725 | 1732 | } |
| 1726 | } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) { | |
| 1733 | } else switch (getExternalExecutor(host, &target, .{ .link_libc = case.link_libc })) { | |
| 1727 | 1734 | .native => { |
| 1728 | 1735 | if (case.backend == .stage2 and case.target.getCpuArch().isArmOrThumb()) { |
| 1729 | 1736 | // 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 { |
| 96 | 96 | |
| 97 | 97 | const exe = b.addExecutable(.{ |
| 98 | 98 | .name = "test", |
| 99 | .target = .{}, | |
| 99 | .target = b.host, | |
| 100 | 100 | .optimize = .Debug, |
| 101 | 101 | }); |
| 102 | 102 | exe.addAssemblyFile(write_src.files.items[0].getPath()); |
| ... | ... | @@ -121,7 +121,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { |
| 121 | 121 | .name = "test", |
| 122 | 122 | .root_source_file = write_src.files.items[0].getPath(), |
| 123 | 123 | .optimize = optimize, |
| 124 | .target = .{}, | |
| 124 | .target = b.host, | |
| 125 | 125 | }); |
| 126 | 126 | if (case.link_libc) { |
| 127 | 127 | exe.linkSystemLibrary("c"); |
| ... | ... | @@ -146,7 +146,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { |
| 146 | 146 | const exe = b.addExecutable(.{ |
| 147 | 147 | .name = "test", |
| 148 | 148 | .root_source_file = write_src.files.items[0].getPath(), |
| 149 | .target = .{}, | |
| 149 | .target = b.host, | |
| 150 | 150 | .optimize = .Debug, |
| 151 | 151 | }); |
| 152 | 152 | if (case.link_libc) { |
test/src/StackTrace.zig+30-50| ... | ... | @@ -5,44 +5,33 @@ test_filter: ?[]const u8, |
| 5 | 5 | optimize_modes: []const OptimizeMode, |
| 6 | 6 | check_exe: *std.Build.Step.Compile, |
| 7 | 7 | |
| 8 | const Expect = [@typeInfo(OptimizeMode).Enum.fields.len][]const u8; | |
| 8 | const 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, | |
| 9 | 15 | |
| 10 | pub 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 | ||
| 23 | pub 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); | |
| 46 | 35 | } |
| 47 | 36 | |
| 48 | 37 | fn addExpect( |
| ... | ... | @@ -50,19 +39,9 @@ fn addExpect( |
| 50 | 39 | name: []const u8, |
| 51 | 40 | source: []const u8, |
| 52 | 41 | optimize_mode: OptimizeMode, |
| 53 | mode_config: anytype, | |
| 42 | mode_config: Config.PerMode, | |
| 54 | 43 | ) 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; | |
| 66 | 45 | |
| 67 | 46 | const b = self.b; |
| 68 | 47 | const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{ |
| ... | ... | @@ -77,7 +56,8 @@ fn addExpect( |
| 77 | 56 | .name = "test", |
| 78 | 57 | .root_source_file = write_src.files.items[0].getPath(), |
| 79 | 58 | .optimize = optimize_mode, |
| 80 | .target = .{}, | |
| 59 | .target = b.host, | |
| 60 | .error_tracing = mode_config.error_tracing, | |
| 81 | 61 | }); |
| 82 | 62 | |
| 83 | 63 | const run = b.addRunArtifact(exe); |
test/src/run_translated_c.zig+2-2| ... | ... | @@ -11,7 +11,7 @@ pub const RunTranslatedCContext = struct { |
| 11 | 11 | step: *std.Build.Step, |
| 12 | 12 | test_index: usize, |
| 13 | 13 | test_filter: ?[]const u8, |
| 14 | target: std.zig.CrossTarget, | |
| 14 | target: std.Build.ResolvedTarget, | |
| 15 | 15 | |
| 16 | 16 | const TestCase = struct { |
| 17 | 17 | name: []const u8, |
| ... | ... | @@ -86,7 +86,7 @@ pub const RunTranslatedCContext = struct { |
| 86 | 86 | } |
| 87 | 87 | const translate_c = b.addTranslateC(.{ |
| 88 | 88 | .source_file = write_src.files.items[0].getPath(), |
| 89 | .target = .{}, | |
| 89 | .target = b.host, | |
| 90 | 90 | .optimize = .Debug, |
| 91 | 91 | }); |
| 92 | 92 |
test/src/translate_c.zig+3-4| ... | ... | @@ -5,7 +5,6 @@ const ArrayList = std.ArrayList; |
| 5 | 5 | const fmt = std.fmt; |
| 6 | 6 | const mem = std.mem; |
| 7 | 7 | const fs = std.fs; |
| 8 | const CrossTarget = std.zig.CrossTarget; | |
| 9 | 8 | |
| 10 | 9 | pub const TranslateCContext = struct { |
| 11 | 10 | b: *std.Build, |
| ... | ... | @@ -18,7 +17,7 @@ pub const TranslateCContext = struct { |
| 18 | 17 | sources: ArrayList(SourceFile), |
| 19 | 18 | expected_lines: ArrayList([]const u8), |
| 20 | 19 | allow_warnings: bool, |
| 21 | target: CrossTarget = CrossTarget{}, | |
| 20 | target: std.Target.Query = .{}, | |
| 22 | 21 | |
| 23 | 22 | const SourceFile = struct { |
| 24 | 23 | filename: []const u8, |
| ... | ... | @@ -74,7 +73,7 @@ pub const TranslateCContext = struct { |
| 74 | 73 | pub fn addWithTarget( |
| 75 | 74 | self: *TranslateCContext, |
| 76 | 75 | name: []const u8, |
| 77 | target: CrossTarget, | |
| 76 | target: std.Target.Query, | |
| 78 | 77 | source: []const u8, |
| 79 | 78 | expected_lines: []const []const u8, |
| 80 | 79 | ) void { |
| ... | ... | @@ -109,7 +108,7 @@ pub const TranslateCContext = struct { |
| 109 | 108 | |
| 110 | 109 | const translate_c = b.addTranslateC(.{ |
| 111 | 110 | .source_file = write_src.files.items[0].getPath(), |
| 112 | .target = case.target, | |
| 111 | .target = b.resolveTargetQuery(case.target), | |
| 113 | 112 | .optimize = .Debug, |
| 114 | 113 | }); |
| 115 | 114 |
test/stack_traces.zig+30-17| ... | ... | @@ -20,7 +20,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 20 | 20 | , |
| 21 | 21 | }, |
| 22 | 22 | .ReleaseSafe = .{ |
| 23 | .exclude_os = .{ | |
| 23 | .exclude_os = &.{ | |
| 24 | 24 | .windows, // TODO |
| 25 | 25 | .linux, // defeated by aggressive inlining |
| 26 | 26 | }, |
| ... | ... | @@ -31,6 +31,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 31 | 31 | \\ ^ |
| 32 | 32 | \\ |
| 33 | 33 | , |
| 34 | .error_tracing = true, | |
| 34 | 35 | }, |
| 35 | 36 | .ReleaseFast = .{ |
| 36 | 37 | .expect = |
| ... | ... | @@ -70,7 +71,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 70 | 71 | , |
| 71 | 72 | }, |
| 72 | 73 | .ReleaseSafe = .{ |
| 73 | .exclude_os = .{ | |
| 74 | .exclude_os = &.{ | |
| 74 | 75 | .windows, // TODO |
| 75 | 76 | }, |
| 76 | 77 | .expect = |
| ... | ... | @@ -83,6 +84,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 83 | 84 | \\ ^ |
| 84 | 85 | \\ |
| 85 | 86 | , |
| 87 | .error_tracing = true, | |
| 86 | 88 | }, |
| 87 | 89 | .ReleaseFast = .{ |
| 88 | 90 | .expect = |
| ... | ... | @@ -125,7 +127,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 125 | 127 | , |
| 126 | 128 | }, |
| 127 | 129 | .ReleaseSafe = .{ |
| 128 | .exclude_os = .{ | |
| 130 | .exclude_os = &.{ | |
| 129 | 131 | .windows, // TODO |
| 130 | 132 | .linux, // defeated by aggressive inlining |
| 131 | 133 | }, |
| ... | ... | @@ -136,6 +138,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 136 | 138 | \\ ^ |
| 137 | 139 | \\ |
| 138 | 140 | , |
| 141 | .error_tracing = true, | |
| 139 | 142 | }, |
| 140 | 143 | .ReleaseFast = .{ |
| 141 | 144 | .expect = |
| ... | ... | @@ -176,7 +179,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 176 | 179 | , |
| 177 | 180 | }, |
| 178 | 181 | .ReleaseSafe = .{ |
| 179 | .exclude_os = .{ | |
| 182 | .exclude_os = &.{ | |
| 180 | 183 | .windows, // TODO |
| 181 | 184 | .linux, // defeated by aggressive inlining |
| 182 | 185 | }, |
| ... | ... | @@ -187,6 +190,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 187 | 190 | \\ ^ |
| 188 | 191 | \\ |
| 189 | 192 | , |
| 193 | .error_tracing = true, | |
| 190 | 194 | }, |
| 191 | 195 | .ReleaseFast = .{ |
| 192 | 196 | .expect = |
| ... | ... | @@ -230,7 +234,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 230 | 234 | , |
| 231 | 235 | }, |
| 232 | 236 | .ReleaseSafe = .{ |
| 233 | .exclude_os = .{ | |
| 237 | .exclude_os = &.{ | |
| 234 | 238 | .windows, // TODO |
| 235 | 239 | .linux, // defeated by aggressive inlining |
| 236 | 240 | }, |
| ... | ... | @@ -244,6 +248,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 244 | 248 | \\ ^ |
| 245 | 249 | \\ |
| 246 | 250 | , |
| 251 | .error_tracing = true, | |
| 247 | 252 | }, |
| 248 | 253 | .ReleaseFast = .{ |
| 249 | 254 | .expect = |
| ... | ... | @@ -286,7 +291,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 286 | 291 | , |
| 287 | 292 | }, |
| 288 | 293 | .ReleaseSafe = .{ |
| 289 | .exclude_os = .{ | |
| 294 | .exclude_os = &.{ | |
| 290 | 295 | .windows, // TODO |
| 291 | 296 | .linux, // defeated by aggressive inlining |
| 292 | 297 | }, |
| ... | ... | @@ -297,6 +302,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 297 | 302 | \\ ^ |
| 298 | 303 | \\ |
| 299 | 304 | , |
| 305 | .error_tracing = true, | |
| 300 | 306 | }, |
| 301 | 307 | .ReleaseFast = .{ |
| 302 | 308 | .expect = |
| ... | ... | @@ -336,7 +342,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 336 | 342 | , |
| 337 | 343 | }, |
| 338 | 344 | .ReleaseSafe = .{ |
| 339 | .exclude_os = .{ | |
| 345 | .exclude_os = &.{ | |
| 340 | 346 | .windows, // TODO |
| 341 | 347 | .linux, // defeated by aggressive inlining |
| 342 | 348 | }, |
| ... | ... | @@ -350,6 +356,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 350 | 356 | \\ ^ |
| 351 | 357 | \\ |
| 352 | 358 | , |
| 359 | .error_tracing = true, | |
| 353 | 360 | }, |
| 354 | 361 | .ReleaseFast = .{ |
| 355 | 362 | .expect = |
| ... | ... | @@ -391,7 +398,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 391 | 398 | , |
| 392 | 399 | }, |
| 393 | 400 | .ReleaseSafe = .{ |
| 394 | .exclude_os = .{ | |
| 401 | .exclude_os = &.{ | |
| 395 | 402 | .windows, // TODO |
| 396 | 403 | .linux, // defeated by aggressive inlining |
| 397 | 404 | }, |
| ... | ... | @@ -402,6 +409,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 402 | 409 | \\ ^ |
| 403 | 410 | \\ |
| 404 | 411 | , |
| 412 | .error_tracing = true, | |
| 405 | 413 | }, |
| 406 | 414 | .ReleaseFast = .{ |
| 407 | 415 | .expect = |
| ... | ... | @@ -461,7 +469,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 461 | 469 | , |
| 462 | 470 | }, |
| 463 | 471 | .ReleaseSafe = .{ |
| 464 | .exclude_os = .{ | |
| 472 | .exclude_os = &.{ | |
| 465 | 473 | .windows, // TODO |
| 466 | 474 | .linux, // defeated by aggressive inlining |
| 467 | 475 | }, |
| ... | ... | @@ -478,6 +486,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 478 | 486 | \\ ^ |
| 479 | 487 | \\ |
| 480 | 488 | , |
| 489 | .error_tracing = true, | |
| 481 | 490 | }, |
| 482 | 491 | .ReleaseFast = .{ |
| 483 | 492 | .expect = |
| ... | ... | @@ -531,7 +540,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 531 | 540 | , |
| 532 | 541 | }, |
| 533 | 542 | .ReleaseSafe = .{ |
| 534 | .exclude_os = .{ | |
| 543 | .exclude_os = &.{ | |
| 535 | 544 | .windows, // TODO |
| 536 | 545 | }, |
| 537 | 546 | .expect = |
| ... | ... | @@ -547,6 +556,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 547 | 556 | \\ ^ |
| 548 | 557 | \\ |
| 549 | 558 | , |
| 559 | .error_tracing = true, | |
| 550 | 560 | }, |
| 551 | 561 | .ReleaseFast = .{ |
| 552 | 562 | .expect = |
| ... | ... | @@ -595,7 +605,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 595 | 605 | , |
| 596 | 606 | }, |
| 597 | 607 | .ReleaseSafe = .{ |
| 598 | .exclude_os = .{ | |
| 608 | .exclude_os = &.{ | |
| 599 | 609 | .windows, // TODO |
| 600 | 610 | }, |
| 601 | 611 | .expect = |
| ... | ... | @@ -611,6 +621,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 611 | 621 | \\ ^ |
| 612 | 622 | \\ |
| 613 | 623 | , |
| 624 | .error_tracing = true, | |
| 614 | 625 | }, |
| 615 | 626 | .ReleaseFast = .{ |
| 616 | 627 | .expect = |
| ... | ... | @@ -659,7 +670,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 659 | 670 | , |
| 660 | 671 | }, |
| 661 | 672 | .ReleaseSafe = .{ |
| 662 | .exclude_os = .{ | |
| 673 | .exclude_os = &.{ | |
| 663 | 674 | .windows, // TODO |
| 664 | 675 | }, |
| 665 | 676 | .expect = |
| ... | ... | @@ -675,6 +686,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 675 | 686 | \\ ^ |
| 676 | 687 | \\ |
| 677 | 688 | , |
| 689 | .error_tracing = true, | |
| 678 | 690 | }, |
| 679 | 691 | .ReleaseFast = .{ |
| 680 | 692 | .expect = |
| ... | ... | @@ -728,7 +740,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 728 | 740 | , |
| 729 | 741 | }, |
| 730 | 742 | .ReleaseSafe = .{ |
| 731 | .exclude_os = .{ | |
| 743 | .exclude_os = &.{ | |
| 732 | 744 | .windows, // TODO |
| 733 | 745 | }, |
| 734 | 746 | .expect = |
| ... | ... | @@ -747,6 +759,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 747 | 759 | \\ ^ |
| 748 | 760 | \\ |
| 749 | 761 | , |
| 762 | .error_tracing = true, | |
| 750 | 763 | }, |
| 751 | 764 | .ReleaseFast = .{ |
| 752 | 765 | .expect = |
| ... | ... | @@ -763,10 +776,6 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 763 | 776 | }); |
| 764 | 777 | |
| 765 | 778 | cases.addCase(.{ |
| 766 | .exclude_os = .{ | |
| 767 | .openbsd, // integer overflow | |
| 768 | .windows, // TODO intermittent failures | |
| 769 | }, | |
| 770 | 779 | .name = "dumpCurrentStackTrace", |
| 771 | 780 | .source = |
| 772 | 781 | \\const std = @import("std"); |
| ... | ... | @@ -783,6 +792,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 783 | 792 | \\} |
| 784 | 793 | , |
| 785 | 794 | .Debug = .{ |
| 795 | .exclude_os = &.{ | |
| 796 | .openbsd, // integer overflow | |
| 797 | .windows, // TODO intermittent failures | |
| 798 | }, | |
| 786 | 799 | .expect = |
| 787 | 800 | \\source.zig:7:8: [address] in foo (test) |
| 788 | 801 | \\ bar(); |
test/standalone.zig+5-5| ... | ... | @@ -2,7 +2,7 @@ pub const SimpleCase = struct { |
| 2 | 2 | src_path: []const u8, |
| 3 | 3 | link_libc: bool = false, |
| 4 | 4 | all_modes: bool = false, |
| 5 | target: std.zig.CrossTarget = .{}, | |
| 5 | target: std.Target.Query = .{}, | |
| 6 | 6 | is_test: bool = false, |
| 7 | 7 | is_exe: bool = true, |
| 8 | 8 | /// Run only on this OS. |
| ... | ... | @@ -89,10 +89,6 @@ pub const build_cases = [_]BuildCase{ |
| 89 | 89 | // .build_root = "test/standalone/issue_13970", |
| 90 | 90 | // .import = @import("standalone/issue_13970/build.zig"), |
| 91 | 91 | //}, |
| 92 | .{ | |
| 93 | .build_root = "test/standalone/main_pkg_path", | |
| 94 | .import = @import("standalone/main_pkg_path/build.zig"), | |
| 95 | }, | |
| 96 | 92 | .{ |
| 97 | 93 | .build_root = "test/standalone/shared_library", |
| 98 | 94 | .import = @import("standalone/shared_library/build.zig"), |
| ... | ... | @@ -262,6 +258,10 @@ pub const build_cases = [_]BuildCase{ |
| 262 | 258 | .build_root = "test/standalone/ios", |
| 263 | 259 | .import = @import("standalone/ios/build.zig"), |
| 264 | 260 | }, |
| 261 | .{ | |
| 262 | .build_root = "test/standalone/depend_on_main_mod", | |
| 263 | .import = @import("standalone/depend_on_main_mod/build.zig"), | |
| 264 | }, | |
| 265 | 265 | }; |
| 266 | 266 | |
| 267 | 267 | const std = @import("std"); |
test/standalone/c_compiler/build.zig+2-2| ... | ... | @@ -23,7 +23,7 @@ fn add( |
| 23 | 23 | cpp_name: []const u8, |
| 24 | 24 | optimize: std.builtin.OptimizeMode, |
| 25 | 25 | ) void { |
| 26 | const target: std.zig.CrossTarget = .{}; | |
| 26 | const target = b.host; | |
| 27 | 27 | |
| 28 | 28 | const exe_c = b.addExecutable(.{ |
| 29 | 29 | .name = c_name, |
| ... | ... | @@ -42,7 +42,7 @@ fn add( |
| 42 | 42 | exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} }); |
| 43 | 43 | exe_cpp.linkLibCpp(); |
| 44 | 44 | |
| 45 | switch (target.getOsTag()) { | |
| 45 | switch (target.result.os.tag) { | |
| 46 | 46 | .windows => { |
| 47 | 47 | // https://github.com/ziglang/zig/issues/8531 |
| 48 | 48 | exe_cpp.want_lto = false; |
test/standalone/child_process/build.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | b.default_step = test_step; |
| 7 | 7 | |
| 8 | 8 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 9 | const target: std.zig.CrossTarget = .{}; | |
| 9 | const target = b.host; | |
| 10 | 10 | |
| 11 | 11 | if (builtin.os.tag == .wasi) return; |
| 12 | 12 |
test/standalone/coff_dwarf/build.zig+5| ... | ... | @@ -11,6 +11,11 @@ pub fn build(b: *std.Build) void { |
| 11 | 11 | |
| 12 | 12 | if (builtin.os.tag != .windows) return; |
| 13 | 13 | |
| 14 | if (builtin.cpu.arch == .aarch64) { | |
| 15 | // https://github.com/ziglang/zig/issues/18427 | |
| 16 | return; | |
| 17 | } | |
| 18 | ||
| 14 | 19 | const exe = b.addExecutable(.{ |
| 15 | 20 | .name = "main", |
| 16 | 21 | .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 { |
| 7 | 7 | const target = b.standardTargetOptions(.{}); |
| 8 | 8 | const optimize = b.standardOptimizeOption(.{}); |
| 9 | 9 | |
| 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; | |
| 12 | 12 | |
| 13 | 13 | const exe = b.addExecutable(.{ |
| 14 | 14 | .name = "main", |
test/standalone/dep_diamond/build.zig+8-7| ... | ... | @@ -7,21 +7,22 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | 8 | |
| 9 | 9 | const shared = b.createModule(.{ |
| 10 | .source_file = .{ .path = "shared.zig" }, | |
| 10 | .root_source_file = .{ .path = "shared.zig" }, | |
| 11 | 11 | }); |
| 12 | 12 | |
| 13 | 13 | const exe = b.addExecutable(.{ |
| 14 | 14 | .name = "test", |
| 15 | 15 | .root_source_file = .{ .path = "test.zig" }, |
| 16 | .target = b.host, | |
| 16 | 17 | .optimize = optimize, |
| 17 | 18 | }); |
| 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 }}, | |
| 21 | 22 | }); |
| 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 }}, | |
| 25 | 26 | }); |
| 26 | 27 | |
| 27 | 28 | 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 { |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | 8 | |
| 9 | 9 | const foo = b.createModule(.{ |
| 10 | .source_file = .{ .path = "foo.zig" }, | |
| 10 | .root_source_file = .{ .path = "foo.zig" }, | |
| 11 | 11 | }); |
| 12 | 12 | const bar = b.createModule(.{ |
| 13 | .source_file = .{ .path = "bar.zig" }, | |
| 13 | .root_source_file = .{ .path = "bar.zig" }, | |
| 14 | 14 | }); |
| 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); | |
| 17 | 17 | |
| 18 | 18 | const exe = b.addExecutable(.{ |
| 19 | 19 | .name = "test", |
| 20 | 20 | .root_source_file = .{ .path = "test.zig" }, |
| 21 | .target = b.host, | |
| 21 | 22 | .optimize = optimize, |
| 22 | 23 | }); |
| 23 | exe.addModule("foo", foo); | |
| 24 | exe.root_module.addImport("foo", foo); | |
| 24 | 25 | |
| 25 | 26 | const run = b.addRunArtifact(exe); |
| 26 | 27 | test_step.dependOn(&run.step); |
test/standalone/dep_recursive/build.zig+4-3| ... | ... | @@ -7,16 +7,17 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | 8 | |
| 9 | 9 | const foo = b.createModule(.{ |
| 10 | .source_file = .{ .path = "foo.zig" }, | |
| 10 | .root_source_file = .{ .path = "foo.zig" }, | |
| 11 | 11 | }); |
| 12 | foo.dependencies.put("foo", foo) catch @panic("OOM"); | |
| 12 | foo.addImport("foo", foo); | |
| 13 | 13 | |
| 14 | 14 | const exe = b.addExecutable(.{ |
| 15 | 15 | .name = "test", |
| 16 | 16 | .root_source_file = .{ .path = "test.zig" }, |
| 17 | .target = b.host, | |
| 17 | 18 | .optimize = optimize, |
| 18 | 19 | }); |
| 19 | exe.addModule("foo", foo); | |
| 20 | exe.root_module.addImport("foo", foo); | |
| 20 | 21 | |
| 21 | 22 | const run = b.addRunArtifact(exe); |
| 22 | 23 | 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 { |
| 9 | 9 | const exe = b.addExecutable(.{ |
| 10 | 10 | .name = "test", |
| 11 | 11 | .root_source_file = .{ .path = "test.zig" }, |
| 12 | .target = b.host, | |
| 12 | 13 | .optimize = optimize, |
| 13 | 14 | }); |
| 14 | exe.addAnonymousModule("foo", .{ | |
| 15 | .source_file = .{ .path = "foo.zig" }, | |
| 15 | exe.root_module.addAnonymousImport("foo", .{ | |
| 16 | .root_source_file = .{ .path = "foo.zig" }, | |
| 16 | 17 | }); |
| 17 | 18 | |
| 18 | 19 | const run = b.addRunArtifact(exe); |
test/standalone/dep_triangle/build.zig+6-5| ... | ... | @@ -7,19 +7,20 @@ pub fn build(b: *std.Build) void { |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | 8 | |
| 9 | 9 | const shared = b.createModule(.{ |
| 10 | .source_file = .{ .path = "shared.zig" }, | |
| 10 | .root_source_file = .{ .path = "shared.zig" }, | |
| 11 | 11 | }); |
| 12 | 12 | |
| 13 | 13 | const exe = b.addExecutable(.{ |
| 14 | 14 | .name = "test", |
| 15 | 15 | .root_source_file = .{ .path = "test.zig" }, |
| 16 | .target = b.host, | |
| 16 | 17 | .optimize = optimize, |
| 17 | 18 | }); |
| 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 }}, | |
| 21 | 22 | }); |
| 22 | exe.addModule("shared", shared); | |
| 23 | exe.root_module.addImport("shared", shared); | |
| 23 | 24 | |
| 24 | 25 | const run = b.addRunArtifact(exe); |
| 25 | 26 | test_step.dependOn(&run.step); |
test/standalone/depend_on_main_mod/build.zig created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub 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 @@ |
| 1 | const std = @import("std"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | ||
| 4 | pub 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 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub 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 { |
| 7 | 7 | const bootloader = b.addExecutable(.{ |
| 8 | 8 | .name = "bootloader", |
| 9 | 9 | .root_source_file = .{ .path = "bootloader.zig" }, |
| 10 | .target = .{ | |
| 10 | .target = b.resolveTargetQuery(.{ | |
| 11 | 11 | .cpu_arch = .x86, |
| 12 | 12 | .os_tag = .freestanding, |
| 13 | }, | |
| 13 | }), | |
| 14 | 14 | .optimize = .ReleaseSmall, |
| 15 | 15 | }); |
| 16 | 16 | |
| ... | ... | @@ -18,8 +18,8 @@ pub fn build(b: *std.Build) void { |
| 18 | 18 | .root_source_file = .{ .path = "main.zig" }, |
| 19 | 19 | .optimize = .Debug, |
| 20 | 20 | }); |
| 21 | exe.addAnonymousModule("bootloader.elf", .{ | |
| 22 | .source_file = bootloader.getEmittedBin(), | |
| 21 | exe.root_module.addAnonymousImport("bootloader.elf", .{ | |
| 22 | .root_source_file = bootloader.getEmittedBin(), | |
| 23 | 23 | }); |
| 24 | 24 | |
| 25 | 25 | // TODO: actually check the output |
test/standalone/empty_env/build.zig+1| ... | ... | @@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void { |
| 15 | 15 | const main = b.addExecutable(.{ |
| 16 | 16 | .name = "main", |
| 17 | 17 | .root_source_file = .{ .path = "main.zig" }, |
| 18 | .target = b.host, | |
| 18 | 19 | .optimize = optimize, |
| 19 | 20 | }); |
| 20 | 21 |
test/standalone/extern/build.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | const obj = b.addObject(.{ |
| 7 | 7 | .name = "exports", |
| 8 | 8 | .root_source_file = .{ .path = "exports.zig" }, |
| 9 | .target = .{}, | |
| 9 | .target = b.host, | |
| 10 | 10 | .optimize = optimize, |
| 11 | 11 | }); |
| 12 | 12 | const main = b.addTest(.{ |
test/standalone/global_linkage/build.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target: std.zig.CrossTarget = .{}; | |
| 8 | const target = b.host; | |
| 9 | 9 | |
| 10 | 10 | const obj1 = b.addStaticLibrary(.{ |
| 11 | 11 | .name = "obj1", |
test/standalone/install_raw_hex/build.zig+2-2| ... | ... | @@ -5,12 +5,12 @@ pub fn build(b: *std.Build) void { |
| 5 | 5 | const test_step = b.step("test", "Test it"); |
| 6 | 6 | b.default_step = test_step; |
| 7 | 7 | |
| 8 | const target = .{ | |
| 8 | const target = b.resolveTargetQuery(.{ | |
| 9 | 9 | .cpu_arch = .thumb, |
| 10 | 10 | .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 }, |
| 11 | 11 | .os_tag = .freestanding, |
| 12 | 12 | .abi = .gnueabihf, |
| 13 | }; | |
| 13 | }); | |
| 14 | 14 | |
| 15 | 15 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 16 | 16 |
test/standalone/ios/build.zig+4-4| ... | ... | @@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void { |
| 8 | 8 | b.default_step = test_step; |
| 9 | 9 | |
| 10 | 10 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 11 | const target: std.zig.CrossTarget = .{ | |
| 11 | const target = b.resolveTargetQuery(.{ | |
| 12 | 12 | .cpu_arch = .aarch64, |
| 13 | 13 | .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"); | |
| 17 | 17 | b.sysroot = sdk; |
| 18 | 18 | |
| 19 | 19 | const exe = b.addExecutable(.{ |
test/standalone/issue_11595/build.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | b.default_step = test_step; |
| 7 | 7 | |
| 8 | 8 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 9 | const target: std.zig.CrossTarget = .{}; | |
| 9 | const target = b.host; | |
| 10 | 10 | |
| 11 | 11 | if (builtin.os.tag == .windows) { |
| 12 | 12 | // 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 { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target: std.zig.CrossTarget = .{}; | |
| 9 | 8 | |
| 10 | 9 | const obj = b.addObject(.{ |
| 11 | 10 | .name = "main", |
| 12 | 11 | .root_source_file = .{ .path = "main.zig" }, |
| 13 | 12 | .optimize = optimize, |
| 14 | .target = target, | |
| 13 | .target = b.host, | |
| 15 | 14 | }); |
| 16 | 15 | _ = obj.getEmittedLlvmIr(); |
| 17 | 16 | _ = obj.getEmittedLlvmBc(); |
test/standalone/issue_12706/build.zig+1-2| ... | ... | @@ -1,13 +1,12 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const CrossTarget = std.zig.CrossTarget; | |
| 4 | 3 | |
| 5 | 4 | pub fn build(b: *std.Build) void { |
| 6 | 5 | const test_step = b.step("test", "Test it"); |
| 7 | 6 | b.default_step = test_step; |
| 8 | 7 | |
| 9 | 8 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 10 | const target: std.zig.CrossTarget = .{}; | |
| 9 | const target = b.host; | |
| 11 | 10 | |
| 12 | 11 | const exe = b.addExecutable(.{ |
| 13 | 12 | .name = "main", |
test/standalone/issue_339/build.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target: std.zig.CrossTarget = .{}; | |
| 8 | const target = b.host; | |
| 9 | 9 | |
| 10 | 10 | const obj = b.addObject(.{ |
| 11 | 11 | .name = "test", |
test/standalone/issue_5825/build.zig+2-2| ... | ... | @@ -8,11 +8,11 @@ pub fn build(b: *std.Build) void { |
| 8 | 8 | // Building for the msvc abi requires a native MSVC installation |
| 9 | 9 | if (builtin.os.tag != .windows or builtin.cpu.arch != .x86_64) return; |
| 10 | 10 | |
| 11 | const target = .{ | |
| 11 | const target = b.resolveTargetQuery(.{ | |
| 12 | 12 | .cpu_arch = .x86_64, |
| 13 | 13 | .os_tag = .windows, |
| 14 | 14 | .abi = .msvc, |
| 15 | }; | |
| 15 | }); | |
| 16 | 16 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 17 | 17 | const obj = b.addObject(.{ |
| 18 | 18 | .name = "issue_5825", |
test/standalone/issue_8550/build.zig+2-2| ... | ... | @@ -5,13 +5,13 @@ pub fn build(b: *std.Build) !void { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target = std.zig.CrossTarget{ | |
| 8 | const target = b.resolveTargetQuery(.{ | |
| 9 | 9 | .os_tag = .freestanding, |
| 10 | 10 | .cpu_arch = .arm, |
| 11 | 11 | .cpu_model = .{ |
| 12 | 12 | .explicit = &std.Target.arm.cpu.arm1176jz_s, |
| 13 | 13 | }, |
| 14 | }; | |
| 14 | }); | |
| 15 | 15 | |
| 16 | 16 | const kernel = b.addExecutable(.{ |
| 17 | 17 | .name = "kernel", |
test/standalone/load_dynamic_library/build.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | b.default_step = test_step; |
| 7 | 7 | |
| 8 | 8 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 9 | const target: std.zig.CrossTarget = .{}; | |
| 9 | const target = b.host; | |
| 10 | 10 | |
| 11 | 11 | if (builtin.os.tag == .wasi) return; |
| 12 | 12 |
test/standalone/main_pkg_path/a/test.zig deleted-5| ... | ... | @@ -1,5 +0,0 @@ |
| 1 | const b = @import("../b.zig"); | |
| 2 | ||
| 3 | test "main pkg path" { | |
| 4 | b.foo(); | |
| 5 | } |
test/standalone/main_pkg_path/b.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub fn foo() void {} |
test/standalone/main_pkg_path/build.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub 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 |
| 19 | 19 | const exe = b.addExecutable(.{ |
| 20 | 20 | .name = "test", |
| 21 | 21 | .root_source_file = .{ .path = "main.zig" }, |
| 22 | .target = b.host, | |
| 22 | 23 | .optimize = optimize, |
| 23 | 24 | }); |
| 24 | 25 | 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 { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target: std.zig.CrossTarget = .{}; | |
| 8 | const target = b.host; | |
| 9 | 9 | |
| 10 | 10 | const obj = b.addObject(.{ |
| 11 | 11 | .name = "base64", |
test/standalone/options/build.zig+1-1| ... | ... | @@ -3,7 +3,7 @@ const std = @import("std"); |
| 3 | 3 | pub fn build(b: *std.Build) void { |
| 4 | 4 | const main = b.addTest(.{ |
| 5 | 5 | .root_source_file = .{ .path = "src/main.zig" }, |
| 6 | .target = .{}, | |
| 6 | .target = b.host, | |
| 7 | 7 | .optimize = .Debug, |
| 8 | 8 | }); |
| 9 | 9 |
test/standalone/pie/build.zig+2-2| ... | ... | @@ -5,10 +5,10 @@ pub fn build(b: *std.Build) void { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 8 | const target: std.zig.CrossTarget = .{ | |
| 8 | const target = b.resolveTargetQuery(.{ | |
| 9 | 9 | .os_tag = .linux, |
| 10 | 10 | .cpu_arch = .x86_64, |
| 11 | }; | |
| 11 | }); | |
| 12 | 12 | |
| 13 | 13 | const main = b.addTest(.{ |
| 14 | 14 | .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 { |
| 10 | 10 | .name = "test", |
| 11 | 11 | .root_source_file = .{ .path = "test.zig" }, |
| 12 | 12 | .optimize = optimize, |
| 13 | .target = b.host, | |
| 13 | 14 | }); |
| 14 | exe.addAnonymousModule("my_pkg", .{ .source_file = .{ .path = "pkg.zig" } }); | |
| 15 | exe.root_module.addAnonymousImport("my_pkg", .{ .root_source_file = .{ .path = "pkg.zig" } }); | |
| 15 | 16 | |
| 16 | 17 | const run = b.addRunArtifact(exe); |
| 17 | 18 | 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 { |
| 7 | 7 | b.default_step = test_step; |
| 8 | 8 | |
| 9 | 9 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 10 | const target: std.zig.CrossTarget = .{}; | |
| 10 | const target = b.host; | |
| 11 | 11 | |
| 12 | 12 | // The test requires getFdPath in order to to get the path of the |
| 13 | 13 | // File returned by openSelfExe |
| 14 | if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return; | |
| 14 | if (!std.os.isGetFdPathSupportedOnTarget(target.result.os)) return; | |
| 15 | 15 | |
| 16 | 16 | const main = b.addExecutable(.{ |
| 17 | 17 | .name = "main", |
test/standalone/shared_library/build.zig+1-1| ... | ... | @@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void { |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | 12 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 13 | const target: std.zig.CrossTarget = .{}; | |
| 13 | const target = b.host; | |
| 14 | 14 | const lib = b.addSharedLibrary(.{ |
| 15 | 15 | .name = "mathtest", |
| 16 | 16 | .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 { |
| 22 | 22 | .root_source_file = .{ .path = "unwind.zig" }, |
| 23 | 23 | .target = target, |
| 24 | 24 | .optimize = optimize, |
| 25 | .unwind_tables = if (target.result.isDarwin()) true else null, | |
| 26 | .omit_frame_pointer = false, | |
| 25 | 27 | }); |
| 26 | 28 | |
| 27 | if (target.isDarwin()) exe.unwind_tables = true; | |
| 28 | exe.omit_frame_pointer = false; | |
| 29 | ||
| 30 | 29 | const run_cmd = b.addRunArtifact(exe); |
| 31 | 30 | test_step.dependOn(&run_cmd.step); |
| 32 | 31 | } |
| ... | ... | @@ -46,11 +45,10 @@ pub fn build(b: *std.Build) void { |
| 46 | 45 | .root_source_file = .{ .path = "unwind.zig" }, |
| 47 | 46 | .target = target, |
| 48 | 47 | .optimize = optimize, |
| 48 | .unwind_tables = true, | |
| 49 | .omit_frame_pointer = true, | |
| 49 | 50 | }); |
| 50 | 51 | |
| 51 | exe.omit_frame_pointer = true; | |
| 52 | exe.unwind_tables = true; | |
| 53 | ||
| 54 | 52 | const run_cmd = b.addRunArtifact(exe); |
| 55 | 53 | test_step.dependOn(&run_cmd.step); |
| 56 | 54 | } |
| ... | ... | @@ -69,11 +67,12 @@ pub fn build(b: *std.Build) void { |
| 69 | 67 | .name = "c_shared_lib", |
| 70 | 68 | .target = target, |
| 71 | 69 | .optimize = optimize, |
| 70 | .strip = false, | |
| 72 | 71 | }); |
| 73 | 72 | |
| 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)"); | |
| 75 | 75 | |
| 76 | c_shared_lib.strip = false; | |
| 77 | 76 | c_shared_lib.addCSourceFile(.{ |
| 78 | 77 | .file = .{ .path = "shared_lib.c" }, |
| 79 | 78 | .flags = &.{"-fomit-frame-pointer"}, |
| ... | ... | @@ -85,10 +84,10 @@ pub fn build(b: *std.Build) void { |
| 85 | 84 | .root_source_file = .{ .path = "shared_lib_unwind.zig" }, |
| 86 | 85 | .target = target, |
| 87 | 86 | .optimize = optimize, |
| 87 | .unwind_tables = if (target.result.isDarwin()) true else null, | |
| 88 | .omit_frame_pointer = true, | |
| 88 | 89 | }); |
| 89 | 90 | |
| 90 | if (target.isDarwin()) exe.unwind_tables = true; | |
| 91 | exe.omit_frame_pointer = true; | |
| 92 | 91 | exe.linkLibrary(c_shared_lib); |
| 93 | 92 | |
| 94 | 93 | 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 { |
| 9 | 9 | const foo = b.addStaticLibrary(.{ |
| 10 | 10 | .name = "foo", |
| 11 | 11 | .optimize = optimize, |
| 12 | .target = .{}, | |
| 12 | .target = b.host, | |
| 13 | 13 | }); |
| 14 | 14 | foo.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &[_][]const u8{} }); |
| 15 | 15 | foo.addIncludePath(.{ .path = "." }); |
test/standalone/strip_empty_loop/build.zig+2-2| ... | ... | @@ -5,15 +5,15 @@ pub fn build(b: *std.Build) void { |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | 7 | const optimize = std.builtin.OptimizeMode.Debug; |
| 8 | const target = std.zig.CrossTarget{}; | |
| 8 | const target = b.host; | |
| 9 | 9 | |
| 10 | 10 | const main = b.addExecutable(.{ |
| 11 | 11 | .name = "main", |
| 12 | 12 | .root_source_file = .{ .path = "main.zig" }, |
| 13 | 13 | .optimize = optimize, |
| 14 | 14 | .target = target, |
| 15 | .strip = true, | |
| 15 | 16 | }); |
| 16 | main.strip = true; | |
| 17 | 17 | |
| 18 | 18 | // TODO: actually check the output |
| 19 | 19 | _ = main.getEmittedBin(); |
test/standalone/strip_struct_init/build.zig+1-1| ... | ... | @@ -9,8 +9,8 @@ pub fn build(b: *std.Build) void { |
| 9 | 9 | const main = b.addTest(.{ |
| 10 | 10 | .root_source_file = .{ .path = "main.zig" }, |
| 11 | 11 | .optimize = optimize, |
| 12 | .strip = true, | |
| 12 | 13 | }); |
| 13 | main.strip = true; | |
| 14 | 14 | |
| 15 | 15 | test_step.dependOn(&b.addRunArtifact(main).step); |
| 16 | 16 | } |
test/standalone/test_runner_module_imports/build.zig+4-4| ... | ... | @@ -6,13 +6,13 @@ pub fn build(b: *std.Build) void { |
| 6 | 6 | .test_runner = "test_runner/main.zig", |
| 7 | 7 | }); |
| 8 | 8 | |
| 9 | const module1 = b.createModule(.{ .source_file = .{ .path = "module1/main.zig" } }); | |
| 9 | const module1 = b.createModule(.{ .root_source_file = .{ .path = "module1/main.zig" } }); | |
| 10 | 10 | 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 }}, | |
| 13 | 13 | }); |
| 14 | 14 | |
| 15 | t.addModule("module2", module2); | |
| 15 | t.root_module.addImport("module2", module2); | |
| 16 | 16 | |
| 17 | 17 | const test_step = b.step("test", "Run unit tests"); |
| 18 | 18 | 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 { |
| 4 | 4 | const test_step = b.step("test", "Test it"); |
| 5 | 5 | b.default_step = test_step; |
| 6 | 6 | |
| 7 | const native_target: std.zig.CrossTarget = .{}; | |
| 8 | const cross_target = .{ | |
| 7 | const target = b.resolveTargetQuery(.{ | |
| 9 | 8 | .cpu_arch = .x86_64, |
| 10 | 9 | .os_tag = .windows, |
| 11 | 10 | .abi = .gnu, |
| 12 | }; | |
| 11 | }); | |
| 13 | 12 | |
| 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); | |
| 16 | 15 | |
| 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); | |
| 19 | 18 | } |
| 20 | 19 | |
| 21 | fn add(b: *std.Build, target: std.zig.CrossTarget, rc_includes: enum { any, gnu }, test_step: *std.Build.Step) void { | |
| 20 | fn add( | |
| 21 | b: *std.Build, | |
| 22 | target: std.Build.ResolvedTarget, | |
| 23 | rc_includes: enum { any, gnu }, | |
| 24 | test_step: *std.Build.Step, | |
| 25 | ) void { | |
| 22 | 26 | const exe = b.addExecutable(.{ |
| 23 | 27 | .name = "zig_resource_test", |
| 24 | 28 | .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 { |
| 6 | 6 | b.default_step = test_step; |
| 7 | 7 | |
| 8 | 8 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 9 | const target: std.zig.CrossTarget = .{}; | |
| 9 | const target = b.host; | |
| 10 | 10 | |
| 11 | 11 | if (builtin.os.tag != .windows) return; |
| 12 | 12 |
test/standalone/zerolength_check/build.zig+2-2| ... | ... | @@ -13,11 +13,11 @@ pub fn build(b: *std.Build) void { |
| 13 | 13 | fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { |
| 14 | 14 | const unit_tests = b.addTest(.{ |
| 15 | 15 | .root_source_file = .{ .path = "src/main.zig" }, |
| 16 | .target = .{ | |
| 16 | .target = b.resolveTargetQuery(.{ | |
| 17 | 17 | .os_tag = .wasi, |
| 18 | 18 | .cpu_arch = .wasm32, |
| 19 | 19 | .cpu_features_add = std.Target.wasm.featureSet(&.{.bulk_memory}), |
| 20 | }, | |
| 20 | }), | |
| 21 | 21 | .optimize = optimize, |
| 22 | 22 | }); |
| 23 | 23 |
test/tests.zig+55-58| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | const CrossTarget = std.zig.CrossTarget; | |
| 5 | 4 | const mem = std.mem; |
| 6 | 5 | const OptimizeMode = std.builtin.OptimizeMode; |
| 7 | 6 | const Step = std.Build.Step; |
| ... | ... | @@ -22,13 +21,13 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig"); |
| 22 | 21 | pub const StackTracesContext = @import("src/StackTrace.zig"); |
| 23 | 22 | |
| 24 | 23 | const TestTarget = struct { |
| 25 | target: CrossTarget = .{}, | |
| 24 | target: std.Target.Query = .{}, | |
| 26 | 25 | optimize_mode: std.builtin.OptimizeMode = .Debug, |
| 27 | 26 | link_libc: ?bool = null, |
| 28 | 27 | single_threaded: ?bool = null, |
| 29 | 28 | use_llvm: ?bool = null, |
| 30 | 29 | use_lld: ?bool = null, |
| 31 | force_pic: ?bool = null, | |
| 30 | pic: ?bool = null, | |
| 32 | 31 | strip: ?bool = null, |
| 33 | 32 | }; |
| 34 | 33 | |
| ... | ... | @@ -105,7 +104,7 @@ const test_targets = blk: { |
| 105 | 104 | }, |
| 106 | 105 | .use_llvm = false, |
| 107 | 106 | .use_lld = false, |
| 108 | .force_pic = true, | |
| 107 | .pic = true, | |
| 109 | 108 | }, |
| 110 | 109 | .{ |
| 111 | 110 | .target = .{ |
| ... | ... | @@ -146,7 +145,7 @@ const test_targets = blk: { |
| 146 | 145 | //}, |
| 147 | 146 | // https://github.com/ziglang/zig/issues/13623 |
| 148 | 147 | //.{ |
| 149 | // .target = CrossTarget.parse(.{ | |
| 148 | // .target = std.Target.Query.parse(.{ | |
| 150 | 149 | // .arch_os_abi = "arm-linux-none", |
| 151 | 150 | // .cpu_features = "generic+v8a", |
| 152 | 151 | // }) catch unreachable, |
| ... | ... | @@ -287,13 +286,13 @@ const test_targets = blk: { |
| 287 | 286 | }, |
| 288 | 287 | |
| 289 | 288 | .{ |
| 290 | .target = CrossTarget.parse(.{ | |
| 289 | .target = std.Target.Query.parse(.{ | |
| 291 | 290 | .arch_os_abi = "arm-linux-none", |
| 292 | 291 | .cpu_features = "generic+v8a", |
| 293 | 292 | }) catch unreachable, |
| 294 | 293 | }, |
| 295 | 294 | .{ |
| 296 | .target = CrossTarget.parse(.{ | |
| 295 | .target = std.Target.Query.parse(.{ | |
| 297 | 296 | .arch_os_abi = "arm-linux-musleabihf", |
| 298 | 297 | .cpu_features = "generic+v8a", |
| 299 | 298 | }) catch unreachable, |
| ... | ... | @@ -301,7 +300,7 @@ const test_targets = blk: { |
| 301 | 300 | }, |
| 302 | 301 | // https://github.com/ziglang/zig/issues/3287 |
| 303 | 302 | //.{ |
| 304 | // .target = CrossTarget.parse(.{ | |
| 303 | // .target = std.Target.Query.parse(.{ | |
| 305 | 304 | // .arch_os_abi = "arm-linux-gnueabihf", |
| 306 | 305 | // .cpu_features = "generic+v8a", |
| 307 | 306 | // }) catch unreachable, |
| ... | ... | @@ -495,10 +494,10 @@ const test_targets = blk: { |
| 495 | 494 | }; |
| 496 | 495 | |
| 497 | 496 | const CAbiTarget = struct { |
| 498 | target: CrossTarget = .{}, | |
| 497 | target: std.Target.Query = .{}, | |
| 499 | 498 | use_llvm: ?bool = null, |
| 500 | 499 | use_lld: ?bool = null, |
| 501 | force_pic: ?bool = null, | |
| 500 | pic: ?bool = null, | |
| 502 | 501 | strip: ?bool = null, |
| 503 | 502 | c_defines: []const []const u8 = &.{}, |
| 504 | 503 | }; |
| ... | ... | @@ -543,7 +542,7 @@ const c_abi_targets = [_]CAbiTarget{ |
| 543 | 542 | }, |
| 544 | 543 | .use_llvm = false, |
| 545 | 544 | .use_lld = false, |
| 546 | .force_pic = true, | |
| 545 | .pic = true, | |
| 547 | 546 | .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, |
| 548 | 547 | }, |
| 549 | 548 | .{ |
| ... | ... | @@ -645,7 +644,7 @@ pub fn addStackTraceTests( |
| 645 | 644 | const check_exe = b.addExecutable(.{ |
| 646 | 645 | .name = "check-stack-trace", |
| 647 | 646 | .root_source_file = .{ .path = "test/src/check-stack-trace.zig" }, |
| 648 | .target = .{}, | |
| 647 | .target = b.host, | |
| 649 | 648 | .optimize = .Debug, |
| 650 | 649 | }); |
| 651 | 650 | |
| ... | ... | @@ -682,12 +681,14 @@ pub fn addStandaloneTests( |
| 682 | 681 | if (os_tag != builtin.os.tag) continue; |
| 683 | 682 | } |
| 684 | 683 | |
| 684 | const resolved_target = b.resolveTargetQuery(case.target); | |
| 685 | ||
| 685 | 686 | if (case.is_exe) { |
| 686 | 687 | const exe = b.addExecutable(.{ |
| 687 | 688 | .name = std.fs.path.stem(case.src_path), |
| 688 | 689 | .root_source_file = .{ .path = case.src_path }, |
| 689 | 690 | .optimize = optimize, |
| 690 | .target = case.target, | |
| 691 | .target = resolved_target, | |
| 691 | 692 | }); |
| 692 | 693 | if (case.link_libc) exe.linkLibC(); |
| 693 | 694 | |
| ... | ... | @@ -701,7 +702,7 @@ pub fn addStandaloneTests( |
| 701 | 702 | .name = std.fs.path.stem(case.src_path), |
| 702 | 703 | .root_source_file = .{ .path = case.src_path }, |
| 703 | 704 | .optimize = optimize, |
| 704 | .target = case.target, | |
| 705 | .target = resolved_target, | |
| 705 | 706 | }); |
| 706 | 707 | if (case.link_libc) exe.linkLibC(); |
| 707 | 708 | |
| ... | ... | @@ -1001,7 +1002,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step { |
| 1001 | 1002 | pub fn addRunTranslatedCTests( |
| 1002 | 1003 | b: *std.Build, |
| 1003 | 1004 | test_filter: ?[]const u8, |
| 1004 | target: std.zig.CrossTarget, | |
| 1005 | target: std.Build.ResolvedTarget, | |
| 1005 | 1006 | ) *Step { |
| 1006 | 1007 | const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM"); |
| 1007 | 1008 | cases.* = .{ |
| ... | ... | @@ -1035,14 +1036,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1035 | 1036 | |
| 1036 | 1037 | for (test_targets) |test_target| { |
| 1037 | 1038 | 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); | |
| 1040 | 1041 | |
| 1041 | 1042 | if (options.skip_non_native and !is_native) |
| 1042 | 1043 | continue; |
| 1043 | 1044 | |
| 1045 | const resolved_target = b.resolveTargetQuery(test_target.target); | |
| 1046 | const target = resolved_target.result; | |
| 1047 | ||
| 1044 | 1048 | 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) | |
| 1046 | 1050 | continue; |
| 1047 | 1051 | |
| 1048 | 1052 | if (options.skip_libc and test_target.link_libc == true) |
| ... | ... | @@ -1052,35 +1056,30 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1052 | 1056 | continue; |
| 1053 | 1057 | |
| 1054 | 1058 | // 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 | |
| 1057 | 1060 | test_target.use_llvm == false and mem.eql(u8, options.name, "compiler-rt")) |
| 1058 | 1061 | continue; |
| 1059 | 1062 | |
| 1060 | 1063 | // TODO get compiler-rt tests passing for wasm32-wasi |
| 1061 | 1064 | // 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 | |
| 1064 | 1066 | mem.eql(u8, options.name, "compiler-rt")) |
| 1065 | 1067 | { |
| 1066 | 1068 | continue; |
| 1067 | 1069 | } |
| 1068 | 1070 | |
| 1069 | 1071 | // 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 | |
| 1071 | 1073 | test_target.use_llvm == false and mem.eql(u8, options.name, "universal-libc")) |
| 1072 | 1074 | continue; |
| 1073 | 1075 | |
| 1074 | 1076 | // 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 | |
| 1077 | 1078 | test_target.use_llvm == false and mem.eql(u8, options.name, "std")) |
| 1078 | 1079 | continue; |
| 1079 | 1080 | |
| 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 | |
| 1084 | 1083 | mem.eql(u8, options.name, "std")) |
| 1085 | 1084 | { |
| 1086 | 1085 | // https://github.com/ziglang/zig/issues/17902 |
| ... | ... | @@ -1093,11 +1092,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1093 | 1092 | if (!want_this_mode) continue; |
| 1094 | 1093 | |
| 1095 | 1094 | 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; | |
| 1098 | 1097 | |
| 1099 | 1098 | // 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) | |
| 1101 | 1100 | options.max_rss * 2 |
| 1102 | 1101 | else |
| 1103 | 1102 | options.max_rss; |
| ... | ... | @@ -1105,7 +1104,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1105 | 1104 | const these_tests = b.addTest(.{ |
| 1106 | 1105 | .root_source_file = .{ .path = options.root_src }, |
| 1107 | 1106 | .optimize = test_target.optimize_mode, |
| 1108 | .target = test_target.target, | |
| 1107 | .target = resolved_target, | |
| 1109 | 1108 | .max_rss = max_rss, |
| 1110 | 1109 | .filter = options.test_filter, |
| 1111 | 1110 | .link_libc = test_target.link_libc, |
| ... | ... | @@ -1113,24 +1112,24 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1113 | 1112 | .use_llvm = test_target.use_llvm, |
| 1114 | 1113 | .use_lld = test_target.use_lld, |
| 1115 | 1114 | .zig_lib_dir = .{ .path = "lib" }, |
| 1115 | .pic = test_target.pic, | |
| 1116 | .strip = test_target.strip, | |
| 1116 | 1117 | }); |
| 1117 | these_tests.force_pic = test_target.force_pic; | |
| 1118 | these_tests.strip = test_target.strip; | |
| 1119 | 1118 | const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else ""; |
| 1120 | 1119 | const backend_suffix = if (test_target.use_llvm == true) |
| 1121 | 1120 | "-llvm" |
| 1122 | else if (test_target.target.ofmt == std.Target.ObjectFormat.c) | |
| 1121 | else if (target.ofmt == std.Target.ObjectFormat.c) | |
| 1123 | 1122 | "-cbe" |
| 1124 | 1123 | else if (test_target.use_llvm == false) |
| 1125 | 1124 | "-selfhosted" |
| 1126 | 1125 | else |
| 1127 | 1126 | ""; |
| 1128 | 1127 | 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 ""; | |
| 1130 | 1129 | |
| 1131 | 1130 | these_tests.addIncludePath(.{ .path = "test" }); |
| 1132 | 1131 | |
| 1133 | if (test_target.target.getOs().tag == .wasi) { | |
| 1132 | if (target.os.tag == .wasi) { | |
| 1134 | 1133 | // WASI's default stack size can be too small for some big tests. |
| 1135 | 1134 | these_tests.stack_size = 2 * 1024 * 1024; |
| 1136 | 1135 | } |
| ... | ... | @@ -1147,14 +1146,14 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1147 | 1146 | use_pic, |
| 1148 | 1147 | }); |
| 1149 | 1148 | |
| 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; | |
| 1153 | 1152 | |
| 1154 | 1153 | const compile_c = b.addExecutable(.{ |
| 1155 | 1154 | .name = qualified_name, |
| 1156 | 1155 | .link_libc = test_target.link_libc, |
| 1157 | .target = altered_target, | |
| 1156 | .target = b.resolveTargetQuery(altered_query), | |
| 1158 | 1157 | .zig_lib_dir = .{ .path = "lib" }, |
| 1159 | 1158 | }); |
| 1160 | 1159 | compile_c.addCSourceFile(.{ |
| ... | ... | @@ -1178,7 +1177,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { |
| 1178 | 1177 | }, |
| 1179 | 1178 | }); |
| 1180 | 1179 | compile_c.addIncludePath(.{ .path = "lib" }); // for zig.h |
| 1181 | if (test_target.target.getOsTag() == .windows) { | |
| 1180 | if (target.os.tag == .windows) { | |
| 1182 | 1181 | if (true) { |
| 1183 | 1182 | // Unfortunately this requires about 8G of RAM for clang to compile |
| 1184 | 1183 | // 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 |
| 1229 | 1228 | for (c_abi_targets) |c_abi_target| { |
| 1230 | 1229 | if (skip_non_native and !c_abi_target.target.isNative()) continue; |
| 1231 | 1230 | |
| 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) { | |
| 1233 | 1235 | // https://github.com/ziglang/zig/issues/14908 |
| 1234 | 1236 | continue; |
| 1235 | 1237 | } |
| 1236 | 1238 | |
| 1237 | 1239 | const test_step = b.addTest(.{ |
| 1238 | 1240 | .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, | |
| 1241 | 1243 | @tagName(optimize_mode), |
| 1242 | 1244 | if (c_abi_target.use_llvm == true) |
| 1243 | 1245 | "-llvm" |
| 1244 | else if (c_abi_target.target.ofmt == std.Target.ObjectFormat.c) | |
| 1246 | else if (target.ofmt == .c) | |
| 1245 | 1247 | "-cbe" |
| 1246 | 1248 | else if (c_abi_target.use_llvm == false) |
| 1247 | 1249 | "-selfhosted" |
| 1248 | 1250 | else |
| 1249 | 1251 | "", |
| 1250 | 1252 | 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 "", | |
| 1252 | 1254 | }), |
| 1253 | 1255 | .root_source_file = .{ .path = "test/c_abi/main.zig" }, |
| 1254 | .target = c_abi_target.target, | |
| 1256 | .target = resolved_target, | |
| 1255 | 1257 | .optimize = optimize_mode, |
| 1256 | 1258 | .link_libc = true, |
| 1257 | 1259 | .use_llvm = c_abi_target.use_llvm, |
| 1258 | 1260 | .use_lld = c_abi_target.use_lld, |
| 1261 | .pic = c_abi_target.pic, | |
| 1262 | .strip = c_abi_target.strip, | |
| 1259 | 1263 | }); |
| 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 | } | |
| 1267 | 1264 | test_step.addCSourceFile(.{ |
| 1268 | 1265 | .file = .{ .path = "test/c_abi/cfuncs.c" }, |
| 1269 | 1266 | .flags = &.{"-std=c99"}, |
| ... | ... | @@ -1297,8 +1294,8 @@ pub fn addCases( |
| 1297 | 1294 | var dir = try b.build_root.handle.openDir("test/cases", .{ .iterate = true }); |
| 1298 | 1295 | defer dir.close(); |
| 1299 | 1296 | |
| 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); | |
| 1302 | 1299 | |
| 1303 | 1300 | const cases_dir_path = try b.build_root.join(b.allocator, &.{ "test", "cases" }); |
| 1304 | 1301 | cases.lowerToBuildSteps( |
test/translate_c.zig+2-3| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const tests = @import("tests.zig"); |
| 4 | const CrossTarget = std.zig.CrossTarget; | |
| 5 | 4 | |
| 6 | 5 | // ******************************************************** |
| 7 | 6 | // * * |
| ... | ... | @@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1846 | 1845 | \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void; |
| 1847 | 1846 | }); |
| 1848 | 1847 | |
| 1849 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ | |
| 1848 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | |
| 1850 | 1849 | .arch_os_abi = "arm-linux-none", |
| 1851 | 1850 | .cpu_features = "generic+v8_5a", |
| 1852 | 1851 | }) catch unreachable, |
| ... | ... | @@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1857 | 1856 | \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; |
| 1858 | 1857 | }); |
| 1859 | 1858 | |
| 1860 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ | |
| 1859 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | |
| 1861 | 1860 | .arch_os_abi = "aarch64-linux-none", |
| 1862 | 1861 | .cpu_features = "generic+v8_5a", |
| 1863 | 1862 | }) catch unreachable, |
tools/docgen.zig+13-12| ... | ... | @@ -9,13 +9,12 @@ const print = std.debug.print; |
| 9 | 9 | const mem = std.mem; |
| 10 | 10 | const testing = std.testing; |
| 11 | 11 | const Allocator = std.mem.Allocator; |
| 12 | const getExternalExecutor = std.zig.system.getExternalExecutor; | |
| 12 | 13 | |
| 13 | 14 | const max_doc_file_size = 10 * 1024 * 1024; |
| 14 | 15 | |
| 15 | const exe_ext = @as(std.zig.CrossTarget, .{}).exeFileExt(); | |
| 16 | 16 | const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch); |
| 17 | 17 | const tmp_dir_name = "docgen_tmp"; |
| 18 | const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext; | |
| 19 | 18 | |
| 20 | 19 | const usage = |
| 21 | 20 | \\Usage: docgen [--zig] [--skip-code-tests] input output" |
| ... | ... | @@ -1309,7 +1308,7 @@ fn genHtml( |
| 1309 | 1308 | var env_map = try process.getEnvMap(allocator); |
| 1310 | 1309 | try env_map.put("YES_COLOR", "1"); |
| 1311 | 1310 | |
| 1312 | const host = try std.zig.system.NativeTargetInfo.detect(.{}); | |
| 1311 | const host = try std.zig.system.resolveTargetQuery(.{}); | |
| 1313 | 1312 | const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe, opt_zig_lib_dir); |
| 1314 | 1313 | |
| 1315 | 1314 | for (toc.nodes) |node| { |
| ... | ... | @@ -1424,9 +1423,7 @@ fn genHtml( |
| 1424 | 1423 | try build_args.append("-lc"); |
| 1425 | 1424 | try shell_out.print("-lc ", .{}); |
| 1426 | 1425 | } |
| 1427 | const target = try std.zig.CrossTarget.parse(.{ | |
| 1428 | .arch_os_abi = code.target_str orelse "native", | |
| 1429 | }); | |
| 1426 | ||
| 1430 | 1427 | if (code.target_str) |triple| { |
| 1431 | 1428 | try build_args.appendSlice(&[_][]const u8{ "-target", triple }); |
| 1432 | 1429 | try shell_out.print("-target {s} ", .{triple}); |
| ... | ... | @@ -1490,9 +1487,13 @@ fn genHtml( |
| 1490 | 1487 | } |
| 1491 | 1488 | } |
| 1492 | 1489 | |
| 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 | ||
| 1493 | 1495 | const path_to_exe = try std.fmt.allocPrint(allocator, "./{s}{s}", .{ |
| 1494 | code.name, | |
| 1495 | target.exeFileExt(), | |
| 1496 | code.name, target.exeFileExt(), | |
| 1496 | 1497 | }); |
| 1497 | 1498 | const run_args = &[_][]const u8{path_to_exe}; |
| 1498 | 1499 | |
| ... | ... | @@ -1565,13 +1566,13 @@ fn genHtml( |
| 1565 | 1566 | try test_args.appendSlice(&[_][]const u8{ "-target", triple }); |
| 1566 | 1567 | try shell_out.print("-target {s} ", .{triple}); |
| 1567 | 1568 | |
| 1568 | const cross_target = try std.zig.CrossTarget.parse(.{ | |
| 1569 | const target_query = try std.Target.Query.parse(.{ | |
| 1569 | 1570 | .arch_os_abi = triple, |
| 1570 | 1571 | }); |
| 1571 | const target_info = try std.zig.system.NativeTargetInfo.detect( | |
| 1572 | cross_target, | |
| 1572 | const target = try std.zig.system.resolveTargetQuery( | |
| 1573 | target_query, | |
| 1573 | 1574 | ); |
| 1574 | switch (host.getExternalExecutor(&target_info, .{ | |
| 1575 | switch (getExternalExecutor(host, &target, .{ | |
| 1575 | 1576 | .link_libc = code.link_libc, |
| 1576 | 1577 | })) { |
| 1577 | 1578 | .native => {}, |