authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-10-30 15:24:47+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-10-30 15:24:47+00:00
log4174ab9c2c98d798452dd745d5d5dc657d601591
tree3c7b27d5e3ebc31e94c2865e017707717ed30c8b
parent74c23a237ef5245b63eb06b832a511aabeb715c0
parent32779a7c7392d823c945ae0a13a65cf94a4044b8
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #25726 from mlugg/std-log-colors

Cache stderr ttyconf, colorize `std.log`, and fix `--webui`

45 files changed, 662 insertions(+), 584 deletions(-)

lib/compiler/build_runner.zig+16-25
...@@ -442,8 +442,7 @@ pub fn main() !void {...@@ -442,8 +442,7 @@ pub fn main() !void {
442 if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});442 if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
443 }443 }
444444
445 const stderr: std.fs.File = .stderr();445 const ttyconf = color.detectTtyConf();
446 const ttyconf = get_tty_conf(color, stderr);
447 switch (ttyconf) {446 switch (ttyconf) {
448 .no_color => try graph.env_map.put("NO_COLOR", "1"),447 .no_color => try graph.env_map.put("NO_COLOR", "1"),
449 .escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"),448 .escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"),
...@@ -522,9 +521,9 @@ pub fn main() !void {...@@ -522,9 +521,9 @@ pub fn main() !void {
522 .error_style = error_style,521 .error_style = error_style,
523 .multiline_errors = multiline_errors,522 .multiline_errors = multiline_errors,
524 .summary = summary orelse if (watch or webui_listen != null) .line else .failures,523 .summary = summary orelse if (watch or webui_listen != null) .line else .failures,
525 .ttyconf = ttyconf,
526 .stderr = stderr,
527 .thread_pool = undefined,524 .thread_pool = undefined,
525
526 .ttyconf = ttyconf,
528 };527 };
529 defer {528 defer {
530 run.memory_blocked_steps.deinit(gpa);529 run.memory_blocked_steps.deinit(gpa);
...@@ -563,9 +562,9 @@ pub fn main() !void {...@@ -563,9 +562,9 @@ pub fn main() !void {
563 break :ws .init(.{562 break :ws .init(.{
564 .gpa = gpa,563 .gpa = gpa,
565 .thread_pool = &run.thread_pool,564 .thread_pool = &run.thread_pool,
565 .ttyconf = ttyconf,
566 .graph = &graph,566 .graph = &graph,
567 .all_steps = run.step_stack.keys(),567 .all_steps = run.step_stack.keys(),
568 .ttyconf = run.ttyconf,
569 .root_prog_node = main_progress_node,568 .root_prog_node = main_progress_node,
570 .watch = watch,569 .watch = watch,
571 .listen_address = listen_address,570 .listen_address = listen_address,
...@@ -578,7 +577,7 @@ pub fn main() !void {...@@ -578,7 +577,7 @@ pub fn main() !void {
578 }577 }
579578
580 rebuild: while (true) : (if (run.error_style.clearOnUpdate()) {579 rebuild: while (true) : (if (run.error_style.clearOnUpdate()) {
581 const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);580 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
582 defer std.debug.unlockStderrWriter();581 defer std.debug.unlockStderrWriter();
583 try bw.writeAll("\x1B[2J\x1B[3J\x1B[H");582 try bw.writeAll("\x1B[2J\x1B[3J\x1B[H");
584 }) {583 }) {
...@@ -682,13 +681,14 @@ const Run = struct {...@@ -682,13 +681,14 @@ const Run = struct {
682 /// Allocated into `gpa`.681 /// Allocated into `gpa`.
683 step_stack: std.AutoArrayHashMapUnmanaged(*Step, void),682 step_stack: std.AutoArrayHashMapUnmanaged(*Step, void),
684 thread_pool: std.Thread.Pool,683 thread_pool: std.Thread.Pool,
684 /// Similar to the `tty.Config` returned by `std.debug.lockStderrWriter`,
685 /// but also respects the '--color' flag.
686 ttyconf: tty.Config,
685687
686 claimed_rss: usize,688 claimed_rss: usize,
687 error_style: ErrorStyle,689 error_style: ErrorStyle,
688 multiline_errors: MultilineErrors,690 multiline_errors: MultilineErrors,
689 summary: Summary,691 summary: Summary,
690 ttyconf: tty.Config,
691 stderr: File,
692};692};
693693
694fn prepare(694fn prepare(
...@@ -834,8 +834,6 @@ fn runStepNames(...@@ -834,8 +834,6 @@ fn runStepNames(
834 }834 }
835 }835 }
836836
837 const ttyconf = run.ttyconf;
838
839 if (fuzz) |mode| blk: {837 if (fuzz) |mode| blk: {
840 switch (builtin.os.tag) {838 switch (builtin.os.tag) {
841 // Current implementation depends on two things that need to be ported to Windows:839 // Current implementation depends on two things that need to be ported to Windows:
...@@ -863,9 +861,9 @@ fn runStepNames(...@@ -863,9 +861,9 @@ fn runStepNames(
863 gpa,861 gpa,
864 io,862 io,
865 thread_pool,863 thread_pool,
864 run.ttyconf,
866 step_stack.keys(),865 step_stack.keys(),
867 parent_prog_node,866 parent_prog_node,
868 ttyconf,
869 mode,867 mode,
870 ) catch |err| fatal("failed to start fuzzer: {s}", .{@errorName(err)});868 ) catch |err| fatal("failed to start fuzzer: {s}", .{@errorName(err)});
871 defer f.deinit();869 defer f.deinit();
...@@ -890,8 +888,9 @@ fn runStepNames(...@@ -890,8 +888,9 @@ fn runStepNames(
890 .none => break :summary,888 .none => break :summary,
891 }889 }
892890
893 const w = std.debug.lockStderrWriter(&stdio_buffer_allocation);891 const w, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
894 defer std.debug.unlockStderrWriter();892 defer std.debug.unlockStderrWriter();
893 const ttyconf = run.ttyconf;
895894
896 const total_count = success_count + failure_count + pending_count + skipped_count;895 const total_count = success_count + failure_count + pending_count + skipped_count;
897 ttyconf.setColor(w, .cyan) catch {};896 ttyconf.setColor(w, .cyan) catch {};
...@@ -1399,9 +1398,10 @@ fn workerMakeOneStep(...@@ -1399,9 +1398,10 @@ fn workerMakeOneStep(
1399 const show_error_msgs = s.result_error_msgs.items.len > 0;1398 const show_error_msgs = s.result_error_msgs.items.len > 0;
1400 const show_stderr = s.result_stderr.len > 0;1399 const show_stderr = s.result_stderr.len > 0;
1401 if (show_error_msgs or show_compile_errors or show_stderr) {1400 if (show_error_msgs or show_compile_errors or show_stderr) {
1402 const bw = std.debug.lockStderrWriter(&stdio_buffer_allocation);1401 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
1403 defer std.debug.unlockStderrWriter();1402 defer std.debug.unlockStderrWriter();
1404 printErrorMessages(run.gpa, s, .{ .ttyconf = run.ttyconf }, bw, run.error_style, run.multiline_errors) catch {};1403 const ttyconf = run.ttyconf;
1404 printErrorMessages(run.gpa, s, .{}, bw, ttyconf, run.error_style, run.multiline_errors) catch {};
1405 }1405 }
14061406
1407 handle_result: {1407 handle_result: {
...@@ -1465,11 +1465,10 @@ pub fn printErrorMessages(...@@ -1465,11 +1465,10 @@ pub fn printErrorMessages(
1465 failing_step: *Step,1465 failing_step: *Step,
1466 options: std.zig.ErrorBundle.RenderOptions,1466 options: std.zig.ErrorBundle.RenderOptions,
1467 stderr: *Writer,1467 stderr: *Writer,
1468 ttyconf: tty.Config,
1468 error_style: ErrorStyle,1469 error_style: ErrorStyle,
1469 multiline_errors: MultilineErrors,1470 multiline_errors: MultilineErrors,
1470) !void {1471) !void {
1471 const ttyconf = options.ttyconf;
1472
1473 if (error_style.verboseContext()) {1472 if (error_style.verboseContext()) {
1474 // Provide context for where these error messages are coming from by1473 // Provide context for where these error messages are coming from by
1475 // printing the corresponding Step subtree.1474 // printing the corresponding Step subtree.
...@@ -1513,7 +1512,7 @@ pub fn printErrorMessages(...@@ -1513,7 +1512,7 @@ pub fn printErrorMessages(
1513 }1512 }
1514 }1513 }
15151514
1516 try failing_step.result_error_bundle.renderToWriter(options, stderr);1515 try failing_step.result_error_bundle.renderToWriter(options, stderr, ttyconf);
15171516
1518 for (failing_step.result_error_msgs.items) |msg| {1517 for (failing_step.result_error_msgs.items) |msg| {
1519 try ttyconf.setColor(stderr, .red);1518 try ttyconf.setColor(stderr, .red);
...@@ -1759,14 +1758,6 @@ const ErrorStyle = enum {...@@ -1759,14 +1758,6 @@ const ErrorStyle = enum {
1759const MultilineErrors = enum { indent, newline, none };1758const MultilineErrors = enum { indent, newline, none };
1760const Summary = enum { all, new, failures, line, none };1759const Summary = enum { all, new, failures, line, none };
17611760
1762fn get_tty_conf(color: Color, stderr: File) tty.Config {
1763 return switch (color) {
1764 .auto => tty.detectConfig(stderr),
1765 .on => .escape_codes,
1766 .off => .no_color,
1767 };
1768}
1769
1770fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {1761fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
1771 std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);1762 std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);
1772 process.exit(1);1763 process.exit(1);
lib/compiler/resinator/cli.zig+3-3
...@@ -124,10 +124,10 @@ pub const Diagnostics = struct {...@@ -124,10 +124,10 @@ pub const Diagnostics = struct {
124 try self.errors.append(self.allocator, error_details);124 try self.errors.append(self.allocator, error_details);
125 }125 }
126126
127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8, config: std.Io.tty.Config) void {127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void {
128 const stderr = std.debug.lockStderrWriter(&.{});128 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
129 defer std.debug.unlockStderrWriter();129 defer std.debug.unlockStderrWriter();
130 self.renderToWriter(args, stderr, config) catch return;130 self.renderToWriter(args, stderr, ttyconf) catch return;
131 }131 }
132132
133 pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void {133 pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, writer: *std.Io.Writer, config: std.Io.tty.Config) !void {
lib/compiler/resinator/errors.zig+3-8
...@@ -67,20 +67,15 @@ pub const Diagnostics = struct {...@@ -67,20 +67,15 @@ pub const Diagnostics = struct {
67 return @intCast(index);67 return @intCast(index);
68 }68 }
6969
70 pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, tty_config: std.Io.tty.Config, source_mappings: ?SourceMappings) void {70 pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
71 const io = self.io;71 const io = self.io;
72 const stderr = std.debug.lockStderrWriter(&.{});72 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
73 defer std.debug.unlockStderrWriter();73 defer std.debug.unlockStderrWriter();
74 for (self.errors.items) |err_details| {74 for (self.errors.items) |err_details| {
75 renderErrorMessage(io, stderr, tty_config, cwd, err_details, source, self.strings.items, source_mappings) catch return;75 renderErrorMessage(io, stderr, ttyconf, cwd, err_details, source, self.strings.items, source_mappings) catch return;
76 }76 }
77 }77 }
7878
79 pub fn renderToStdErrDetectTTY(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, source_mappings: ?SourceMappings) void {
80 const tty_config = std.Io.tty.detectConfig(std.fs.File.stderr());
81 return self.renderToStdErr(cwd, source, tty_config, source_mappings);
82 }
83
84 pub fn contains(self: *const Diagnostics, err: ErrorDetails.Error) bool {79 pub fn contains(self: *const Diagnostics, err: ErrorDetails.Error) bool {
85 for (self.errors.items) |details| {80 for (self.errors.items) |details| {
86 if (details.err == err) return true;81 if (details.err == err) return true;
lib/compiler/resinator/main.zig+29-34
...@@ -28,13 +28,11 @@ pub fn main() !void {...@@ -28,13 +28,11 @@ pub fn main() !void {
28 defer arena_state.deinit();28 defer arena_state.deinit();
29 const arena = arena_state.allocator();29 const arena = arena_state.allocator();
3030
31 const stderr = std.fs.File.stderr();
32 const stderr_config = std.Io.tty.detectConfig(stderr);
33
34 const args = try std.process.argsAlloc(arena);31 const args = try std.process.argsAlloc(arena);
3532
36 if (args.len < 2) {33 if (args.len < 2) {
37 try renderErrorMessage(std.debug.lockStderrWriter(&.{}), stderr_config, .err, "expected zig lib dir as first argument", .{});34 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
35 try renderErrorMessage(w, ttyconf, .err, "expected zig lib dir as first argument", .{});
38 std.process.exit(1);36 std.process.exit(1);
39 }37 }
40 const zig_lib_dir = args[1];38 const zig_lib_dir = args[1];
...@@ -56,9 +54,7 @@ pub fn main() !void {...@@ -56,9 +54,7 @@ pub fn main() !void {
56 .in = undefined, // won't be receiving messages54 .in = undefined, // won't be receiving messages
57 },55 },
58 },56 },
59 false => .{57 false => .stderr,
60 .tty = stderr_config,
61 },
62 };58 };
6359
64 var options = options: {60 var options = options: {
...@@ -75,12 +71,14 @@ pub fn main() !void {...@@ -75,12 +71,14 @@ pub fn main() !void {
7571
76 if (!zig_integration) {72 if (!zig_integration) {
77 // print any warnings/notes73 // print any warnings/notes
78 cli_diagnostics.renderToStdErr(cli_args, stderr_config);74 cli_diagnostics.renderToStdErr(cli_args);
79 // If there was something printed, then add an extra newline separator75 // If there was something printed, then add an extra newline separator
80 // so that there is a clear separation between the cli diagnostics and whatever76 // so that there is a clear separation between the cli diagnostics and whatever
81 // gets printed after77 // gets printed after
82 if (cli_diagnostics.errors.items.len > 0) {78 if (cli_diagnostics.errors.items.len > 0) {
83 try stderr.writeAll("\n");79 const stderr, _ = std.debug.lockStderrWriter(&.{});
80 defer std.debug.unlockStderrWriter();
81 try stderr.writeByte('\n');
84 }82 }
85 }83 }
86 break :options options;84 break :options options;
...@@ -130,17 +128,18 @@ pub fn main() !void {...@@ -130,17 +128,18 @@ pub fn main() !void {
130 const aro_arena = aro_arena_state.allocator();128 const aro_arena = aro_arena_state.allocator();
131129
132 var stderr_buf: [512]u8 = undefined;130 var stderr_buf: [512]u8 = undefined;
133 var stderr_writer = stderr.writer(&stderr_buf);131 var diagnostics: aro.Diagnostics = .{ .output = output: {
134 var diagnostics: aro.Diagnostics = switch (zig_integration) {132 if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } };
135 false => .{ .output = .{ .to_writer = .{133 const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf);
136 .writer = &stderr_writer.interface,134 break :output .{ .to_writer = .{
137 .color = stderr_config,135 .writer = w,
138 } } },136 .color = ttyconf,
139 true => .{ .output = .{ .to_list = .{137 } };
140 .arena = .init(gpa),138 } };
141 } } },139 defer {
142 };140 diagnostics.deinit();
143 defer diagnostics.deinit();141 if (!zig_integration) std.debug.unlockStderrWriter();
142 }
144143
145 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());144 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());
146 defer comp.deinit();145 defer comp.deinit();
...@@ -307,7 +306,7 @@ pub fn main() !void {...@@ -307,7 +306,7 @@ pub fn main() !void {
307306
308 // print any warnings/notes307 // print any warnings/notes
309 if (!zig_integration) {308 if (!zig_integration) {
310 diagnostics.renderToStdErr(std.fs.cwd(), final_input, stderr_config, mapping_results.mappings);309 diagnostics.renderToStdErr(std.fs.cwd(), final_input, mapping_results.mappings);
311 }310 }
312311
313 // write the depfile312 // write the depfile
...@@ -660,7 +659,7 @@ const SourceMappings = @import("source_mapping.zig").SourceMappings;...@@ -660,7 +659,7 @@ const SourceMappings = @import("source_mapping.zig").SourceMappings;
660659
661const ErrorHandler = union(enum) {660const ErrorHandler = union(enum) {
662 server: std.zig.Server,661 server: std.zig.Server,
663 tty: std.Io.tty.Config,662 stderr,
664663
665 pub fn emitCliDiagnostics(664 pub fn emitCliDiagnostics(
666 self: *ErrorHandler,665 self: *ErrorHandler,
...@@ -675,9 +674,7 @@ const ErrorHandler = union(enum) {...@@ -675,9 +674,7 @@ const ErrorHandler = union(enum) {
675674
676 try server.serveErrorBundle(error_bundle);675 try server.serveErrorBundle(error_bundle);
677 },676 },
678 .tty => {677 .stderr => diagnostics.renderToStdErr(args),
679 diagnostics.renderToStdErr(args, self.tty);
680 },
681 }678 }
682 }679 }
683680
...@@ -698,11 +695,11 @@ const ErrorHandler = union(enum) {...@@ -698,11 +695,11 @@ const ErrorHandler = union(enum) {
698695
699 try server.serveErrorBundle(error_bundle);696 try server.serveErrorBundle(error_bundle);
700 },697 },
701 .tty => {698 .stderr => {
702 // aro errors have already been emitted699 // aro errors have already been emitted
703 const stderr = std.debug.lockStderrWriter(&.{});700 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
704 defer std.debug.unlockStderrWriter();701 defer std.debug.unlockStderrWriter();
705 try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg});702 try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg});
706 },703 },
707 }704 }
708 }705 }
...@@ -722,9 +719,7 @@ const ErrorHandler = union(enum) {...@@ -722,9 +719,7 @@ const ErrorHandler = union(enum) {
722719
723 try server.serveErrorBundle(error_bundle);720 try server.serveErrorBundle(error_bundle);
724 },721 },
725 .tty => {722 .stderr => diagnostics.renderToStdErr(cwd, source, mappings),
726 diagnostics.renderToStdErr(cwd, source, self.tty, mappings);
727 },
728 }723 }
729 }724 }
730725
...@@ -745,10 +740,10 @@ const ErrorHandler = union(enum) {...@@ -745,10 +740,10 @@ const ErrorHandler = union(enum) {
745740
746 try server.serveErrorBundle(error_bundle);741 try server.serveErrorBundle(error_bundle);
747 },742 },
748 .tty => {743 .stderr => {
749 const stderr = std.debug.lockStderrWriter(&.{});744 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
750 defer std.debug.unlockStderrWriter();745 defer std.debug.unlockStderrWriter();
751 try renderErrorMessage(stderr, self.tty, msg_type, format, args);746 try renderErrorMessage(stderr, ttyconf, msg_type, format, args);
752 },747 },
753 }748 }
754 }749 }
lib/compiler/std-docs.zig+1-2
...@@ -394,8 +394,7 @@ fn buildWasmBinary(...@@ -394,8 +394,7 @@ fn buildWasmBinary(
394 }394 }
395395
396 if (result_error_bundle.errorMessageCount() > 0) {396 if (result_error_bundle.errorMessageCount() > 0) {
397 const color = std.zig.Color.auto;397 result_error_bundle.renderToStdErr(.{}, true);
398 result_error_bundle.renderToStdErr(color.renderOptions());
399 std.log.err("the following command failed with {d} compilation errors:\n{s}", .{398 std.log.err("the following command failed with {d} compilation errors:\n{s}", .{
400 result_error_bundle.errorMessageCount(),399 result_error_bundle.errorMessageCount(),
401 try std.Build.Step.allocPrintCmd(arena, null, argv.items),400 try std.Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/Build.zig+5-7
...@@ -2257,8 +2257,8 @@ pub const GeneratedFile = struct {...@@ -2257,8 +2257,8 @@ pub const GeneratedFile = struct {
22572257
2258 pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {2258 pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {
2259 return gen.path orelse {2259 return gen.path orelse {
2260 const w = debug.lockStderrWriter(&.{});2260 const w, const ttyconf = debug.lockStderrWriter(&.{});
2261 dumpBadGetPathHelp(gen.step, w, .detect(.stderr()), src_builder, asking_step) catch {};2261 dumpBadGetPathHelp(gen.step, w, ttyconf, src_builder, asking_step) catch {};
2262 debug.unlockStderrWriter();2262 debug.unlockStderrWriter();
2263 @panic("misconfigured build script");2263 @panic("misconfigured build script");
2264 };2264 };
...@@ -2466,8 +2466,8 @@ pub const LazyPath = union(enum) {...@@ -2466,8 +2466,8 @@ pub const LazyPath = union(enum) {
2466 var file_path: Cache.Path = .{2466 var file_path: Cache.Path = .{
2467 .root_dir = Cache.Directory.cwd(),2467 .root_dir = Cache.Directory.cwd(),
2468 .sub_path = gen.file.path orelse {2468 .sub_path = gen.file.path orelse {
2469 const w = debug.lockStderrWriter(&.{});2469 const w, const ttyconf = debug.lockStderrWriter(&.{});
2470 dumpBadGetPathHelp(gen.file.step, w, .detect(.stderr()), src_builder, asking_step) catch {};2470 dumpBadGetPathHelp(gen.file.step, w, ttyconf, src_builder, asking_step) catch {};
2471 debug.unlockStderrWriter();2471 debug.unlockStderrWriter();
2472 @panic("misconfigured build script");2472 @panic("misconfigured build script");
2473 },2473 },
...@@ -2558,13 +2558,11 @@ fn dumpBadDirnameHelp(...@@ -2558,13 +2558,11 @@ fn dumpBadDirnameHelp(
2558 comptime msg: []const u8,2558 comptime msg: []const u8,
2559 args: anytype,2559 args: anytype,
2560) anyerror!void {2560) anyerror!void {
2561 const w = debug.lockStderrWriter(&.{});2561 const w, const tty_config = debug.lockStderrWriter(&.{});
2562 defer debug.unlockStderrWriter();2562 defer debug.unlockStderrWriter();
25632563
2564 try w.print(msg, args);2564 try w.print(msg, args);
25652565
2566 const tty_config = std.Io.tty.detectConfig(.stderr());
2567
2568 if (fail_step) |s| {2566 if (fail_step) |s| {
2569 tty_config.setColor(w, .red) catch {};2567 tty_config.setColor(w, .red) catch {};
2570 try w.writeAll(" The step was created by this stack trace:\n");2568 try w.writeAll(" The step was created by this stack trace:\n");
lib/std/Build/Fuzz.zig+9-9
...@@ -16,6 +16,7 @@ const build_runner = @import("root");...@@ -16,6 +16,7 @@ const build_runner = @import("root");
1616
17gpa: Allocator,17gpa: Allocator,
18io: Io,18io: Io,
19ttyconf: tty.Config,
19mode: Mode,20mode: Mode,
2021
21/// Allocated into `gpa`.22/// Allocated into `gpa`.
...@@ -25,7 +26,6 @@ wait_group: std.Thread.WaitGroup,...@@ -25,7 +26,6 @@ wait_group: std.Thread.WaitGroup,
25root_prog_node: std.Progress.Node,26root_prog_node: std.Progress.Node,
26prog_node: std.Progress.Node,27prog_node: std.Progress.Node,
27thread_pool: *std.Thread.Pool,28thread_pool: *std.Thread.Pool,
28ttyconf: tty.Config,
2929
30/// Protects `coverage_files`.30/// Protects `coverage_files`.
31coverage_mutex: std.Thread.Mutex,31coverage_mutex: std.Thread.Mutex,
...@@ -79,9 +79,9 @@ pub fn init(...@@ -79,9 +79,9 @@ pub fn init(
79 gpa: Allocator,79 gpa: Allocator,
80 io: Io,80 io: Io,
81 thread_pool: *std.Thread.Pool,81 thread_pool: *std.Thread.Pool,
82 ttyconf: tty.Config,
82 all_steps: []const *Build.Step,83 all_steps: []const *Build.Step,
83 root_prog_node: std.Progress.Node,84 root_prog_node: std.Progress.Node,
84 ttyconf: tty.Config,
85 mode: Mode,85 mode: Mode,
86) Allocator.Error!Fuzz {86) Allocator.Error!Fuzz {
87 const run_steps: []const *Step.Run = steps: {87 const run_steps: []const *Step.Run = steps: {
...@@ -115,11 +115,11 @@ pub fn init(...@@ -115,11 +115,11 @@ pub fn init(
115 return .{115 return .{
116 .gpa = gpa,116 .gpa = gpa,
117 .io = io,117 .io = io,
118 .ttyconf = ttyconf,
118 .mode = mode,119 .mode = mode,
119 .run_steps = run_steps,120 .run_steps = run_steps,
120 .wait_group = .{},121 .wait_group = .{},
121 .thread_pool = thread_pool,122 .thread_pool = thread_pool,
122 .ttyconf = ttyconf,
123 .root_prog_node = root_prog_node,123 .root_prog_node = root_prog_node,
124 .prog_node = .none,124 .prog_node = .none,
125 .coverage_files = .empty,125 .coverage_files = .empty,
...@@ -158,7 +158,7 @@ pub fn deinit(fuzz: *Fuzz) void {...@@ -158,7 +158,7 @@ pub fn deinit(fuzz: *Fuzz) void {
158 fuzz.gpa.free(fuzz.run_steps);158 fuzz.gpa.free(fuzz.run_steps);
159}159}
160160
161fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) void {161fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) void {
162 rebuildTestsWorkerRunFallible(run, gpa, ttyconf, parent_prog_node) catch |err| {162 rebuildTestsWorkerRunFallible(run, gpa, ttyconf, parent_prog_node) catch |err| {
163 const compile = run.producer.?;163 const compile = run.producer.?;
164 log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{164 log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{
...@@ -167,7 +167,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Con...@@ -167,7 +167,7 @@ fn rebuildTestsWorkerRun(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Con
167 };167 };
168}168}
169169
170fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io.tty.Config, parent_prog_node: std.Progress.Node) !void {170fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: tty.Config, parent_prog_node: std.Progress.Node) !void {
171 const compile = run.producer.?;171 const compile = run.producer.?;
172 const prog_node = parent_prog_node.start(compile.step.name, 0);172 const prog_node = parent_prog_node.start(compile.step.name, 0);
173 defer prog_node.end();173 defer prog_node.end();
...@@ -180,9 +180,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io...@@ -180,9 +180,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io
180180
181 if (show_error_msgs or show_compile_errors or show_stderr) {181 if (show_error_msgs or show_compile_errors or show_stderr) {
182 var buf: [256]u8 = undefined;182 var buf: [256]u8 = undefined;
183 const w = std.debug.lockStderrWriter(&buf);183 const w, _ = std.debug.lockStderrWriter(&buf);
184 defer std.debug.unlockStderrWriter();184 defer std.debug.unlockStderrWriter();
185 build_runner.printErrorMessages(gpa, &compile.step, .{ .ttyconf = ttyconf }, w, .verbose, .indent) catch {};185 build_runner.printErrorMessages(gpa, &compile.step, .{}, w, ttyconf, .verbose, .indent) catch {};
186 }186 }
187187
188 const rebuilt_bin_path = result catch |err| switch (err) {188 const rebuilt_bin_path = result catch |err| switch (err) {
...@@ -206,9 +206,9 @@ fn fuzzWorkerRun(...@@ -206,9 +206,9 @@ fn fuzzWorkerRun(
206 run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {206 run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
207 error.MakeFailed => {207 error.MakeFailed => {
208 var buf: [256]u8 = undefined;208 var buf: [256]u8 = undefined;
209 const w = std.debug.lockStderrWriter(&buf);209 const w, _ = std.debug.lockStderrWriter(&buf);
210 defer std.debug.unlockStderrWriter();210 defer std.debug.unlockStderrWriter();
211 build_runner.printErrorMessages(gpa, &run.step, .{ .ttyconf = fuzz.ttyconf }, w, .verbose, .indent) catch {};211 build_runner.printErrorMessages(gpa, &run.step, .{}, w, fuzz.ttyconf, .verbose, .indent) catch {};
212 return;212 return;
213 },213 },
214 else => {214 else => {
lib/std/Build/Step/Compile.zig+5-6
...@@ -1056,15 +1056,15 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking...@@ -1056,15 +1056,15 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
1056 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);1056 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
10571057
1058 const generated_file = maybe_path orelse {1058 const generated_file = maybe_path orelse {
1059 const w = std.debug.lockStderrWriter(&.{});1059 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1060 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};1060 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
1061 std.debug.unlockStderrWriter();1061 std.debug.unlockStderrWriter();
1062 @panic("missing emit option for " ++ tag_name);1062 @panic("missing emit option for " ++ tag_name);
1063 };1063 };
10641064
1065 const path = generated_file.path orelse {1065 const path = generated_file.path orelse {
1066 const w = std.debug.lockStderrWriter(&.{});1066 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1067 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};1067 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
1068 std.debug.unlockStderrWriter();1068 std.debug.unlockStderrWriter();
1069 @panic(tag_name ++ " is null. Is there a missing step dependency?");1069 @panic(tag_name ++ " is null. Is there a missing step dependency?");
1070 };1070 };
...@@ -2027,10 +2027,9 @@ fn checkCompileErrors(compile: *Compile) !void {...@@ -2027,10 +2027,9 @@ fn checkCompileErrors(compile: *Compile) !void {
2027 var aw: std.Io.Writer.Allocating = .init(arena);2027 var aw: std.Io.Writer.Allocating = .init(arena);
2028 defer aw.deinit();2028 defer aw.deinit();
2029 try actual_eb.renderToWriter(.{2029 try actual_eb.renderToWriter(.{
2030 .ttyconf = .no_color,
2031 .include_reference_trace = false,2030 .include_reference_trace = false,
2032 .include_source_line = false,2031 .include_source_line = false,
2033 }, &aw.writer);2032 }, &aw.writer, .no_color);
2034 break :ae try aw.toOwnedSlice();2033 break :ae try aw.toOwnedSlice();
2035 };2034 };
20362035
lib/std/Build/Step/Run.zig+9-5
...@@ -1587,11 +1587,15 @@ fn spawnChildAndCollect(...@@ -1587,11 +1587,15 @@ fn spawnChildAndCollect(
1587 run.step.test_results = res.test_results;1587 run.step.test_results = res.test_results;
1588 if (res.test_metadata) |tm| {1588 if (res.test_metadata) |tm| {
1589 run.cached_test_metadata = tm.toCachedTestMetadata();1589 run.cached_test_metadata = tm.toCachedTestMetadata();
1590 if (options.web_server) |ws| ws.updateTimeReportRunTest(1590 if (options.web_server) |ws| {
1591 run,1591 if (b.graph.time_report) {
1592 &run.cached_test_metadata.?,1592 ws.updateTimeReportRunTest(
1593 tm.ns_per_test,1593 run,
1594 );1594 &run.cached_test_metadata.?,
1595 tm.ns_per_test,
1596 );
1597 }
1598 }
1595 }1599 }
1596 return null;1600 return null;
1597 } else {1601 } else {
lib/std/Build/WebServer.zig+4-5
...@@ -54,9 +54,9 @@ pub fn notifyUpdate(ws: *WebServer) void {...@@ -54,9 +54,9 @@ pub fn notifyUpdate(ws: *WebServer) void {
54pub const Options = struct {54pub const Options = struct {
55 gpa: Allocator,55 gpa: Allocator,
56 thread_pool: *std.Thread.Pool,56 thread_pool: *std.Thread.Pool,
57 ttyconf: Io.tty.Config,
57 graph: *const std.Build.Graph,58 graph: *const std.Build.Graph,
58 all_steps: []const *Build.Step,59 all_steps: []const *Build.Step,
59 ttyconf: Io.tty.Config,
60 root_prog_node: std.Progress.Node,60 root_prog_node: std.Progress.Node,
61 watch: bool,61 watch: bool,
62 listen_address: net.IpAddress,62 listen_address: net.IpAddress,
...@@ -101,10 +101,10 @@ pub fn init(opts: Options) WebServer {...@@ -101,10 +101,10 @@ pub fn init(opts: Options) WebServer {
101 return .{101 return .{
102 .gpa = opts.gpa,102 .gpa = opts.gpa,
103 .thread_pool = opts.thread_pool,103 .thread_pool = opts.thread_pool,
104 .ttyconf = opts.ttyconf,
104 .graph = opts.graph,105 .graph = opts.graph,
105 .all_steps = all_steps,106 .all_steps = all_steps,
106 .listen_address = opts.listen_address,107 .listen_address = opts.listen_address,
107 .ttyconf = opts.ttyconf,
108 .root_prog_node = opts.root_prog_node,108 .root_prog_node = opts.root_prog_node,
109 .watch = opts.watch,109 .watch = opts.watch,
110110
...@@ -236,9 +236,9 @@ pub fn finishBuild(ws: *WebServer, opts: struct {...@@ -236,9 +236,9 @@ pub fn finishBuild(ws: *WebServer, opts: struct {
236 ws.gpa,236 ws.gpa,
237 ws.graph.io,237 ws.graph.io,
238 ws.thread_pool,238 ws.thread_pool,
239 ws.ttyconf,
239 ws.all_steps,240 ws.all_steps,
240 ws.root_prog_node,241 ws.root_prog_node,
241 ws.ttyconf,
242 .{ .forever = .{ .ws = ws } },242 .{ .forever = .{ .ws = ws } },
243 ) catch |err| std.process.fatal("failed to start fuzzer: {s}", .{@errorName(err)});243 ) catch |err| std.process.fatal("failed to start fuzzer: {s}", .{@errorName(err)});
244 ws.fuzz.?.start();244 ws.fuzz.?.start();
...@@ -655,8 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim...@@ -655,8 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
655 }655 }
656656
657 if (result_error_bundle.errorMessageCount() > 0) {657 if (result_error_bundle.errorMessageCount() > 0) {
658 const color = std.zig.Color.auto;658 result_error_bundle.renderToStdErr(.{}, .auto);
659 result_error_bundle.renderToStdErr(color.renderOptions());
660 log.err("the following command failed with {d} compilation errors:\n{s}", .{659 log.err("the following command failed with {d} compilation errors:\n{s}", .{
661 result_error_bundle.errorMessageCount(),660 result_error_bundle.errorMessageCount(),
662 try Build.Step.allocPrintCmd(arena, null, argv.items),661 try Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/debug.zig+19-19
...@@ -272,7 +272,7 @@ pub fn unlockStdErr() void {...@@ -272,7 +272,7 @@ pub fn unlockStdErr() void {
272 std.Progress.unlockStdErr();272 std.Progress.unlockStdErr();
273}273}
274274
275/// Allows the caller to freely write to stderr until `unlockStdErr` is called.275/// Allows the caller to freely write to stderr until `unlockStderrWriter` is called.
276///276///
277/// During the lock, any `std.Progress` information is cleared from the terminal.277/// During the lock, any `std.Progress` information is cleared from the terminal.
278///278///
...@@ -282,8 +282,16 @@ pub fn unlockStdErr() void {...@@ -282,8 +282,16 @@ pub fn unlockStdErr() void {
282///282///
283/// The returned `Writer` does not need to be manually flushed: flushing is performed automatically283/// The returned `Writer` does not need to be manually flushed: flushing is performed automatically
284/// when the matching `unlockStderrWriter` call occurs.284/// when the matching `unlockStderrWriter` call occurs.
285pub fn lockStderrWriter(buffer: []u8) *Writer {285pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } {
286 return std.Progress.lockStderrWriter(buffer);286 const global = struct {
287 var conf: ?tty.Config = null;
288 };
289 const w = std.Progress.lockStderrWriter(buffer);
290 // The stderr lock also locks access to `global.conf`.
291 if (global.conf == null) {
292 global.conf = .detect(.stderr());
293 }
294 return .{ w, global.conf.? };
287}295}
288296
289pub fn unlockStderrWriter() void {297pub fn unlockStderrWriter() void {
...@@ -297,7 +305,7 @@ pub fn unlockStderrWriter() void {...@@ -297,7 +305,7 @@ pub fn unlockStderrWriter() void {
297/// function returns.305/// function returns.
298pub fn print(comptime fmt: []const u8, args: anytype) void {306pub fn print(comptime fmt: []const u8, args: anytype) void {
299 var buffer: [64]u8 = undefined;307 var buffer: [64]u8 = undefined;
300 const bw = lockStderrWriter(&buffer);308 const bw, _ = lockStderrWriter(&buffer);
301 defer unlockStderrWriter();309 defer unlockStderrWriter();
302 nosuspend bw.print(fmt, args) catch return;310 nosuspend bw.print(fmt, args) catch return;
303}311}
...@@ -314,9 +322,8 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {...@@ -314,9 +322,8 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {
314/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.322/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
315/// Obtains the stderr mutex while dumping.323/// Obtains the stderr mutex while dumping.
316pub fn dumpHex(bytes: []const u8) void {324pub fn dumpHex(bytes: []const u8) void {
317 const bw = lockStderrWriter(&.{});325 const bw, const ttyconf = lockStderrWriter(&.{});
318 defer unlockStderrWriter();326 defer unlockStderrWriter();
319 const ttyconf = tty.detectConfig(.stderr());
320 dumpHexFallible(bw, ttyconf, bytes) catch {};327 dumpHexFallible(bw, ttyconf, bytes) catch {};
321}328}
322329
...@@ -538,9 +545,7 @@ pub fn defaultPanic(...@@ -538,9 +545,7 @@ pub fn defaultPanic(
538 _ = panicking.fetchAdd(1, .seq_cst);545 _ = panicking.fetchAdd(1, .seq_cst);
539546
540 trace: {547 trace: {
541 const tty_config = tty.detectConfig(.stderr());548 const stderr, const tty_config = lockStderrWriter(&.{});
542
543 const stderr = lockStderrWriter(&.{});
544 defer unlockStderrWriter();549 defer unlockStderrWriter();
545550
546 if (builtin.single_threaded) {551 if (builtin.single_threaded) {
...@@ -743,8 +748,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri...@@ -743,8 +748,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri
743}748}
744/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.749/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.
745pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {750pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
746 const tty_config = tty.detectConfig(.stderr());751 const stderr, const tty_config = lockStderrWriter(&.{});
747 const stderr = lockStderrWriter(&.{});
748 defer unlockStderrWriter();752 defer unlockStderrWriter();
749 writeCurrentStackTrace(.{753 writeCurrentStackTrace(.{
750 .first_address = a: {754 .first_address = a: {
...@@ -809,8 +813,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C...@@ -809,8 +813,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C
809}813}
810/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.814/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.
811pub fn dumpStackTrace(st: *const StackTrace) void {815pub fn dumpStackTrace(st: *const StackTrace) void {
812 const tty_config = tty.detectConfig(.stderr());816 const stderr, const tty_config = lockStderrWriter(&.{});
813 const stderr = lockStderrWriter(&.{});
814 defer unlockStderrWriter();817 defer unlockStderrWriter();
815 writeStackTrace(st, stderr, tty_config) catch |err| switch (err) {818 writeStackTrace(st, stderr, tty_config) catch |err| switch (err) {
816 error.WriteFailed => {},819 error.WriteFailed => {},
...@@ -1552,9 +1555,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex...@@ -1552,9 +1555,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
1552 _ = panicking.fetchAdd(1, .seq_cst);1555 _ = panicking.fetchAdd(1, .seq_cst);
15531556
1554 trace: {1557 trace: {
1555 const tty_config = tty.detectConfig(.stderr());1558 const stderr, const tty_config = lockStderrWriter(&.{});
1556
1557 const stderr = lockStderrWriter(&.{});
1558 defer unlockStderrWriter();1559 defer unlockStderrWriter();
15591560
1560 if (addr) |a| {1561 if (addr) |a| {
...@@ -1612,7 +1613,7 @@ test "manage resources correctly" {...@@ -1612,7 +1613,7 @@ test "manage resources correctly" {
1612 &di,1613 &di,
1613 &discarding.writer,1614 &discarding.writer,
1614 S.showMyTrace(),1615 S.showMyTrace(),
1615 tty.detectConfig(.stderr()),1616 .no_color,
1616 );1617 );
1617}1618}
16181619
...@@ -1674,8 +1675,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize...@@ -1674,8 +1675,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
1674 pub fn dump(t: @This()) void {1675 pub fn dump(t: @This()) void {
1675 if (!enabled) return;1676 if (!enabled) return;
16761677
1677 const tty_config = tty.detectConfig(.stderr());1678 const stderr, const tty_config = lockStderrWriter(&.{});
1678 const stderr = lockStderrWriter(&.{});
1679 defer unlockStderrWriter();1679 defer unlockStderrWriter();
1680 const end = @min(t.index, size);1680 const end = @min(t.index, size);
1681 for (t.addrs[0..end], 0..) |frames_array, i| {1681 for (t.addrs[0..end], 0..) |frames_array, i| {
lib/std/json/dynamic.zig+1-1
...@@ -47,7 +47,7 @@ pub const Value = union(enum) {...@@ -47,7 +47,7 @@ pub const Value = union(enum) {
47 }47 }
4848
49 pub fn dump(v: Value) void {49 pub fn dump(v: Value) void {
50 const w = std.debug.lockStderrWriter(&.{});50 const w, _ = std.debug.lockStderrWriter(&.{});
51 defer std.debug.unlockStderrWriter();51 defer std.debug.unlockStderrWriter();
5252
53 json.Stringify.value(v, .{}, w) catch return;53 json.Stringify.value(v, .{}, w) catch return;
lib/std/log.zig+34-77
...@@ -13,63 +13,15 @@...@@ -13,63 +13,15 @@
13//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its13//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its
14//! log messages.14//! log messages.
15//!15//!
16//! An example `logFn` might look something like this:16//! For an example implementation of the `logFn` function, see `defaultLog`,
17//!17//! which is the default implementation. It outputs to stderr, using color if
18//! ```18//! the detected `std.Io.tty.Config` supports it. Its output looks like this:
19//! const std = @import("std");
20//!
21//! pub const std_options: std.Options = .{
22//! // Set the log level to info
23//! .log_level = .info,
24//!
25//! // Define logFn to override the std implementation
26//! .logFn = myLogFn,
27//! };
28//!
29//! pub fn myLogFn(
30//! comptime level: std.log.Level,
31//! comptime scope: @Type(.enum_literal),
32//! comptime format: []const u8,
33//! args: anytype,
34//! ) void {
35//! // Ignore all non-error logging from sources other than
36//! // .my_project, .nice_library and the default
37//! const scope_prefix = "(" ++ switch (scope) {
38//! .my_project, .nice_library, std.log.default_log_scope => @tagName(scope),
39//! else => if (@intFromEnum(level) <= @intFromEnum(std.log.Level.err))
40//! @tagName(scope)
41//! else
42//! return,
43//! } ++ "): ";
44//!
45//! const prefix = "[" ++ comptime level.asText() ++ "] " ++ scope_prefix;
46//!
47//! // Print the message to stderr, silently ignoring any errors
48//! std.debug.lockStdErr();
49//! defer std.debug.unlockStdErr();
50//! var stderr = std.fs.File.stderr().writer(&.{});
51//! nosuspend stderr.interface.print(prefix ++ format ++ "\n", args) catch return;
52//! }
53//!
54//! pub fn main() void {
55//! // Using the default scope:
56//! std.log.debug("A borderline useless debug log message", .{}); // Won't be printed as log_level is .info
57//! std.log.info("Flux capacitor is starting to overheat", .{});
58//!
59//! // Using scoped logging:
60//! const my_project_log = std.log.scoped(.my_project);
61//! const nice_library_log = std.log.scoped(.nice_library);
62//! const verbose_lib_log = std.log.scoped(.verbose_lib);
63//!
64//! my_project_log.debug("Starting up", .{}); // Won't be printed as log_level is .info
65//! nice_library_log.warn("Something went very wrong, sorry", .{});
66//! verbose_lib_log.warn("Added 1 + 1: {}", .{1 + 1}); // Won't be printed as it gets filtered out by our log function
67//! }
68//! ```19//! ```
69//! Which produces the following output:20//! error: this is an error
70//! ```21//! error(scope): this is an error with a non-default scope
71//! [info] (default): Flux capacitor is starting to overheat22//! warning: this is a warning
72//! [warning] (nice_library): Something went very wrong, sorry23//! info: this is an informative message
24//! debug: this is a debugging message
73//! ```25//! ```
7426
75const std = @import("std.zig");27const std = @import("std.zig");
...@@ -104,37 +56,28 @@ pub const default_level: Level = switch (builtin.mode) {...@@ -104,37 +56,28 @@ pub const default_level: Level = switch (builtin.mode) {
104 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .info,56 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .info,
105};57};
10658
107const level = std.options.log_level;
108
109pub const ScopeLevel = struct {59pub const ScopeLevel = struct {
110 scope: @Type(.enum_literal),60 scope: @Type(.enum_literal),
111 level: Level,61 level: Level,
112};62};
11363
114const scope_levels = std.options.log_scope_levels;
115
116fn log(64fn log(
117 comptime message_level: Level,65 comptime level: Level,
118 comptime scope: @Type(.enum_literal),66 comptime scope: @Type(.enum_literal),
119 comptime format: []const u8,67 comptime format: []const u8,
120 args: anytype,68 args: anytype,
121) void {69) void {
122 if (comptime !logEnabled(message_level, scope)) return;70 if (comptime !logEnabled(level, scope)) return;
12371
124 std.options.logFn(message_level, scope, format, args);72 std.options.logFn(level, scope, format, args);
125}73}
12674
127/// Determine if a specific log message level and scope combination are enabled for logging.75/// Determine if a specific log message level and scope combination are enabled for logging.
128pub fn logEnabled(comptime message_level: Level, comptime scope: @Type(.enum_literal)) bool {76pub fn logEnabled(comptime level: Level, comptime scope: @Type(.enum_literal)) bool {
129 inline for (scope_levels) |scope_level| {77 inline for (std.options.log_scope_levels) |scope_level| {
130 if (scope_level.scope == scope) return @intFromEnum(message_level) <= @intFromEnum(scope_level.level);78 if (scope_level.scope == scope) return @intFromEnum(level) <= @intFromEnum(scope_level.level);
131 }79 }
132 return @intFromEnum(message_level) <= @intFromEnum(level);80 return @intFromEnum(level) <= @intFromEnum(std.options.log_level);
133}
134
135/// Determine if a specific log message level using the default log scope is enabled for logging.
136pub fn defaultLogEnabled(comptime message_level: Level) bool {
137 return comptime logEnabled(message_level, default_log_scope);
138}81}
13982
140/// The default implementation for the log function. Custom log functions may83/// The default implementation for the log function. Custom log functions may
...@@ -143,17 +86,31 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {...@@ -143,17 +86,31 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
143/// Uses a 64-byte buffer for formatted printing which is flushed before this86/// Uses a 64-byte buffer for formatted printing which is flushed before this
144/// function returns.87/// function returns.
145pub fn defaultLog(88pub fn defaultLog(
146 comptime message_level: Level,89 comptime level: Level,
147 comptime scope: @Type(.enum_literal),90 comptime scope: @Type(.enum_literal),
148 comptime format: []const u8,91 comptime format: []const u8,
149 args: anytype,92 args: anytype,
150) void {93) void {
151 const level_txt = comptime message_level.asText();
152 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
153 var buffer: [64]u8 = undefined;94 var buffer: [64]u8 = undefined;
154 const stderr = std.debug.lockStderrWriter(&buffer);95 const stderr, const ttyconf = std.debug.lockStderrWriter(&buffer);
155 defer std.debug.unlockStderrWriter();96 defer std.debug.unlockStderrWriter();
156 nosuspend stderr.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return;97 ttyconf.setColor(stderr, switch (level) {
98 .err => .red,
99 .warn => .yellow,
100 .info => .green,
101 .debug => .magenta,
102 }) catch {};
103 ttyconf.setColor(stderr, .bold) catch {};
104 stderr.writeAll(level.asText()) catch return;
105 ttyconf.setColor(stderr, .reset) catch {};
106 ttyconf.setColor(stderr, .dim) catch {};
107 ttyconf.setColor(stderr, .bold) catch {};
108 if (scope != .default) {
109 stderr.print("({s})", .{@tagName(scope)}) catch return;
110 }
111 stderr.writeAll(": ") catch return;
112 ttyconf.setColor(stderr, .reset) catch {};
113 stderr.print(format ++ "\n", args) catch return;
157}114}
158115
159/// Returns a scoped logging namespace that logs all messages using the scope116/// Returns a scoped logging namespace that logs all messages using the scope
lib/std/testing.zig+4-4
...@@ -355,7 +355,7 @@ test expectApproxEqRel {...@@ -355,7 +355,7 @@ test expectApproxEqRel {
355/// This function is intended to be used only in tests. When the two slices are not355/// This function is intended to be used only in tests. When the two slices are not
356/// equal, prints diagnostics to stderr to show exactly how they are not equal (with356/// equal, prints diagnostics to stderr to show exactly how they are not equal (with
357/// the differences highlighted in red), then returns a test failure error.357/// the differences highlighted in red), then returns a test failure error.
358/// The colorized output is optional and controlled by the return of `std.Io.tty.detectConfig()`.358/// The colorized output is optional and controlled by the return of `std.Io.tty.Config.detect`.
359/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.359/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
360pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {360pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
361 const diff_index: usize = diff_index: {361 const diff_index: usize = diff_index: {
...@@ -367,9 +367,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const...@@ -367,9 +367,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
367 break :diff_index if (expected.len == actual.len) return else shortest;367 break :diff_index if (expected.len == actual.len) return else shortest;
368 };368 };
369 if (!backend_can_print) return error.TestExpectedEqual;369 if (!backend_can_print) return error.TestExpectedEqual;
370 const stderr_w = std.debug.lockStderrWriter(&.{});370 const stderr_w, const ttyconf = std.debug.lockStderrWriter(&.{});
371 defer std.debug.unlockStderrWriter();371 defer std.debug.unlockStderrWriter();
372 failEqualSlices(T, expected, actual, diff_index, stderr_w) catch {};372 failEqualSlices(T, expected, actual, diff_index, stderr_w, ttyconf) catch {};
373 return error.TestExpectedEqual;373 return error.TestExpectedEqual;
374}374}
375375
...@@ -379,6 +379,7 @@ fn failEqualSlices(...@@ -379,6 +379,7 @@ fn failEqualSlices(
379 actual: []const T,379 actual: []const T,
380 diff_index: usize,380 diff_index: usize,
381 w: *std.Io.Writer,381 w: *std.Io.Writer,
382 ttyconf: std.Io.tty.Config,
382) !void {383) !void {
383 try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });384 try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
384385
...@@ -398,7 +399,6 @@ fn failEqualSlices(...@@ -398,7 +399,6 @@ fn failEqualSlices(
398 const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];399 const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
399 const actual_truncated = window_start + actual_window.len < actual.len;400 const actual_truncated = window_start + actual_window.len < actual.len;
400401
401 const ttyconf = std.Io.tty.detectConfig(.stderr());
402 var differ = if (T == u8) BytesDiffer{402 var differ = if (T == u8) BytesDiffer{
403 .expected = expected_window,403 .expected = expected_window,
404 .actual = actual_window,404 .actual = actual_window,
lib/std/zig.zig+8-7
...@@ -53,17 +53,18 @@ pub const Color = enum {...@@ -53,17 +53,18 @@ pub const Color = enum {
53 /// Assume stderr is a terminal.53 /// Assume stderr is a terminal.
54 on,54 on,
5555
56 pub fn get_tty_conf(color: Color) Io.tty.Config {56 pub fn getTtyConf(color: Color, detected: Io.tty.Config) Io.tty.Config {
57 return switch (color) {57 return switch (color) {
58 .auto => Io.tty.detectConfig(std.fs.File.stderr()),58 .auto => detected,
59 .on => .escape_codes,59 .on => .escape_codes,
60 .off => .no_color,60 .off => .no_color,
61 };61 };
62 }62 }
6363 pub fn detectTtyConf(color: Color) Io.tty.Config {
64 pub fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions {64 return switch (color) {
65 return .{65 .auto => .detect(.stderr()),
66 .ttyconf = get_tty_conf(color),66 .on => .escape_codes,
67 .off => .no_color,
67 };68 };
68 }69 }
69};70};
...@@ -606,7 +607,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color...@@ -606,7 +607,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color
606607
607 var error_bundle = try wip_errors.toOwnedBundle("");608 var error_bundle = try wip_errors.toOwnedBundle("");
608 defer error_bundle.deinit(gpa);609 defer error_bundle.deinit(gpa);
609 error_bundle.renderToStdErr(color.renderOptions());610 error_bundle.renderToStdErr(.{}, color);
610}611}
611612
612pub fn putAstErrorsIntoBundle(613pub fn putAstErrorsIntoBundle(
lib/std/zig/ErrorBundle.zig+8-9
...@@ -157,23 +157,22 @@ pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {...@@ -157,23 +157,22 @@ pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {
157}157}
158158
159pub const RenderOptions = struct {159pub const RenderOptions = struct {
160 ttyconf: Io.tty.Config,
161 include_reference_trace: bool = true,160 include_reference_trace: bool = true,
162 include_source_line: bool = true,161 include_source_line: bool = true,
163 include_log_text: bool = true,162 include_log_text: bool = true,
164};163};
165164
166pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {165pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void {
167 var buffer: [256]u8 = undefined;166 var buffer: [256]u8 = undefined;
168 const w = std.debug.lockStderrWriter(&buffer);167 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
169 defer std.debug.unlockStderrWriter();168 defer std.debug.unlockStderrWriter();
170 renderToWriter(eb, options, w) catch return;169 renderToWriter(eb, options, w, color.getTtyConf(ttyconf)) catch return;
171}170}
172171
173pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer) (Writer.Error || std.posix.UnexpectedError)!void {172pub fn renderToWriter(eb: ErrorBundle, options: RenderOptions, w: *Writer, ttyconf: Io.tty.Config) (Writer.Error || std.posix.UnexpectedError)!void {
174 if (eb.extra.len == 0) return;173 if (eb.extra.len == 0) return;
175 for (eb.getMessages()) |err_msg| {174 for (eb.getMessages()) |err_msg| {
176 try renderErrorMessageToWriter(eb, options, err_msg, w, "error", .red, 0);175 try renderErrorMessageToWriter(eb, options, err_msg, w, ttyconf, "error", .red, 0);
177 }176 }
178177
179 if (options.include_log_text) {178 if (options.include_log_text) {
...@@ -190,11 +189,11 @@ fn renderErrorMessageToWriter(...@@ -190,11 +189,11 @@ fn renderErrorMessageToWriter(
190 options: RenderOptions,189 options: RenderOptions,
191 err_msg_index: MessageIndex,190 err_msg_index: MessageIndex,
192 w: *Writer,191 w: *Writer,
192 ttyconf: Io.tty.Config,
193 kind: []const u8,193 kind: []const u8,
194 color: Io.tty.Color,194 color: Io.tty.Color,
195 indent: usize,195 indent: usize,
196) (Writer.Error || std.posix.UnexpectedError)!void {196) (Writer.Error || std.posix.UnexpectedError)!void {
197 const ttyconf = options.ttyconf;
198 const err_msg = eb.getErrorMessage(err_msg_index);197 const err_msg = eb.getErrorMessage(err_msg_index);
199 if (err_msg.src_loc != .none) {198 if (err_msg.src_loc != .none) {
200 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));199 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
...@@ -251,7 +250,7 @@ fn renderErrorMessageToWriter(...@@ -251,7 +250,7 @@ fn renderErrorMessageToWriter(
251 try ttyconf.setColor(w, .reset);250 try ttyconf.setColor(w, .reset);
252 }251 }
253 for (eb.getNotes(err_msg_index)) |note| {252 for (eb.getNotes(err_msg_index)) |note| {
254 try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent);253 try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent);
255 }254 }
256 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {255 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
257 try ttyconf.setColor(w, .reset);256 try ttyconf.setColor(w, .reset);
...@@ -300,7 +299,7 @@ fn renderErrorMessageToWriter(...@@ -300,7 +299,7 @@ fn renderErrorMessageToWriter(
300 }299 }
301 try ttyconf.setColor(w, .reset);300 try ttyconf.setColor(w, .reset);
302 for (eb.getNotes(err_msg_index)) |note| {301 for (eb.getNotes(err_msg_index)) |note| {
303 try renderErrorMessageToWriter(eb, options, note, w, "note", .cyan, indent + 4);302 try renderErrorMessageToWriter(eb, options, note, w, ttyconf, "note", .cyan, indent + 4);
304 }303 }
305 }304 }
306}305}
lib/std/zig/parser_test.zig+1-1
...@@ -6386,7 +6386,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;...@@ -6386,7 +6386,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
63866386
6387fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {6387fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
6388 var buffer: [64]u8 = undefined;6388 var buffer: [64]u8 = undefined;
6389 const stderr = std.debug.lockStderrWriter(&buffer);6389 const stderr, _ = std.debug.lockStderrWriter(&buffer);
6390 defer std.debug.unlockStderrWriter();6390 defer std.debug.unlockStderrWriter();
63916391
6392 var tree = try std.zig.Ast.parse(allocator, source, .zig);6392 var tree = try std.zig.Ast.parse(allocator, source, .zig);
src/Air/print.zig+2-2
...@@ -73,13 +73,13 @@ pub fn writeInst(...@@ -73,13 +73,13 @@ pub fn writeInst(
73}73}
7474
75pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {75pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
76 const stderr_bw = std.debug.lockStderrWriter(&.{});76 const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
77 defer std.debug.unlockStderrWriter();77 defer std.debug.unlockStderrWriter();
78 air.write(stderr_bw, pt, liveness);78 air.write(stderr_bw, pt, liveness);
79}79}
8080
81pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {81pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
82 const stderr_bw = std.debug.lockStderrWriter(&.{});82 const stderr_bw, _ = std.debug.lockStderrWriter(&.{});
83 defer std.debug.unlockStderrWriter();83 defer std.debug.unlockStderrWriter();
84 air.writeInst(stderr_bw, inst, pt, liveness);84 air.writeInst(stderr_bw, inst, pt, liveness);
85}85}
src/Compilation.zig+3-3
...@@ -2093,7 +2093,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2093,7 +2093,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
20932093
2094 if (options.verbose_llvm_cpu_features) {2094 if (options.verbose_llvm_cpu_features) {
2095 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {2095 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
2096 const stderr_w = std.debug.lockStderrWriter(&.{});2096 const stderr_w, _ = std.debug.lockStderrWriter(&.{});
2097 defer std.debug.unlockStderrWriter();2097 defer std.debug.unlockStderrWriter();
2098 stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print;2098 stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print;
2099 stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;2099 stderr_w.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;
...@@ -4270,7 +4270,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {...@@ -4270,7 +4270,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
4270 // However, we haven't reported any such error.4270 // However, we haven't reported any such error.
4271 // This is a compiler bug.4271 // This is a compiler bug.
4272 print_ctx: {4272 print_ctx: {
4273 var stderr_w = std.debug.lockStderrWriter(&.{});4273 var stderr_w, _ = std.debug.lockStderrWriter(&.{});
4274 defer std.debug.unlockStderrWriter();4274 defer std.debug.unlockStderrWriter();
4275 stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;4275 stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;
4276 stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;4276 stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;
...@@ -7752,7 +7752,7 @@ pub fn lockAndSetMiscFailure(...@@ -7752,7 +7752,7 @@ pub fn lockAndSetMiscFailure(
77527752
7753pub fn dump_argv(argv: []const []const u8) void {7753pub fn dump_argv(argv: []const []const u8) void {
7754 var buffer: [64]u8 = undefined;7754 var buffer: [64]u8 = undefined;
7755 const stderr = std.debug.lockStderrWriter(&buffer);7755 const stderr, _ = std.debug.lockStderrWriter(&buffer);
7756 defer std.debug.unlockStderrWriter();7756 defer std.debug.unlockStderrWriter();
7757 nosuspend {7757 nosuspend {
7758 for (argv, 0..) |arg, i| {7758 for (argv, 0..) |arg, i| {
src/InternPool.zig+2-2
...@@ -11330,7 +11330,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -11330,7 +11330,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1133011330
11331fn dumpAllFallible(ip: *const InternPool) anyerror!void {11331fn dumpAllFallible(ip: *const InternPool) anyerror!void {
11332 var buffer: [4096]u8 = undefined;11332 var buffer: [4096]u8 = undefined;
11333 const stderr_bw = std.debug.lockStderrWriter(&buffer);11333 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
11334 defer std.debug.unlockStderrWriter();11334 defer std.debug.unlockStderrWriter();
11335 for (ip.locals, 0..) |*local, tid| {11335 for (ip.locals, 0..) |*local, tid| {
11336 const items = local.shared.items.view();11336 const items = local.shared.items.view();
...@@ -11462,7 +11462,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -11462,7 +11462,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
11462 }11462 }
1146311463
11464 var buffer: [4096]u8 = undefined;11464 var buffer: [4096]u8 = undefined;
11465 const stderr_bw = std.debug.lockStderrWriter(&buffer);11465 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
11466 defer std.debug.unlockStderrWriter();11466 defer std.debug.unlockStderrWriter();
1146711467
11468 const SortContext = struct {11468 const SortContext = struct {
src/Package/Fetch.zig+2-2
...@@ -2043,7 +2043,7 @@ const UnpackResult = struct {...@@ -2043,7 +2043,7 @@ const UnpackResult = struct {
2043 defer errors.deinit(gpa);2043 defer errors.deinit(gpa);
2044 var aw: Io.Writer.Allocating = .init(gpa);2044 var aw: Io.Writer.Allocating = .init(gpa);
2045 defer aw.deinit();2045 defer aw.deinit();
2046 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);2046 try errors.renderToWriter(.{}, &aw.writer, .no_color);
2047 try std.testing.expectEqualStrings(2047 try std.testing.expectEqualStrings(
2048 \\error: unable to unpack2048 \\error: unable to unpack
2049 \\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError2049 \\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError
...@@ -2360,7 +2360,7 @@ const TestFetchBuilder = struct {...@@ -2360,7 +2360,7 @@ const TestFetchBuilder = struct {
2360 }2360 }
2361 var aw: Io.Writer.Allocating = .init(std.testing.allocator);2361 var aw: Io.Writer.Allocating = .init(std.testing.allocator);
2362 defer aw.deinit();2362 defer aw.deinit();
2363 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);2363 try errors.renderToWriter(.{}, &aw.writer, .no_color);
2364 try std.testing.expectEqualStrings(msg, aw.written());2364 try std.testing.expectEqualStrings(msg, aw.written());
2365 }2365 }
2366};2366};
src/Sema.zig+1-1
...@@ -2631,7 +2631,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg...@@ -2631,7 +2631,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
2631 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");2631 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
2632 std.debug.print("compile error during Sema:\n", .{});2632 std.debug.print("compile error during Sema:\n", .{});
2633 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");2633 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
2634 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });2634 error_bundle.renderToStdErr(.{}, .auto);
2635 std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{});2635 std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{});
2636 }2636 }
26372637
src/Zcu/PerThread.zig+1-1
...@@ -4473,7 +4473,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e...@@ -4473,7 +4473,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
4473 defer if (liveness) |*l| l.deinit(gpa);4473 defer if (liveness) |*l| l.deinit(gpa);
44744474
4475 if (build_options.enable_debug_extensions and comp.verbose_air) {4475 if (build_options.enable_debug_extensions and comp.verbose_air) {
4476 const stderr = std.debug.lockStderrWriter(&.{});4476 const stderr, _ = std.debug.lockStderrWriter(&.{});
4477 defer std.debug.unlockStderrWriter();4477 defer std.debug.unlockStderrWriter();
4478 stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};4478 stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
4479 air.write(stderr, pt, liveness);4479 air.write(stderr, pt, liveness);
src/codegen/aarch64/Disassemble.zig+34-6
...@@ -74,10 +74,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr...@@ -74,10 +74,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
74 dis.operands_separator,74 dis.operands_separator,
75 imm12,75 imm12,
76 });76 });
77 return if (!elide_shift) writer.print("{s}{f} #{s}", .{77 return if (!elide_shift) writer.print("{s}{f} #{t}", .{
78 dis.operands_separator,78 dis.operands_separator,
79 fmtCase(.lsl, dis.case),79 fmtCase(.lsl, dis.case),
80 @tagName(sh),80 sh,
81 });81 });
82 },82 },
83 .add_subtract_immediate_with_tags => |add_subtract_immediate_with_tags| {83 .add_subtract_immediate_with_tags => |add_subtract_immediate_with_tags| {
...@@ -176,10 +176,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr...@@ -176,10 +176,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
176 dis.operands_separator,176 dis.operands_separator,
177 imm16,177 imm16,
178 });178 });
179 return if (!elide_shift) writer.print("{s}{f} #{s}", .{179 return if (!elide_shift) writer.print("{s}{f} #{t}", .{
180 dis.operands_separator,180 dis.operands_separator,
181 fmtCase(.lsl, dis.case),181 fmtCase(.lsl, dis.case),
182 @tagName(hw),182 hw,
183 });183 });
184 },184 },
185 .bitfield => |bitfield| {185 .bitfield => |bitfield| {
...@@ -833,8 +833,36 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr...@@ -833,8 +833,36 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
833 },833 },
834 .rotate_right_into_flags => {},834 .rotate_right_into_flags => {},
835 .evaluate_into_flags => {},835 .evaluate_into_flags => {},
836 .conditional_compare_register => {},836 .conditional_compare_register => |conditional_compare_register| {
837 .conditional_compare_immediate => {},837 const group = conditional_compare_register.group;
838 const sf = group.sf;
839 return writer.print("{f}{s}{f}{s}{f}{s}#0x{x}{s}{f}", .{
840 fmtCase(group.op, dis.case),
841 dis.mnemonic_operands_separator,
842 group.Rn.decode(.{}).general(sf).fmtCase(dis.case),
843 dis.operands_separator,
844 group.Rm.decode(.{}).general(sf).fmtCase(dis.case),
845 dis.operands_separator,
846 @as(u4, @bitCast(group.nzcv)),
847 dis.operands_separator,
848 fmtCase(group.cond, dis.case),
849 });
850 },
851 .conditional_compare_immediate => |conditional_compare_immediate| {
852 const group = conditional_compare_immediate.group;
853 const sf = group.sf;
854 return writer.print("{f}{s}{f}{s}#0x{x}{s}#0x{x}{s}{f}", .{
855 fmtCase(group.op, dis.case),
856 dis.mnemonic_operands_separator,
857 group.Rn.decode(.{}).general(sf).fmtCase(dis.case),
858 dis.operands_separator,
859 group.imm5,
860 dis.operands_separator,
861 @as(u4, @bitCast(group.nzcv)),
862 dis.operands_separator,
863 fmtCase(group.cond, dis.case),
864 });
865 },
838 .conditional_select => |conditional_select| {866 .conditional_select => |conditional_select| {
839 const decoded = conditional_select.decode();867 const decoded = conditional_select.decode();
840 if (decoded == .unallocated) break :unallocated;868 if (decoded == .unallocated) break :unallocated;
src/codegen/aarch64/Mir.zig+61-19
...@@ -107,6 +107,7 @@ pub fn emit(...@@ -107,6 +107,7 @@ pub fn emit(
107 mir.body[nav_reloc.reloc.label],107 mir.body[nav_reloc.reloc.label],
108 body_end - Instruction.size * (1 + nav_reloc.reloc.label),108 body_end - Instruction.size * (1 + nav_reloc.reloc.label),
109 nav_reloc.reloc.addend,109 nav_reloc.reloc.addend,
110 if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
110 );111 );
111 for (mir.uav_relocs) |uav_reloc| try emitReloc(112 for (mir.uav_relocs) |uav_reloc| try emitReloc(
112 lf,113 lf,
...@@ -124,6 +125,7 @@ pub fn emit(...@@ -124,6 +125,7 @@ pub fn emit(
124 mir.body[uav_reloc.reloc.label],125 mir.body[uav_reloc.reloc.label],
125 body_end - Instruction.size * (1 + uav_reloc.reloc.label),126 body_end - Instruction.size * (1 + uav_reloc.reloc.label),
126 uav_reloc.reloc.addend,127 uav_reloc.reloc.addend,
128 .direct,
127 );129 );
128 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(130 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
129 lf,131 lf,
...@@ -136,10 +138,11 @@ pub fn emit(...@@ -136,10 +138,11 @@ pub fn emit(
136 mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|138 mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
137 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})139 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
138 else140 else
139 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),141 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {t}", .{lf.tag}),
140 mir.body[lazy_reloc.reloc.label],142 mir.body[lazy_reloc.reloc.label],
141 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),143 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
142 lazy_reloc.reloc.addend,144 lazy_reloc.reloc.addend,
145 .direct,
143 );146 );
144 for (mir.global_relocs) |global_reloc| try emitReloc(147 for (mir.global_relocs) |global_reloc| try emitReloc(
145 lf,148 lf,
...@@ -150,10 +153,11 @@ pub fn emit(...@@ -150,10 +153,11 @@ pub fn emit(
150 else if (lf.cast(.macho)) |mf|153 else if (lf.cast(.macho)) |mf|
151 try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)154 try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
152 else155 else
153 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),156 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {t}", .{lf.tag}),
154 mir.body[global_reloc.reloc.label],157 mir.body[global_reloc.reloc.label],
155 body_end - Instruction.size * (1 + global_reloc.reloc.label),158 body_end - Instruction.size * (1 + global_reloc.reloc.label),
156 global_reloc.reloc.addend,159 global_reloc.reloc.addend,
160 .direct,
157 );161 );
158 const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);162 const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
159 for (mir.literal_relocs) |literal_reloc| {163 for (mir.literal_relocs) |literal_reloc| {
...@@ -188,6 +192,7 @@ fn emitReloc(...@@ -188,6 +192,7 @@ fn emitReloc(
188 instruction: Instruction,192 instruction: Instruction,
189 offset: u32,193 offset: u32,
190 addend: u64,194 addend: u64,
195 kind: enum { direct, got_load },
191) !void {196) !void {
192 const gpa = zcu.gpa;197 const gpa = zcu.gpa;
193 switch (instruction.decode()) {198 switch (instruction.decode()) {
...@@ -198,11 +203,20 @@ fn emitReloc(...@@ -198,11 +203,20 @@ fn emitReloc(
198 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {203 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
199 else => unreachable,204 else => unreachable,
200 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {205 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
201 .adr => .ADR_PREL_LO21,206 .adr => switch (kind) {
202 .adrp => .ADR_PREL_PG_HI21,207 .direct => .ADR_PREL_LO21,
208 .got_load => unreachable,
209 },
210 .adrp => switch (kind) {
211 .direct => .ADR_PREL_PG_HI21,
212 .got_load => .ADR_GOT_PAGE,
213 },
203 },214 },
204 .add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {215 .add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {
205 .add => .ADD_ABS_LO12_NC,216 .add => switch (kind) {
217 .direct => .ADD_ABS_LO12_NC,
218 .got_load => unreachable,
219 },
206 .sub => unreachable,220 .sub => unreachable,
207 },221 },
208 };222 };
...@@ -223,7 +237,10 @@ fn emitReloc(...@@ -223,7 +237,10 @@ fn emitReloc(
223 .offset = offset,237 .offset = offset,
224 .target = sym_index,238 .target = sym_index,
225 .addend = @bitCast(addend),239 .addend = @bitCast(addend),
226 .type = .page,240 .type = switch (kind) {
241 .direct => .page,
242 .got_load => .got_load_page,
243 },
227 .meta = .{244 .meta = .{
228 .pcrel = true,245 .pcrel = true,
229 .has_subtractor = false,246 .has_subtractor = false,
...@@ -238,7 +255,10 @@ fn emitReloc(...@@ -238,7 +255,10 @@ fn emitReloc(
238 .offset = offset,255 .offset = offset,
239 .target = sym_index,256 .target = sym_index,
240 .addend = @bitCast(addend),257 .addend = @bitCast(addend),
241 .type = .pageoff,258 .type = switch (kind) {
259 .direct => .pageoff,
260 .got_load => .got_load_pageoff,
261 },
242 .meta = .{262 .meta = .{
243 .pcrel = false,263 .pcrel = false,
244 .has_subtractor = false,264 .has_subtractor = false,
...@@ -285,20 +305,39 @@ fn emitReloc(...@@ -285,20 +305,39 @@ fn emitReloc(
285 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {305 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
286 .integer => |integer| switch (integer.decode()) {306 .integer => |integer| switch (integer.decode()) {
287 .unallocated, .prfm => unreachable,307 .unallocated, .prfm => unreachable,
288 .strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,308 .strb, .ldrb, .ldrsb => switch (kind) {
289 .strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,309 .direct => .LDST8_ABS_LO12_NC,
290 .ldrsw => .LDST32_ABS_LO12_NC,310 .got_load => unreachable,
291 inline .str, .ldr => |encoded| switch (encoded.sf) {311 },
312 .strh, .ldrh, .ldrsh => switch (kind) {
313 .direct => .LDST16_ABS_LO12_NC,
314 .got_load => unreachable,
315 },
316 .ldrsw => switch (kind) {
317 .direct => .LDST32_ABS_LO12_NC,
318 .got_load => unreachable,
319 },
320 inline .str, .ldr => |encoded, mnemonic| switch (encoded.sf) {
292 .word => .LDST32_ABS_LO12_NC,321 .word => .LDST32_ABS_LO12_NC,
293 .doubleword => .LDST64_ABS_LO12_NC,322 .doubleword => switch (kind) {
323 .direct => .LDST64_ABS_LO12_NC,
324 .got_load => switch (mnemonic) {
325 else => comptime unreachable,
326 .str => unreachable,
327 .ldr => .LD64_GOT_LO12_NC,
328 },
329 },
294 },330 },
295 },331 },
296 .vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {332 .vector => |vector| switch (kind) {
297 .byte => .LDST8_ABS_LO12_NC,333 .direct => switch (vector.group.opc1.decode(vector.group.size)) {
298 .half => .LDST16_ABS_LO12_NC,334 .byte => .LDST8_ABS_LO12_NC,
299 .single => .LDST32_ABS_LO12_NC,335 .half => .LDST16_ABS_LO12_NC,
300 .double => .LDST64_ABS_LO12_NC,336 .single => .LDST32_ABS_LO12_NC,
301 .quad => .LDST128_ABS_LO12_NC,337 .double => .LDST64_ABS_LO12_NC,
338 .quad => .LDST128_ABS_LO12_NC,
339 },
340 .got_load => unreachable,
302 },341 },
303 };342 };
304 try atom.addReloc(gpa, .{343 try atom.addReloc(gpa, .{
...@@ -314,7 +353,10 @@ fn emitReloc(...@@ -314,7 +353,10 @@ fn emitReloc(
314 .offset = offset,353 .offset = offset,
315 .target = sym_index,354 .target = sym_index,
316 .addend = @bitCast(addend),355 .addend = @bitCast(addend),
317 .type = .pageoff,356 .type = switch (kind) {
357 .direct => .pageoff,
358 .got_load => .got_load_pageoff,
359 },
318 .meta = .{360 .meta = .{
319 .pcrel = false,361 .pcrel = false,
320 .has_subtractor = false,362 .has_subtractor = false,
src/codegen/aarch64/Select.zig+357-273
...@@ -961,7 +961,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -961,7 +961,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
961 .inst_index = undefined,961 .inst_index = undefined,
962 };962 };
963 air_tag: switch (air.next().?) {963 air_tag: switch (air.next().?) {
964 else => |air_tag| return isel.fail("unimplemented {s}", .{@tagName(air_tag)}),964 else => |air_tag| return isel.fail("unimplemented {t}", .{air_tag}),
965 .arg => {965 .arg => {
966 const arg_vi = isel.live_values.fetchRemove(air.inst_index).?.value;966 const arg_vi = isel.live_values.fetchRemove(air.inst_index).?.value;
967 defer arg_vi.deref(isel);967 defer arg_vi.deref(isel);
...@@ -1117,12 +1117,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1117,12 +1117,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
11171117
1118 const bin_op = air.data(air.inst_index).bin_op;1118 const bin_op = air.data(air.inst_index).bin_op;
1119 const ty = isel.air.typeOf(bin_op.lhs, ip);1119 const ty = isel.air.typeOf(bin_op.lhs, ip);
1120 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });1120 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
1121 const int_info = ty.intInfo(zcu);1121 const int_info = ty.intInfo(zcu);
1122 switch (int_info.bits) {1122 switch (int_info.bits) {
1123 0 => unreachable,1123 0 => unreachable,
1124 32, 64 => |bits| switch (int_info.signedness) {1124 32, 64 => |bits| switch (int_info.signedness) {
1125 .signed => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1125 .signed => return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1126 .unsigned => {1126 .unsigned => {
1127 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;1127 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
1128 const lhs_vi = try isel.use(bin_op.lhs);1128 const lhs_vi = try isel.use(bin_op.lhs);
...@@ -1160,7 +1160,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1160,7 +1160,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1160 try lhs_mat.finish(isel);1160 try lhs_mat.finish(isel);
1161 },1161 },
1162 },1162 },
1163 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1163 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1164 }1164 }
1165 }1165 }
1166 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;1166 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -1172,7 +1172,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1172,7 +1172,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1172 const bin_op = air.data(air.inst_index).bin_op;1172 const bin_op = air.data(air.inst_index).bin_op;
1173 const ty = isel.air.typeOf(bin_op.lhs, ip);1173 const ty = isel.air.typeOf(bin_op.lhs, ip);
1174 if (!ty.isRuntimeFloat()) {1174 if (!ty.isRuntimeFloat()) {
1175 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });1175 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
1176 const int_info = ty.intInfo(zcu);1176 const int_info = ty.intInfo(zcu);
1177 switch (int_info.bits) {1177 switch (int_info.bits) {
1178 0 => unreachable,1178 0 => unreachable,
...@@ -1318,7 +1318,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1318,7 +1318,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1318 try rhs_lo64_mat.finish(isel);1318 try rhs_lo64_mat.finish(isel);
1319 try lhs_lo64_mat.finish(isel);1319 try lhs_lo64_mat.finish(isel);
1320 },1320 },
1321 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1321 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1322 }1322 }
1323 } else switch (ty.floatBits(isel.target)) {1323 } else switch (ty.floatBits(isel.target)) {
1324 else => unreachable,1324 else => unreachable,
...@@ -1421,7 +1421,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1421,7 +1421,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
14211421
1422 const bin_op = air.data(air.inst_index).bin_op;1422 const bin_op = air.data(air.inst_index).bin_op;
1423 const ty = isel.air.typeOf(bin_op.lhs, ip);1423 const ty = isel.air.typeOf(bin_op.lhs, ip);
1424 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });1424 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
1425 const int_info = ty.intInfo(zcu);1425 const int_info = ty.intInfo(zcu);
1426 switch (int_info.signedness) {1426 switch (int_info.signedness) {
1427 .signed => switch (int_info.bits) {1427 .signed => switch (int_info.bits) {
...@@ -1443,7 +1443,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1443,7 +1443,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1443 try rhs_mat.finish(isel);1443 try rhs_mat.finish(isel);
1444 try lhs_mat.finish(isel);1444 try lhs_mat.finish(isel);
1445 },1445 },
1446 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1446 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1447 },1447 },
1448 .unsigned => switch (int_info.bits) {1448 .unsigned => switch (int_info.bits) {
1449 0 => unreachable,1449 0 => unreachable,
...@@ -1545,8 +1545,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1545,8 +1545,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1545 try rhs_mat.finish(isel);1545 try rhs_mat.finish(isel);
1546 try lhs_mat.finish(isel);1546 try lhs_mat.finish(isel);
1547 },1547 },
1548 65...128 => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1548 65...128 => return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1549 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1549 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1550 },1550 },
1551 }1551 }
1552 }1552 }
...@@ -1558,7 +1558,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1558,7 +1558,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
15581558
1559 const bin_op = air.data(air.inst_index).bin_op;1559 const bin_op = air.data(air.inst_index).bin_op;
1560 const ty = isel.air.typeOf(bin_op.lhs, ip);1560 const ty = isel.air.typeOf(bin_op.lhs, ip);
1561 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });1561 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
1562 const int_info = ty.intInfo(zcu);1562 const int_info = ty.intInfo(zcu);
1563 switch (int_info.bits) {1563 switch (int_info.bits) {
1564 0 => unreachable,1564 0 => unreachable,
...@@ -1784,7 +1784,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1784,7 +1784,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1784 try rhs_mat.finish(isel);1784 try rhs_mat.finish(isel);
1785 try lhs_mat.finish(isel);1785 try lhs_mat.finish(isel);
1786 },1786 },
1787 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),1787 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
1788 }1788 }
1789 }1789 }
1790 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;1790 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -1897,7 +1897,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1897,7 +1897,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1897 const bin_op = air.data(air.inst_index).bin_op;1897 const bin_op = air.data(air.inst_index).bin_op;
1898 const ty = isel.air.typeOf(bin_op.lhs, ip);1898 const ty = isel.air.typeOf(bin_op.lhs, ip);
1899 if (!ty.isRuntimeFloat()) {1899 if (!ty.isRuntimeFloat()) {
1900 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });1900 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
1901 const int_info = ty.intInfo(zcu);1901 const int_info = ty.intInfo(zcu);
1902 switch (int_info.bits) {1902 switch (int_info.bits) {
1903 0 => unreachable,1903 0 => unreachable,
...@@ -1970,7 +1970,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -1970,7 +1970,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
1970 else => unreachable,1970 else => unreachable,
1971 .div_trunc, .div_exact => {},1971 .div_trunc, .div_exact => {},
1972 .div_floor => switch (int_info.signedness) {1972 .div_floor => switch (int_info.signedness) {
1973 .signed => return isel.fail("unimplemented {s}", .{@tagName(air_tag)}),1973 .signed => return isel.fail("unimplemented {t}", .{air_tag}),
1974 .unsigned => {},1974 .unsigned => {},
1975 },1975 },
1976 }1976 }
...@@ -2012,7 +2012,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2012,7 +2012,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2012 try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);2012 try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
2013 try call.finishParams(isel);2013 try call.finishParams(isel);
2014 },2014 },
2015 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),2015 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
2016 }2016 }
2017 } else switch (ty.floatBits(isel.target)) {2017 } else switch (ty.floatBits(isel.target)) {
2018 else => unreachable,2018 else => unreachable,
...@@ -2169,9 +2169,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2169,9 +2169,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2169 const bin_op = air.data(air.inst_index).bin_op;2169 const bin_op = air.data(air.inst_index).bin_op;
2170 const ty = isel.air.typeOf(bin_op.lhs, ip);2170 const ty = isel.air.typeOf(bin_op.lhs, ip);
2171 if (!ty.isRuntimeFloat()) {2171 if (!ty.isRuntimeFloat()) {
2172 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2172 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
2173 const int_info = ty.intInfo(zcu);2173 const int_info = ty.intInfo(zcu);
2174 if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2174 if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
21752175
2176 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;2176 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
2177 const lhs_vi = try isel.use(bin_op.lhs);2177 const lhs_vi = try isel.use(bin_op.lhs);
...@@ -2494,9 +2494,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2494,9 +2494,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2494 const bin_op = air.data(air.inst_index).bin_op;2494 const bin_op = air.data(air.inst_index).bin_op;
2495 const ty = isel.air.typeOf(bin_op.lhs, ip);2495 const ty = isel.air.typeOf(bin_op.lhs, ip);
2496 if (!ty.isRuntimeFloat()) {2496 if (!ty.isRuntimeFloat()) {
2497 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2497 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
2498 const int_info = ty.intInfo(zcu);2498 const int_info = ty.intInfo(zcu);
2499 if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2499 if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
25002500
2501 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;2501 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
2502 const lhs_vi = try isel.use(bin_op.lhs);2502 const lhs_vi = try isel.use(bin_op.lhs);
...@@ -2920,8 +2920,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2920,8 +2920,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
2920 else if (ty.isAbiInt(zcu))2920 else if (ty.isAbiInt(zcu))
2921 ty.intInfo(zcu)2921 ty.intInfo(zcu)
2922 else2922 else
2923 return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2923 return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
2924 if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2924 if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
29252925
2926 const lhs_vi = try isel.use(bin_op.lhs);2926 const lhs_vi = try isel.use(bin_op.lhs);
2927 const rhs_vi = try isel.use(bin_op.rhs);2927 const rhs_vi = try isel.use(bin_op.rhs);
...@@ -2968,7 +2968,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -2968,7 +2968,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
29682968
2969 const bin_op = air.data(air.inst_index).bin_op;2969 const bin_op = air.data(air.inst_index).bin_op;
2970 const ty = isel.air.typeOf(bin_op.lhs, ip);2970 const ty = isel.air.typeOf(bin_op.lhs, ip);
2971 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });2971 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
2972 const int_info = ty.intInfo(zcu);2972 const int_info = ty.intInfo(zcu);
2973 switch (int_info.bits) {2973 switch (int_info.bits) {
2974 0 => unreachable,2974 0 => unreachable,
...@@ -3161,7 +3161,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3161,7 +3161,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3161 try lhs_hi64_mat.finish(isel);3161 try lhs_hi64_mat.finish(isel);
3162 break :unused;3162 break :unused;
3163 },3163 },
3164 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),3164 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
3165 }3165 }
3166 }3166 }
3167 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;3167 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -3174,10 +3174,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3174,10 +3174,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3174 const ty = ty_op.ty.toType();3174 const ty = ty_op.ty.toType();
3175 const int_info: std.builtin.Type.Int = int_info: {3175 const int_info: std.builtin.Type.Int = int_info: {
3176 if (ty_op.ty == .bool_type) break :int_info .{ .signedness = .unsigned, .bits = 1 };3176 if (ty_op.ty == .bool_type) break :int_info .{ .signedness = .unsigned, .bits = 1 };
3177 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3177 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3178 break :int_info ty.intInfo(zcu);3178 break :int_info ty.intInfo(zcu);
3179 };3179 };
3180 if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3180 if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
31813181
3182 const src_vi = try isel.use(ty_op.operand);3182 const src_vi = try isel.use(ty_op.operand);
3183 var offset = res_vi.value.size(isel);3183 var offset = res_vi.value.size(isel);
...@@ -3302,7 +3302,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3302,7 +3302,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3302 }3302 }
3303 },3303 },
3304 128 => try dst_vi.value.move(isel, ty_op.operand),3304 128 => try dst_vi.value.move(isel, ty_op.operand),
3305 else => return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),3305 else => return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
3306 }3306 }
3307 } else if ((dst_ty.isPtrAtRuntime(zcu) or dst_ty.isAbiInt(zcu)) and (src_ty.isPtrAtRuntime(zcu) or src_ty.isAbiInt(zcu))) {3307 } else if ((dst_ty.isPtrAtRuntime(zcu) or dst_ty.isAbiInt(zcu)) and (src_ty.isPtrAtRuntime(zcu) or src_ty.isAbiInt(zcu))) {
3308 try dst_vi.value.move(isel, ty_op.operand);3308 try dst_vi.value.move(isel, ty_op.operand);
...@@ -3313,7 +3313,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3313,7 +3313,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3313 src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));3313 src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));
3314 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {3314 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
3315 try dst_vi.value.move(isel, ty_op.operand);3315 try dst_vi.value.move(isel, ty_op.operand);
3316 } else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });3316 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
3317 } else if (dst_tag == .float and src_tag == .float) {3317 } else if (dst_tag == .float and src_tag == .float) {
3318 assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target));3318 assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target));
3319 try dst_vi.value.move(isel, ty_op.operand);3319 try dst_vi.value.move(isel, ty_op.operand);
...@@ -3483,7 +3483,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3483,7 +3483,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3483 try call.paramAddress(isel, src_vi, .r1);3483 try call.paramAddress(isel, src_vi, .r1);
3484 try call.paramAddress(isel, dst_vi.value, .r0);3484 try call.paramAddress(isel, dst_vi.value, .r0);
3485 try call.finishParams(isel);3485 try call.finishParams(isel);
3486 } else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });3486 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
3487 } else if (dst_tag == .array and dst_ty.childType(zcu).isAbiInt(zcu) and src_ty.isAbiInt(zcu)) {3487 } else if (dst_tag == .array and dst_ty.childType(zcu).isAbiInt(zcu) and src_ty.isAbiInt(zcu)) {
3488 const dst_child_int_info = dst_ty.childType(zcu).intInfo(zcu);3488 const dst_child_int_info = dst_ty.childType(zcu).intInfo(zcu);
3489 const src_int_info = src_ty.intInfo(zcu);3489 const src_int_info = src_ty.intInfo(zcu);
...@@ -3510,8 +3510,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3510,8 +3510,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3510 try call.paramAddress(isel, src_vi, .r1);3510 try call.paramAddress(isel, src_vi, .r1);
3511 try call.paramAddress(isel, dst_vi.value, .r0);3511 try call.paramAddress(isel, dst_vi.value, .r0);
3512 try call.finishParams(isel);3512 try call.finishParams(isel);
3513 } else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });3513 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
3514 } else return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });3514 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
3515 }3515 }
3516 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;3516 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
3517 },3517 },
...@@ -3737,7 +3737,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3737,7 +3737,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
37373737
3738 const ty_op = air.data(air.inst_index).ty_op;3738 const ty_op = air.data(air.inst_index).ty_op;
3739 const ty = isel.air.typeOf(ty_op.operand, ip);3739 const ty = isel.air.typeOf(ty_op.operand, ip);
3740 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3740 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3741 const int_info = ty.intInfo(zcu);3741 const int_info = ty.intInfo(zcu);
3742 switch (int_info.bits) {3742 switch (int_info.bits) {
3743 0 => unreachable,3743 0 => unreachable,
...@@ -3769,7 +3769,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3769,7 +3769,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3769 try src_hi64_mat.finish(isel);3769 try src_hi64_mat.finish(isel);
3770 try src_lo64_mat.finish(isel);3770 try src_lo64_mat.finish(isel);
3771 },3771 },
3772 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),3772 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
3773 }3773 }
3774 }3774 }
3775 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;3775 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -3780,7 +3780,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3780,7 +3780,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
37803780
3781 const ty_op = air.data(air.inst_index).ty_op;3781 const ty_op = air.data(air.inst_index).ty_op;
3782 const ty = isel.air.typeOf(ty_op.operand, ip);3782 const ty = isel.air.typeOf(ty_op.operand, ip);
3783 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3783 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3784 const int_info = ty.intInfo(zcu);3784 const int_info = ty.intInfo(zcu);
3785 switch (int_info.bits) {3785 switch (int_info.bits) {
3786 0 => unreachable,3786 0 => unreachable,
...@@ -3812,7 +3812,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3812,7 +3812,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
3812 try src_hi64_mat.finish(isel);3812 try src_hi64_mat.finish(isel);
3813 try src_lo64_mat.finish(isel);3813 try src_lo64_mat.finish(isel);
3814 },3814 },
3815 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),3815 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
3816 }3816 }
3817 }3817 }
3818 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;3818 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -3823,9 +3823,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3823,9 +3823,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
38233823
3824 const ty_op = air.data(air.inst_index).ty_op;3824 const ty_op = air.data(air.inst_index).ty_op;
3825 const ty = isel.air.typeOf(ty_op.operand, ip);3825 const ty = isel.air.typeOf(ty_op.operand, ip);
3826 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3826 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3827 const int_info = ty.intInfo(zcu);3827 const int_info = ty.intInfo(zcu);
3828 if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3828 if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
38293829
3830 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;3830 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
3831 const src_vi = try isel.use(ty_op.operand);3831 const src_vi = try isel.use(ty_op.operand);
...@@ -3877,9 +3877,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3877,9 +3877,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
38773877
3878 const ty_op = air.data(air.inst_index).ty_op;3878 const ty_op = air.data(air.inst_index).ty_op;
3879 const ty = ty_op.ty.toType();3879 const ty = ty_op.ty.toType();
3880 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3880 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3881 const int_info = ty.intInfo(zcu);3881 const int_info = ty.intInfo(zcu);
3882 if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3882 if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
38833883
3884 if (int_info.bits == 8) break :unused try res_vi.value.move(isel, ty_op.operand);3884 if (int_info.bits == 8) break :unused try res_vi.value.move(isel, ty_op.operand);
3885 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;3885 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
...@@ -3941,9 +3941,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -3941,9 +3941,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
39413941
3942 const ty_op = air.data(air.inst_index).ty_op;3942 const ty_op = air.data(air.inst_index).ty_op;
3943 const ty = ty_op.ty.toType();3943 const ty = ty_op.ty.toType();
3944 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3944 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
3945 const int_info = ty.intInfo(zcu);3945 const int_info = ty.intInfo(zcu);
3946 if (int_info.bits > 64) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });3946 if (int_info.bits > 64) return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) });
39473947
3948 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;3948 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
3949 const src_vi = try isel.use(ty_op.operand);3949 const src_vi = try isel.use(ty_op.operand);
...@@ -4244,7 +4244,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4244,7 +4244,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4244 const ty_op = air.data(air.inst_index).ty_op;4244 const ty_op = air.data(air.inst_index).ty_op;
4245 const ty = ty_op.ty.toType();4245 const ty = ty_op.ty.toType();
4246 if (!ty.isRuntimeFloat()) {4246 if (!ty.isRuntimeFloat()) {
4247 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });4247 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ air_tag, isel.fmtType(ty) });
4248 switch (ty.intInfo(zcu).bits) {4248 switch (ty.intInfo(zcu).bits) {
4249 0 => unreachable,4249 0 => unreachable,
4250 1...32 => {4250 1...32 => {
...@@ -4306,7 +4306,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4306,7 +4306,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4306 try src_lo64_mat.finish(isel);4306 try src_lo64_mat.finish(isel);
4307 try src_hi64_mat.finish(isel);4307 try src_hi64_mat.finish(isel);
4308 },4308 },
4309 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),4309 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(ty) }),
4310 }4310 }
4311 } else switch (ty.floatBits(isel.target)) {4311 } else switch (ty.floatBits(isel.target)) {
4312 else => unreachable,4312 else => unreachable,
...@@ -4465,216 +4465,61 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -4465,216 +4465,61 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
4465 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {4465 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
4466 defer res_vi.value.deref(isel);4466 defer res_vi.value.deref(isel);
44674467
4468 var bin_op = air.data(air.inst_index).bin_op;4468 const bin_op = air.data(air.inst_index).bin_op;
4469 const ty = isel.air.typeOf(bin_op.lhs, ip);4469 const ty = isel.air.typeOf(bin_op.lhs, ip);
4470 if (!ty.isRuntimeFloat()) {4470 switch (ip.indexToKey(ty.toIntern())) {
4471 const int_info: std.builtin.Type.Int = if (ty.toIntern() == .bool_type)4471 else => {},
4472 .{ .signedness = .unsigned, .bits = 1 }4472 .opt_type => |payload_ty| switch (air_tag) {
4473 else if (ty.isAbiInt(zcu))
4474 ty.intInfo(zcu)
4475 else if (ty.isPtrAtRuntime(zcu))
4476 .{ .signedness = .unsigned, .bits = 64 }
4477 else
4478 return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
4479 if (int_info.bits > 256) return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
4480
4481 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
4482 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (air_tag) {
4483 else => unreachable,4473 else => unreachable,
4484 .cmp_lt => switch (int_info.signedness) {4474 .cmp_eq, .cmp_neq => if (!ty.optionalReprIsPayload(zcu)) {
4485 .signed => .lt,4475 const lhs_vi = try isel.use(bin_op.lhs);
4486 .unsigned => .lo,4476 const rhs_vi = try isel.use(bin_op.rhs);
4487 },4477 const payload_size = ZigType.abiSize(.fromInterned(payload_ty), zcu);
4488 .cmp_lte => switch (int_info.bits) {4478 var lhs_payload_part_it = lhs_vi.field(ty, 0, payload_size);
4489 else => unreachable,4479 const lhs_payload_part_vi = try lhs_payload_part_it.only(isel);
4490 1...64 => switch (int_info.signedness) {4480 var rhs_payload_part_it = rhs_vi.field(ty, 0, payload_size);
4491 .signed => .le,4481 const rhs_payload_part_vi = try rhs_payload_part_it.only(isel);
4492 .unsigned => .ls,4482 const cmp_info = try isel.cmp(
4493 },4483 try res_vi.value.defReg(isel) orelse break :unused,
4494 65...128 => {4484 .fromInterned(payload_ty),
4495 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);4485 lhs_payload_part_vi.?,
4496 continue :cond .cmp_gte;4486 air_tag.toCmpOp().?,
4497 },4487 rhs_payload_part_vi.?,
4498 },4488 );
4499 .cmp_eq => .eq,4489 try isel.emit(.@"b."(
4500 .cmp_gte => switch (int_info.signedness) {4490 .vc,
4501 .signed => .ge,4491 @intCast((isel.instructions.items.len + 1 - cmp_info.cset_label) << 2),
4502 .unsigned => .hs,4492 ));
4503 },4493 var lhs_has_value_part_it = lhs_vi.field(ty, payload_size, 1);
4504 .cmp_gt => switch (int_info.bits) {4494 const lhs_has_value_part_vi = try lhs_has_value_part_it.only(isel);
4505 else => unreachable,4495 const lhs_has_value_part_mat = try lhs_has_value_part_vi.?.matReg(isel);
4506 1...64 => switch (int_info.signedness) {4496 var rhs_has_value_part_it = rhs_vi.field(ty, payload_size, 1);
4507 .signed => .gt,4497 const rhs_has_value_part_vi = try rhs_has_value_part_it.only(isel);
4508 .unsigned => .hi,4498 const rhs_has_value_part_mat = try rhs_has_value_part_vi.?.matReg(isel);
4509 },4499 try isel.emit(.ccmp(
4510 65...128 => {4500 lhs_has_value_part_mat.ra.w(),
4511 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);4501 .{ .register = rhs_has_value_part_mat.ra.w() },
4512 continue :cond .cmp_lt;4502 .{ .n = false, .z = false, .c = false, .v = true },
4513 },4503 .eq,
4504 ));
4505 try isel.emit(.ands(
4506 .wzr,
4507 lhs_has_value_part_mat.ra.w(),
4508 .{ .register = rhs_has_value_part_mat.ra.w() },
4509 ));
4510 try rhs_has_value_part_mat.finish(isel);
4511 try lhs_has_value_part_mat.finish(isel);
4512 break :unused;
4514 },4513 },
4515 .cmp_neq => .ne,
4516 })));
4517
4518 const lhs_vi = try isel.use(bin_op.lhs);
4519 const rhs_vi = try isel.use(bin_op.rhs);
4520 var part_offset = lhs_vi.size(isel);
4521 while (part_offset > 0) {
4522 const part_size = @min(part_offset, 8);
4523 part_offset -= part_size;
4524 var lhs_part_it = lhs_vi.field(ty, part_offset, part_size);
4525 const lhs_part_vi = try lhs_part_it.only(isel);
4526 const lhs_part_mat = try lhs_part_vi.?.matReg(isel);
4527 var rhs_part_it = rhs_vi.field(ty, part_offset, part_size);
4528 const rhs_part_vi = try rhs_part_it.only(isel);
4529 const rhs_part_mat = try rhs_part_vi.?.matReg(isel);
4530 try isel.emit(switch (part_size) {
4531 else => unreachable,
4532 1...4 => switch (part_offset) {
4533 0 => .subs(.wzr, lhs_part_mat.ra.w(), .{ .register = rhs_part_mat.ra.w() }),
4534 else => switch (air_tag) {
4535 else => unreachable,
4536 .cmp_lt, .cmp_lte, .cmp_gte, .cmp_gt => .sbcs(
4537 .wzr,
4538 lhs_part_mat.ra.w(),
4539 rhs_part_mat.ra.w(),
4540 ),
4541 .cmp_eq, .cmp_neq => .ccmp(
4542 lhs_part_mat.ra.w(),
4543 .{ .register = rhs_part_mat.ra.w() },
4544 .{ .n = false, .z = false, .c = false, .v = false },
4545 .eq,
4546 ),
4547 },
4548 },
4549 5...8 => switch (part_offset) {
4550 0 => .subs(.xzr, lhs_part_mat.ra.x(), .{ .register = rhs_part_mat.ra.x() }),
4551 else => switch (air_tag) {
4552 else => unreachable,
4553 .cmp_lt, .cmp_lte, .cmp_gte, .cmp_gt => .sbcs(
4554 .xzr,
4555 lhs_part_mat.ra.x(),
4556 rhs_part_mat.ra.x(),
4557 ),
4558 .cmp_eq, .cmp_neq => .ccmp(
4559 lhs_part_mat.ra.x(),
4560 .{ .register = rhs_part_mat.ra.x() },
4561 .{ .n = false, .z = false, .c = false, .v = false },
4562 .eq,
4563 ),
4564 },
4565 },
4566 });
4567 try rhs_part_mat.finish(isel);
4568 try lhs_part_mat.finish(isel);
4569 }
4570 } else switch (ty.floatBits(isel.target)) {
4571 else => unreachable,
4572 16, 32, 64 => |bits| {
4573 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
4574 const need_fcvt = switch (bits) {
4575 else => unreachable,
4576 16 => !isel.target.cpu.has(.aarch64, .fullfp16),
4577 32, 64 => false,
4578 };
4579 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(switch (air_tag) {
4580 else => unreachable,
4581 .cmp_lt => .lo,
4582 .cmp_lte => .ls,
4583 .cmp_eq => .eq,
4584 .cmp_gte => .ge,
4585 .cmp_gt => .gt,
4586 .cmp_neq => .ne,
4587 })));
4588
4589 const lhs_vi = try isel.use(bin_op.lhs);
4590 const rhs_vi = try isel.use(bin_op.rhs);
4591 const lhs_mat = try lhs_vi.matReg(isel);
4592 const rhs_mat = try rhs_vi.matReg(isel);
4593 const lhs_ra = if (need_fcvt) try isel.allocVecReg() else lhs_mat.ra;
4594 defer if (need_fcvt) isel.freeReg(lhs_ra);
4595 const rhs_ra = if (need_fcvt) try isel.allocVecReg() else rhs_mat.ra;
4596 defer if (need_fcvt) isel.freeReg(rhs_ra);
4597 try isel.emit(bits: switch (bits) {
4598 else => unreachable,
4599 16 => if (need_fcvt)
4600 continue :bits 32
4601 else
4602 .fcmp(lhs_ra.h(), .{ .register = rhs_ra.h() }),
4603 32 => .fcmp(lhs_ra.s(), .{ .register = rhs_ra.s() }),
4604 64 => .fcmp(lhs_ra.d(), .{ .register = rhs_ra.d() }),
4605 });
4606 if (need_fcvt) {
4607 try isel.emit(.fcvt(rhs_ra.s(), rhs_mat.ra.h()));
4608 try isel.emit(.fcvt(lhs_ra.s(), lhs_mat.ra.h()));
4609 }
4610 try rhs_mat.finish(isel);
4611 try lhs_mat.finish(isel);
4612 },
4613 80, 128 => |bits| {
4614 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
4615
4616 try call.prepareReturn(isel);
4617 try call.returnFill(isel, .r0);
4618 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (air_tag) {
4619 else => unreachable,
4620 .cmp_lt => .lt,
4621 .cmp_lte => .le,
4622 .cmp_eq => .eq,
4623 .cmp_gte => {
4624 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
4625 continue :cond .cmp_lte;
4626 },
4627 .cmp_gt => {
4628 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
4629 continue :cond .cmp_lt;
4630 },
4631 .cmp_neq => .ne,
4632 })));
4633 try isel.emit(.subs(.wzr, .w0, .{ .immediate = 0 }));
4634 try call.finishReturn(isel);
4635
4636 try call.prepareCallee(isel);
4637 try isel.global_relocs.append(gpa, .{
4638 .name = switch (bits) {
4639 else => unreachable,
4640 16 => "__cmphf2",
4641 32 => "__cmpsf2",
4642 64 => "__cmpdf2",
4643 80 => "__cmpxf2",
4644 128 => "__cmptf2",
4645 },
4646 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
4647 });
4648 try isel.emit(.bl(0));
4649 try call.finishCallee(isel);
4650
4651 try call.prepareParams(isel);
4652 const lhs_vi = try isel.use(bin_op.lhs);
4653 const rhs_vi = try isel.use(bin_op.rhs);
4654 switch (bits) {
4655 else => unreachable,
4656 16, 32, 64, 128 => {
4657 try call.paramLiveOut(isel, rhs_vi, .v1);
4658 try call.paramLiveOut(isel, lhs_vi, .v0);
4659 },
4660 80 => {
4661 var rhs_hi16_it = rhs_vi.field(ty, 8, 8);
4662 const rhs_hi16_vi = try rhs_hi16_it.only(isel);
4663 try call.paramLiveOut(isel, rhs_hi16_vi.?, .r3);
4664 var rhs_lo64_it = rhs_vi.field(ty, 0, 8);
4665 const rhs_lo64_vi = try rhs_lo64_it.only(isel);
4666 try call.paramLiveOut(isel, rhs_lo64_vi.?, .r2);
4667 var lhs_hi16_it = lhs_vi.field(ty, 8, 8);
4668 const lhs_hi16_vi = try lhs_hi16_it.only(isel);
4669 try call.paramLiveOut(isel, lhs_hi16_vi.?, .r1);
4670 var lhs_lo64_it = lhs_vi.field(ty, 0, 8);
4671 const lhs_lo64_vi = try lhs_lo64_it.only(isel);
4672 try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
4673 },
4674 }
4675 try call.finishParams(isel);
4676 },4514 },
4677 }4515 }
4516 _ = try isel.cmp(
4517 try res_vi.value.defReg(isel) orelse break :unused,
4518 ty,
4519 try isel.use(bin_op.lhs),
4520 air_tag.toCmpOp().?,
4521 try isel.use(bin_op.rhs),
4522 );
4678 }4523 }
4679 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;4524 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
4680 },4525 },
...@@ -5497,7 +5342,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5497,7 +5342,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5497 try src_mat.finish(isel);5342 try src_mat.finish(isel);
5498 },5343 },
5499 };5344 };
5500 } else return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });5345 } else return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5501 }5346 }
5502 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;5347 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
5503 },5348 },
...@@ -5517,7 +5362,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5517,7 +5362,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5517 .int => .integer_out_of_bounds,5362 .int => .integer_out_of_bounds,
5518 .@"enum" => {5363 .@"enum" => {
5519 if (!dst_ty.isNonexhaustiveEnum(zcu)) {5364 if (!dst_ty.isNonexhaustiveEnum(zcu)) {
5520 return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });5365 return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5521 }5366 }
5522 break :panic_id .invalid_enum_value;5367 break :panic_id .invalid_enum_value;
5523 },5368 },
...@@ -5599,7 +5444,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5599,7 +5444,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5599 try src_mat.finish(isel);5444 try src_mat.finish(isel);
5600 }5445 }
5601 }5446 }
5602 } else return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });5447 } else return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5603 }5448 }
5604 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;5449 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
5605 },5450 },
...@@ -5610,7 +5455,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5610,7 +5455,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5610 const ty_op = air.data(air.inst_index).ty_op;5455 const ty_op = air.data(air.inst_index).ty_op;
5611 const dst_ty = ty_op.ty.toType();5456 const dst_ty = ty_op.ty.toType();
5612 const src_ty = isel.air.typeOf(ty_op.operand, ip);5457 const src_ty = isel.air.typeOf(ty_op.operand, ip);
5613 if (!dst_ty.isAbiInt(zcu) or !src_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });5458 if (!dst_ty.isAbiInt(zcu) or !src_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
5614 const dst_int_info = dst_ty.intInfo(zcu);5459 const dst_int_info = dst_ty.intInfo(zcu);
5615 switch (dst_int_info.bits) {5460 switch (dst_int_info.bits) {
5616 0 => unreachable,5461 0 => unreachable,
...@@ -5683,9 +5528,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5683,9 +5528,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5683 try src_lo64_vi.?.liveOut(isel, dst_lo64_ra);5528 try src_lo64_vi.?.liveOut(isel, dst_lo64_ra);
5684 }5529 }
5685 },5530 },
5686 else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),5531 else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
5687 },5532 },
5688 else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),5533 else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
5689 }5534 }
5690 }5535 }
5691 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;5536 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -6487,7 +6332,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6487,7 +6332,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6487 const ty_op = air.data(air.inst_index).ty_op;6332 const ty_op = air.data(air.inst_index).ty_op;
6488 const dst_ty = ty_op.ty.toType();6333 const dst_ty = ty_op.ty.toType();
6489 const src_ty = isel.air.typeOf(ty_op.operand, ip);6334 const src_ty = isel.air.typeOf(ty_op.operand, ip);
6490 if (!dst_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });6335 if (!dst_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
6491 const dst_int_info = dst_ty.intInfo(zcu);6336 const dst_int_info = dst_ty.intInfo(zcu);
6492 const src_bits = src_ty.floatBits(isel.target);6337 const src_bits = src_ty.floatBits(isel.target);
6493 switch (@max(dst_int_info.bits, src_bits)) {6338 switch (@max(dst_int_info.bits, src_bits)) {
...@@ -6617,7 +6462,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6617,7 +6462,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6617 }6462 }
6618 try call.finishParams(isel);6463 try call.finishParams(isel);
6619 },6464 },
6620 else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),6465 else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
6621 }6466 }
6622 }6467 }
6623 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;6468 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -6630,7 +6475,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6630,7 +6475,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6630 const dst_ty = ty_op.ty.toType();6475 const dst_ty = ty_op.ty.toType();
6631 const src_ty = isel.air.typeOf(ty_op.operand, ip);6476 const src_ty = isel.air.typeOf(ty_op.operand, ip);
6632 const dst_bits = dst_ty.floatBits(isel.target);6477 const dst_bits = dst_ty.floatBits(isel.target);
6633 if (!src_ty.isAbiInt(zcu)) return isel.fail("bad {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) });6478 if (!src_ty.isAbiInt(zcu)) return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
6634 const src_int_info = src_ty.intInfo(zcu);6479 const src_int_info = src_ty.intInfo(zcu);
6635 switch (@max(dst_bits, src_int_info.bits)) {6480 switch (@max(dst_bits, src_int_info.bits)) {
6636 0 => unreachable,6481 0 => unreachable,
...@@ -6757,7 +6602,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6757,7 +6602,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6757 }6602 }
6758 try call.finishParams(isel);6603 try call.finishParams(isel);
6759 },6604 },
6760 else => return isel.fail("too big {s} {f} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty), isel.fmtType(src_ty) }),6605 else => return isel.fail("too big {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) }),
6761 }6606 }
6762 }6607 }
6763 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;6608 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
...@@ -6836,7 +6681,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -6836,7 +6681,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
68366681
6837 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;6682 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
6838 },6683 },
6839 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(dst_ty) }),6684 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(dst_ty) }),
6840 }6685 }
6841 };6686 };
68426687
...@@ -7157,7 +7002,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7157,7 +7002,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7157 else => unreachable,7002 else => unreachable,
7158 },7003 },
7159 }),7004 }),
7160 else => return isel.fail("too big {s} {f}", .{ @tagName(air_tag), isel.fmtType(union_ty) }),7005 else => return isel.fail("too big {t} {f}", .{ air_tag, isel.fmtType(union_ty) }),
7161 }7006 }
7162 }7007 }
7163 var payload_it = union_vi.value.field(union_ty, union_layout.payloadOffset(), union_layout.payload_size);7008 var payload_it = union_vi.value.field(union_ty, union_layout.payloadOffset(), union_layout.payload_size);
...@@ -7412,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7412,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7412 .nav = ty_nav.nav,7257 .nav = ty_nav.nav,
7413 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7258 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7414 });7259 });
7415 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));7260 if (ip.getNav(ty_nav.nav).getExtern(ip)) |_|
7261 try isel.emit(.ldr(ptr_ra.x(), .{ .unsigned_offset = .{ .base = ptr_ra.x(), .offset = 0 } }))
7262 else
7263 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
7416 try isel.nav_relocs.append(gpa, .{7264 try isel.nav_relocs.append(gpa, .{
7417 .nav = ty_nav.nav,7265 .nav = ty_nav.nav,
7418 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7266 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
...@@ -8499,6 +8347,217 @@ fn ctzLimb(...@@ -8499,6 +8347,217 @@ fn ctzLimb(
8499 }8347 }
8500}8348}
85018349
8350fn cmp(
8351 isel: *Select,
8352 res_ra: Register.Alias,
8353 ty: ZigType,
8354 orig_lhs_vi: Value.Index,
8355 op: std.math.CompareOperator,
8356 orig_rhs_vi: Value.Index,
8357) !struct { cset_label: usize } {
8358 var lhs_vi = orig_lhs_vi;
8359 var rhs_vi = orig_rhs_vi;
8360 if (!ty.isRuntimeFloat()) {
8361 const int_info: std.builtin.Type.Int = if (ty.toIntern() == .bool_type)
8362 .{ .signedness = .unsigned, .bits = 1 }
8363 else if (ty.isAbiInt(isel.pt.zcu))
8364 ty.intInfo(isel.pt.zcu)
8365 else if (ty.isPtrAtRuntime(isel.pt.zcu))
8366 .{ .signedness = .unsigned, .bits = 64 }
8367 else
8368 return isel.fail("bad cmp_{t} {f}", .{ op, isel.fmtType(ty) });
8369 if (int_info.bits > 256) return isel.fail("too big cmp_{t} {f}", .{ op, isel.fmtType(ty) });
8370 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (op) {
8371 .lt => switch (int_info.signedness) {
8372 .signed => .lt,
8373 .unsigned => .lo,
8374 },
8375 .lte => switch (int_info.bits) {
8376 else => unreachable,
8377 1...64 => switch (int_info.signedness) {
8378 .signed => .le,
8379 .unsigned => .ls,
8380 },
8381 65...128 => {
8382 std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
8383 continue :cond .gte;
8384 },
8385 },
8386 .eq => .eq,
8387 .gte => switch (int_info.signedness) {
8388 .signed => .ge,
8389 .unsigned => .hs,
8390 },
8391 .gt => switch (int_info.bits) {
8392 else => unreachable,
8393 1...64 => switch (int_info.signedness) {
8394 .signed => .gt,
8395 .unsigned => .hi,
8396 },
8397 65...128 => {
8398 std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
8399 continue :cond .lt;
8400 },
8401 },
8402 .neq => .ne,
8403 })));
8404 const cset_label = isel.instructions.items.len;
8405
8406 var part_offset = lhs_vi.size(isel);
8407 while (part_offset > 0) {
8408 const part_size = @min(part_offset, 8);
8409 part_offset -= part_size;
8410 var lhs_part_it = lhs_vi.field(ty, part_offset, part_size);
8411 const lhs_part_vi = try lhs_part_it.only(isel);
8412 const lhs_part_mat = try lhs_part_vi.?.matReg(isel);
8413 var rhs_part_it = rhs_vi.field(ty, part_offset, part_size);
8414 const rhs_part_vi = try rhs_part_it.only(isel);
8415 const rhs_part_mat = try rhs_part_vi.?.matReg(isel);
8416 try isel.emit(switch (part_size) {
8417 else => unreachable,
8418 1...4 => switch (part_offset) {
8419 0 => .subs(.wzr, lhs_part_mat.ra.w(), .{ .register = rhs_part_mat.ra.w() }),
8420 else => switch (op) {
8421 .lt, .lte, .gte, .gt => .sbcs(
8422 .wzr,
8423 lhs_part_mat.ra.w(),
8424 rhs_part_mat.ra.w(),
8425 ),
8426 .eq, .neq => .ccmp(
8427 lhs_part_mat.ra.w(),
8428 .{ .register = rhs_part_mat.ra.w() },
8429 .{ .n = false, .z = false, .c = false, .v = false },
8430 .eq,
8431 ),
8432 },
8433 },
8434 5...8 => switch (part_offset) {
8435 0 => .subs(.xzr, lhs_part_mat.ra.x(), .{ .register = rhs_part_mat.ra.x() }),
8436 else => switch (op) {
8437 .lt, .lte, .gte, .gt => .sbcs(
8438 .xzr,
8439 lhs_part_mat.ra.x(),
8440 rhs_part_mat.ra.x(),
8441 ),
8442 .eq, .neq => .ccmp(
8443 lhs_part_mat.ra.x(),
8444 .{ .register = rhs_part_mat.ra.x() },
8445 .{ .n = false, .z = false, .c = false, .v = false },
8446 .eq,
8447 ),
8448 },
8449 },
8450 });
8451 try rhs_part_mat.finish(isel);
8452 try lhs_part_mat.finish(isel);
8453 }
8454 return .{ .cset_label = cset_label };
8455 }
8456 switch (ty.floatBits(isel.target)) {
8457 else => unreachable,
8458 16, 32, 64 => |bits| {
8459 const need_fcvt = switch (bits) {
8460 else => unreachable,
8461 16 => !isel.target.cpu.has(.aarch64, .fullfp16),
8462 32, 64 => false,
8463 };
8464 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(switch (op) {
8465 .lt => .lo,
8466 .lte => .ls,
8467 .eq => .eq,
8468 .gte => .ge,
8469 .gt => .gt,
8470 .neq => .ne,
8471 })));
8472 const cset_label = isel.instructions.items.len;
8473
8474 const lhs_mat = try lhs_vi.matReg(isel);
8475 const rhs_mat = try rhs_vi.matReg(isel);
8476 const lhs_ra = if (need_fcvt) try isel.allocVecReg() else lhs_mat.ra;
8477 defer if (need_fcvt) isel.freeReg(lhs_ra);
8478 const rhs_ra = if (need_fcvt) try isel.allocVecReg() else rhs_mat.ra;
8479 defer if (need_fcvt) isel.freeReg(rhs_ra);
8480 try isel.emit(bits: switch (bits) {
8481 else => unreachable,
8482 16 => if (need_fcvt)
8483 continue :bits 32
8484 else
8485 .fcmp(lhs_ra.h(), .{ .register = rhs_ra.h() }),
8486 32 => .fcmp(lhs_ra.s(), .{ .register = rhs_ra.s() }),
8487 64 => .fcmp(lhs_ra.d(), .{ .register = rhs_ra.d() }),
8488 });
8489 if (need_fcvt) {
8490 try isel.emit(.fcvt(rhs_ra.s(), rhs_mat.ra.h()));
8491 try isel.emit(.fcvt(lhs_ra.s(), lhs_mat.ra.h()));
8492 }
8493 try rhs_mat.finish(isel);
8494 try lhs_mat.finish(isel);
8495 return .{ .cset_label = cset_label };
8496 },
8497 80, 128 => |bits| {
8498 try call.prepareReturn(isel);
8499 try call.returnFill(isel, .r0);
8500 try isel.emit(.csinc(res_ra.w(), .wzr, .wzr, .invert(cond: switch (op) {
8501 .lt => .lt,
8502 .lte => .le,
8503 .eq => .eq,
8504 .gte => {
8505 std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
8506 continue :cond .lte;
8507 },
8508 .gt => {
8509 std.mem.swap(Value.Index, &lhs_vi, &rhs_vi);
8510 continue :cond .lt;
8511 },
8512 .neq => .ne,
8513 })));
8514 const cset_label = isel.instructions.items.len;
8515 try isel.emit(.subs(.wzr, .w0, .{ .immediate = 0 }));
8516 try call.finishReturn(isel);
8517
8518 try call.prepareCallee(isel);
8519 try isel.global_relocs.append(isel.pt.zcu.gpa, .{
8520 .name = switch (bits) {
8521 else => unreachable,
8522 16 => "__cmphf2",
8523 32 => "__cmpsf2",
8524 64 => "__cmpdf2",
8525 80 => "__cmpxf2",
8526 128 => "__cmptf2",
8527 },
8528 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
8529 });
8530 try isel.emit(.bl(0));
8531 try call.finishCallee(isel);
8532
8533 try call.prepareParams(isel);
8534 switch (bits) {
8535 else => unreachable,
8536 16, 32, 64, 128 => {
8537 try call.paramLiveOut(isel, rhs_vi, .v1);
8538 try call.paramLiveOut(isel, lhs_vi, .v0);
8539 },
8540 80 => {
8541 var rhs_hi16_it = rhs_vi.field(ty, 8, 8);
8542 const rhs_hi16_vi = try rhs_hi16_it.only(isel);
8543 try call.paramLiveOut(isel, rhs_hi16_vi.?, .r3);
8544 var rhs_lo64_it = rhs_vi.field(ty, 0, 8);
8545 const rhs_lo64_vi = try rhs_lo64_it.only(isel);
8546 try call.paramLiveOut(isel, rhs_lo64_vi.?, .r2);
8547 var lhs_hi16_it = lhs_vi.field(ty, 8, 8);
8548 const lhs_hi16_vi = try lhs_hi16_it.only(isel);
8549 try call.paramLiveOut(isel, lhs_hi16_vi.?, .r1);
8550 var lhs_lo64_it = lhs_vi.field(ty, 0, 8);
8551 const lhs_lo64_vi = try lhs_lo64_it.only(isel);
8552 try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
8553 },
8554 }
8555 try call.finishParams(isel);
8556 return .{ .cset_label = cset_label };
8557 },
8558 }
8559}
8560
8502fn loadReg(8561fn loadReg(
8503 isel: *Select,8562 isel: *Select,
8504 ra: Register.Alias,8563 ra: Register.Alias,
...@@ -9272,9 +9331,9 @@ pub const Value = struct {...@@ -9272,9 +9331,9 @@ pub const Value = struct {
9272 opts: AddOrSubtractOptions,9331 opts: AddOrSubtractOptions,
9273 ) !void {9332 ) !void {
9274 const zcu = isel.pt.zcu;9333 const zcu = isel.pt.zcu;
9275 if (!ty.isAbiInt(zcu)) return isel.fail("bad {s} {f}", .{ @tagName(op), isel.fmtType(ty) });9334 if (!ty.isAbiInt(zcu)) return isel.fail("bad {t} {f}", .{ op, isel.fmtType(ty) });
9276 const int_info = ty.intInfo(zcu);9335 const int_info = ty.intInfo(zcu);
9277 if (int_info.bits > 128) return isel.fail("too big {s} {f}", .{ @tagName(op), isel.fmtType(ty) });9336 if (int_info.bits > 128) return isel.fail("too big {t} {f}", .{ op, isel.fmtType(ty) });
9278 var part_offset = res_vi.size(isel);9337 var part_offset = res_vi.size(isel);
9279 var need_wrap = switch (opts.overflow) {9338 var need_wrap = switch (opts.overflow) {
9280 .@"unreachable" => false,9339 .@"unreachable" => false,
...@@ -10783,7 +10842,7 @@ pub const Value = struct {...@@ -10783,7 +10842,7 @@ pub const Value = struct {
10783 .err_name => continue :constant_key .{ .undef = error_union_type.payload_type },10842 .err_name => continue :constant_key .{ .undef = error_union_type.payload_type },
10784 .payload => |payload| {10843 .payload => |payload| {
10785 constant = payload;10844 constant = payload;
10786 constant_key = ip.indexToKey(payload);10845 constant_key = ip.indexToKey(constant);
10787 continue :constant_key constant_key;10846 continue :constant_key constant_key;
10788 },10847 },
10789 }10848 }
...@@ -10915,7 +10974,10 @@ pub const Value = struct {...@@ -10915,7 +10974,10 @@ pub const Value = struct {
10915 .addend = ptr.byte_offset,10974 .addend = ptr.byte_offset,
10916 },10975 },
10917 });10976 });
10918 try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));10977 if (ip.getNav(nav).getExtern(ip)) |_|
10978 try isel.emit(.ldr(mat.ra.x(), .{ .unsigned_offset = .{ .base = mat.ra.x(), .offset = 0 } }))
10979 else
10980 try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
10919 try isel.nav_relocs.append(zcu.gpa, .{10981 try isel.nav_relocs.append(zcu.gpa, .{
10920 .nav = nav,10982 .nav = nav,
10921 .reloc = .{10983 .reloc = .{
...@@ -11017,7 +11079,7 @@ pub const Value = struct {...@@ -11017,7 +11079,7 @@ pub const Value = struct {
11017 } } else .{ .undef = child_ty },11079 } } else .{ .undef = child_ty },
11018 else => |child| {11080 else => |child| {
11019 constant = child;11081 constant = child;
11020 constant_key = ip.indexToKey(child);11082 constant_key = ip.indexToKey(constant);
11021 continue :constant_key constant_key;11083 continue :constant_key constant_key;
11022 },11084 },
11023 };11085 };
...@@ -11040,7 +11102,7 @@ pub const Value = struct {...@@ -11040,7 +11102,7 @@ pub const Value = struct {
11040 },11102 },
11041 .repeated_elem => |repeated_elem| {11103 .repeated_elem => |repeated_elem| {
11042 constant = repeated_elem;11104 constant = repeated_elem;
11043 constant_key = ip.indexToKey(repeated_elem);11105 constant_key = ip.indexToKey(constant);
11044 continue :constant_key constant_key;11106 continue :constant_key constant_key;
11045 },11107 },
11046 };11108 };
...@@ -11099,6 +11161,28 @@ pub const Value = struct {...@@ -11099,6 +11161,28 @@ pub const Value = struct {
11099 }11161 }
11100 },11162 },
11101 },11163 },
11164 .un => |un| {
11165 const loaded_union = ip.loadUnionType(un.ty);
11166 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
11167 if (loaded_union.hasTag(ip)) {
11168 const tag_offset = union_layout.tagOffset();
11169 if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {
11170 offset -= tag_offset;
11171 continue :constant_key switch (ip.indexToKey(un.tag)) {
11172 else => unreachable,
11173 .int => |int| .{ .int = int },
11174 .enum_tag => |enum_tag| .{ .enum_tag = enum_tag },
11175 };
11176 }
11177 }
11178 const payload_offset = union_layout.payloadOffset();
11179 if (offset >= payload_offset and offset + size <= payload_offset + union_layout.payload_size) {
11180 offset -= payload_offset;
11181 constant = un.val;
11182 constant_key = ip.indexToKey(constant);
11183 continue :constant_key constant_key;
11184 }
11185 },
11102 else => {},11186 else => {},
11103 }11187 }
11104 var buffer: [16]u8 = @splat(0);11188 var buffer: [16]u8 = @splat(0);
...@@ -11188,7 +11272,7 @@ fn initValueAdvanced(...@@ -11188,7 +11272,7 @@ fn initValueAdvanced(
11188}11272}
11189pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {11273pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
11190 errdefer |err| @panic(@errorName(err));11274 errdefer |err| @panic(@errorName(err));
11191 const stderr = std.debug.lockStderrWriter(&.{});11275 const stderr, _ = std.debug.lockStderrWriter(&.{});
11192 defer std.debug.unlockStderrWriter();11276 defer std.debug.unlockStderrWriter();
1119311277
11194 const zcu = isel.pt.zcu;11278 const zcu = isel.pt.zcu;
...@@ -11259,7 +11343,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {...@@ -11259,7 +11343,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
11259 first = false;11343 first = false;
11260 };11344 };
11261 if (reverse_live_registers.get(vi)) |ra| {11345 if (reverse_live_registers.get(vi)) |ra| {
11262 try stderr.print("{s}{s}", .{ if (first) " <- " else ", ", @tagName(ra) });11346 try stderr.print("{s}{t}", .{ if (first) " <- " else ", ", ra });
11263 first = false;11347 first = false;
11264 }11348 }
11265 }11349 }
...@@ -11267,8 +11351,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {...@@ -11267,8 +11351,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
11267 switch (value.flags.parent_tag) {11351 switch (value.flags.parent_tag) {
11268 .unallocated => if (value.offset_from_parent != 0) try stderr.print(" +0x{x}", .{value.offset_from_parent}),11352 .unallocated => if (value.offset_from_parent != 0) try stderr.print(" +0x{x}", .{value.offset_from_parent}),
11269 .stack_slot => {11353 .stack_slot => {
11270 try stderr.print(" [{s}, #{s}0x{x}", .{11354 try stderr.print(" [{t}, #{s}0x{x}", .{
11271 @tagName(value.parent_payload.stack_slot.base),11355 value.parent_payload.stack_slot.base,
11272 if (value.parent_payload.stack_slot.offset < 0) "-" else "",11356 if (value.parent_payload.stack_slot.offset < 0) "-" else "",
11273 @abs(value.parent_payload.stack_slot.offset),11357 @abs(value.parent_payload.stack_slot.offset),
11274 });11358 });
...@@ -11282,7 +11366,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {...@@ -11282,7 +11366,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
11282 isel.fmtConstant(value.parent_payload.constant),11366 isel.fmtConstant(value.parent_payload.constant),
11283 }),11367 }),
11284 }11368 }
11285 try stderr.print(" align({s})", .{@tagName(value.flags.alignment)});11369 try stderr.print(" align({t})", .{value.flags.alignment});
11286 switch (value.flags.location_tag) {11370 switch (value.flags.location_tag) {
11287 .large => try stderr.print(" size=0x{x} large", .{value.location_payload.large.size}),11371 .large => try stderr.print(" size=0x{x} large", .{value.location_payload.large.size}),
11288 .small => {11372 .small => {
...@@ -11292,8 +11376,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {...@@ -11292,8 +11376,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
11292 .unsigned => {},11376 .unsigned => {},
11293 .signed => try stderr.writeAll(" signed"),11377 .signed => try stderr.writeAll(" signed"),
11294 }11378 }
11295 if (loc.hint != .zr) try stderr.print(" hint={s}", .{@tagName(loc.hint)});11379 if (loc.hint != .zr) try stderr.print(" hint={t}", .{loc.hint});
11296 if (loc.register != .zr) try stderr.print(" loc={s}", .{@tagName(loc.register)});11380 if (loc.register != .zr) try stderr.print(" loc={t}", .{loc.register});
11297 },11381 },
11298 }11382 }
11299 try stderr.print(" refs={d}\n", .{value.refs});11383 try stderr.print(" refs={d}\n", .{value.refs});
src/crash_report.zig+1-1
...@@ -95,7 +95,7 @@ fn dumpCrashContext() Io.Writer.Error!void {...@@ -95,7 +95,7 @@ fn dumpCrashContext() Io.Writer.Error!void {
9595
96 // TODO: this does mean that a different thread could grab the stderr mutex between the context96 // TODO: this does mean that a different thread could grab the stderr mutex between the context
97 // and the actual panic printing, which would be quite confusing.97 // and the actual panic printing, which would be quite confusing.
98 const stderr = std.debug.lockStderrWriter(&.{});98 const stderr, _ = std.debug.lockStderrWriter(&.{});
99 defer std.debug.unlockStderrWriter();99 defer std.debug.unlockStderrWriter();
100100
101 try stderr.writeAll("Compiler crash context:\n");101 try stderr.writeAll("Compiler crash context:\n");
src/fmt.zig+4-4
...@@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !...@@ -124,7 +124,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
124 try wip_errors.addZirErrorMessages(zir, tree, source_code, "<stdin>");124 try wip_errors.addZirErrorMessages(zir, tree, source_code, "<stdin>");
125 var error_bundle = try wip_errors.toOwnedBundle("");125 var error_bundle = try wip_errors.toOwnedBundle("");
126 defer error_bundle.deinit(gpa);126 defer error_bundle.deinit(gpa);
127 error_bundle.renderToStdErr(color.renderOptions());127 error_bundle.renderToStdErr(.{}, color);
128 process.exit(2);128 process.exit(2);
129 }129 }
130 } else {130 } else {
...@@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !...@@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
138 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, "<stdin>");138 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, "<stdin>");
139 var error_bundle = try wip_errors.toOwnedBundle("");139 var error_bundle = try wip_errors.toOwnedBundle("");
140 defer error_bundle.deinit(gpa);140 defer error_bundle.deinit(gpa);
141 error_bundle.renderToStdErr(color.renderOptions());141 error_bundle.renderToStdErr(.{}, color);
142 process.exit(2);142 process.exit(2);
143 }143 }
144 }144 }
...@@ -317,7 +317,7 @@ fn fmtPathFile(...@@ -317,7 +317,7 @@ fn fmtPathFile(
317 try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path);317 try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path);
318 var error_bundle = try wip_errors.toOwnedBundle("");318 var error_bundle = try wip_errors.toOwnedBundle("");
319 defer error_bundle.deinit(gpa);319 defer error_bundle.deinit(gpa);
320 error_bundle.renderToStdErr(fmt.color.renderOptions());320 error_bundle.renderToStdErr(.{}, fmt.color);
321 fmt.any_error = true;321 fmt.any_error = true;
322 }322 }
323 },323 },
...@@ -332,7 +332,7 @@ fn fmtPathFile(...@@ -332,7 +332,7 @@ fn fmtPathFile(
332 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path);332 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path);
333 var error_bundle = try wip_errors.toOwnedBundle("");333 var error_bundle = try wip_errors.toOwnedBundle("");
334 defer error_bundle.deinit(gpa);334 defer error_bundle.deinit(gpa);
335 error_bundle.renderToStdErr(fmt.color.renderOptions());335 error_bundle.renderToStdErr(.{}, fmt.color);
336 fmt.any_error = true;336 fmt.any_error = true;
337 }337 }
338 },338 },
src/libs/mingw.zig+4-4
...@@ -312,7 +312,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -312,7 +312,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
312 const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });312 const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
313313
314 if (comp.verbose_cc) print: {314 if (comp.verbose_cc) print: {
315 var stderr = std.debug.lockStderrWriter(&.{});315 var stderr, _ = std.debug.lockStderrWriter(&.{});
316 defer std.debug.unlockStderrWriter();316 defer std.debug.unlockStderrWriter();
317 nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;317 nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
318 nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;318 nosuspend stderr.print("include dir: {s}\n", .{include_dir}) catch break :print;
...@@ -332,11 +332,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -332,11 +332,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
332332
333 if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) {333 if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) {
334 var buffer: [64]u8 = undefined;334 var buffer: [64]u8 = undefined;
335 const w = std.debug.lockStderrWriter(&buffer);335 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
336 defer std.debug.unlockStderrWriter();336 defer std.debug.unlockStderrWriter();
337 for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {337 for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {
338 if (msg.kind == .@"fatal error" or msg.kind == .@"error") {338 if (msg.kind == .@"fatal error" or msg.kind == .@"error") {
339 msg.write(w, .detect(std.fs.File.stderr()), true) catch {};339 msg.write(w, ttyconf, true) catch {};
340 return error.AroPreprocessorFailed;340 return error.AroPreprocessorFailed;
341 }341 }
342 }342 }
...@@ -356,7 +356,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {...@@ -356,7 +356,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
356 error.OutOfMemory => |e| return e,356 error.OutOfMemory => |e| return e,
357 error.ParseError => {357 error.ParseError => {
358 var buffer: [64]u8 = undefined;358 var buffer: [64]u8 = undefined;
359 const w = std.debug.lockStderrWriter(&buffer);359 const w, _ = std.debug.lockStderrWriter(&buffer);
360 defer std.debug.unlockStderrWriter();360 defer std.debug.unlockStderrWriter();
361 try w.writeAll("error: ");361 try w.writeAll("error: ");
362 try def_diagnostics.writeMsg(w, input);362 try def_diagnostics.writeMsg(w, input);
src/libs/mingw/def.zig+1-1
...@@ -1028,7 +1028,7 @@ fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, ex...@@ -1028,7 +1028,7 @@ fn testParse(machine_type: std.coff.IMAGE.FILE.MACHINE, source: [:0]const u8, ex
1028 const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) {1028 const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) {
1029 error.OutOfMemory => |e| return e,1029 error.OutOfMemory => |e| return e,
1030 error.ParseError => {1030 error.ParseError => {
1031 const stderr = std.debug.lockStderrWriter(&.{});1031 const stderr, _ = std.debug.lockStderrWriter(&.{});
1032 defer std.debug.unlockStderrWriter();1032 defer std.debug.unlockStderrWriter();
1033 try diagnostics.writeMsg(stderr, source);1033 try diagnostics.writeMsg(stderr, source);
1034 try stderr.writeByte('\n');1034 try stderr.writeByte('\n');
src/link.zig+1-1
...@@ -2215,7 +2215,7 @@ fn resolvePathInputLib(...@@ -2215,7 +2215,7 @@ fn resolvePathInputLib(
2215 var error_bundle = try wip_errors.toOwnedBundle("");2215 var error_bundle = try wip_errors.toOwnedBundle("");
2216 defer error_bundle.deinit(gpa);2216 defer error_bundle.deinit(gpa);
22172217
2218 error_bundle.renderToStdErr(color.renderOptions());2218 error_bundle.renderToStdErr(.{}, color);
22192219
2220 std.process.exit(1);2220 std.process.exit(1);
2221 }2221 }
src/link/Coff.zig+1-1
...@@ -2335,7 +2335,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe...@@ -2335,7 +2335,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
2335}2335}
23362336
2337pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void {2337pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void {
2338 const w = std.debug.lockStderrWriter(&.{});2338 const w, _ = std.debug.lockStderrWriter(&.{});
2339 defer std.debug.unlockStderrWriter();2339 defer std.debug.unlockStderrWriter();
2340 coff.printNode(tid, w, .root, 0) catch {};2340 coff.printNode(tid, w, .root, 0) catch {};
2341}2341}
src/link/Elf2.zig+1-1
...@@ -1965,7 +1965,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm...@@ -1965,7 +1965,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
1965}1965}
19661966
1967pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {1967pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {
1968 const w = std.debug.lockStderrWriter(&.{});1968 const w, _ = std.debug.lockStderrWriter(&.{});
1969 defer std.debug.unlockStderrWriter();1969 defer std.debug.unlockStderrWriter();
1970 elf.printNode(tid, w, .root, 0) catch {};1970 elf.printNode(tid, w, .root, 0) catch {};
1971}1971}
src/main.zig+9-9
...@@ -4520,7 +4520,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)...@@ -4520,7 +4520,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
4520 defer errors.deinit(comp.gpa);4520 defer errors.deinit(comp.gpa);
45214521
4522 if (errors.errorMessageCount() > 0) {4522 if (errors.errorMessageCount() > 0) {
4523 errors.renderToStdErr(color.renderOptions());4523 errors.renderToStdErr(.{}, color);
4524 return error.CompileErrorsReported;4524 return error.CompileErrorsReported;
4525 }4525 }
4526}4526}
...@@ -4573,7 +4573,7 @@ fn cmdTranslateC(...@@ -4573,7 +4573,7 @@ fn cmdTranslateC(
4573 return;4573 return;
4574 } else {4574 } else {
4575 const color: Color = .auto;4575 const color: Color = .auto;
4576 result.errors.renderToStdErr(color.renderOptions());4576 result.errors.renderToStdErr(.{}, color);
4577 process.exit(1);4577 process.exit(1);
4578 }4578 }
4579 }4579 }
...@@ -5199,7 +5199,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5199,7 +5199,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
51995199
5200 if (fetch.error_bundle.root_list.items.len > 0) {5200 if (fetch.error_bundle.root_list.items.len > 0) {
5201 var errors = try fetch.error_bundle.toOwnedBundle("");5201 var errors = try fetch.error_bundle.toOwnedBundle("");
5202 errors.renderToStdErr(color.renderOptions());5202 errors.renderToStdErr(.{}, color);
5203 process.exit(1);5203 process.exit(1);
5204 }5204 }
52055205
...@@ -6135,7 +6135,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6135,7 +6135,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
6135 try wip_errors.init(arena);6135 try wip_errors.init(arena);
6136 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);6136 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);
6137 var error_bundle = try wip_errors.toOwnedBundle("");6137 var error_bundle = try wip_errors.toOwnedBundle("");
6138 error_bundle.renderToStdErr(color.renderOptions());6138 error_bundle.renderToStdErr(.{}, color);
6139 if (zir.loweringFailed()) {6139 if (zir.loweringFailed()) {
6140 process.exit(1);6140 process.exit(1);
6141 }6141 }
...@@ -6206,7 +6206,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6206,7 +6206,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
6206 try wip_errors.init(arena);6206 try wip_errors.init(arena);
6207 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);6207 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);
6208 var error_bundle = try wip_errors.toOwnedBundle("");6208 var error_bundle = try wip_errors.toOwnedBundle("");
6209 error_bundle.renderToStdErr(color.renderOptions());6209 error_bundle.renderToStdErr(.{}, color);
6210 process.exit(1);6210 process.exit(1);
6211 }6211 }
62126212
...@@ -6479,7 +6479,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6479,7 +6479,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
6479 try wip_errors.init(arena);6479 try wip_errors.init(arena);
6480 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);6480 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);
6481 var error_bundle = try wip_errors.toOwnedBundle("");6481 var error_bundle = try wip_errors.toOwnedBundle("");
6482 error_bundle.renderToStdErr(color.renderOptions());6482 error_bundle.renderToStdErr(.{}, color);
6483 process.exit(1);6483 process.exit(1);
6484 }6484 }
64856485
...@@ -6491,7 +6491,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {...@@ -6491,7 +6491,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
6491 try wip_errors.init(arena);6491 try wip_errors.init(arena);
6492 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);6492 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);
6493 var error_bundle = try wip_errors.toOwnedBundle("");6493 var error_bundle = try wip_errors.toOwnedBundle("");
6494 error_bundle.renderToStdErr(color.renderOptions());6494 error_bundle.renderToStdErr(.{}, color);
6495 process.exit(1);6495 process.exit(1);
6496 }6496 }
64976497
...@@ -6948,7 +6948,7 @@ fn cmdFetch(...@@ -6948,7 +6948,7 @@ fn cmdFetch(
69486948
6949 if (fetch.error_bundle.root_list.items.len > 0) {6949 if (fetch.error_bundle.root_list.items.len > 0) {
6950 var errors = try fetch.error_bundle.toOwnedBundle("");6950 var errors = try fetch.error_bundle.toOwnedBundle("");
6951 errors.renderToStdErr(color.renderOptions());6951 errors.renderToStdErr(.{}, color);
6952 process.exit(1);6952 process.exit(1);
6953 }6953 }
69546954
...@@ -7304,7 +7304,7 @@ fn loadManifest(...@@ -7304,7 +7304,7 @@ fn loadManifest(
73047304
7305 var error_bundle = try wip_errors.toOwnedBundle("");7305 var error_bundle = try wip_errors.toOwnedBundle("");
7306 defer error_bundle.deinit(gpa);7306 defer error_bundle.deinit(gpa);
7307 error_bundle.renderToStdErr(options.color.renderOptions());7307 error_bundle.renderToStdErr(.{}, options.color);
73087308
7309 process.exit(2);7309 process.exit(2);
7310 }7310 }
test/behavior/enum.zig-2
...@@ -899,7 +899,6 @@ test "enum value allocation" {...@@ -899,7 +899,6 @@ test "enum value allocation" {
899}899}
900900
901test "enum literal casting to tagged union" {901test "enum literal casting to tagged union" {
902 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
903 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;902 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
904 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO903 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
905904
...@@ -935,7 +934,6 @@ test "enum literal casting to error union with payload enum" {...@@ -935,7 +934,6 @@ test "enum literal casting to error union with payload enum" {
935}934}
936935
937test "constant enum initialization with differing sizes" {936test "constant enum initialization with differing sizes" {
938 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
939 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;937 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
940 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO938 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
941 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;939 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/optional.zig-2
...@@ -149,7 +149,6 @@ test "nested optional field in struct" {...@@ -149,7 +149,6 @@ test "nested optional field in struct" {
149}149}
150150
151test "equality compare optionals and non-optionals" {151test "equality compare optionals and non-optionals" {
152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
153 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO152 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
154 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO153 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
155 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -209,7 +208,6 @@ test "equality compare optionals and non-optionals" {...@@ -209,7 +208,6 @@ test "equality compare optionals and non-optionals" {
209}208}
210209
211test "compare optionals with modified payloads" {210test "compare optionals with modified payloads" {
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;211 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
214212
215 var lhs: ?bool = false;213 var lhs: ?bool = false;
test/behavior/switch.zig-2
...@@ -576,7 +576,6 @@ test "switch with null and T peer types and inferred result location type" {...@@ -576,7 +576,6 @@ test "switch with null and T peer types and inferred result location type" {
576}576}
577577
578test "switch prongs with cases with identical payload types" {578test "switch prongs with cases with identical payload types" {
579 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
580 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO579 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
581 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO580 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
582581
...@@ -824,7 +823,6 @@ test "comptime inline switch" {...@@ -824,7 +823,6 @@ test "comptime inline switch" {
824}823}
825824
826test "switch capture peer type resolution" {825test "switch capture peer type resolution" {
827 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
828 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;826 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
829827
830 const U = union(enum) {828 const U = union(enum) {
test/behavior/tuple.zig-1
...@@ -496,7 +496,6 @@ test "anon tuple field referencing comptime var isn't comptime" {...@@ -496,7 +496,6 @@ test "anon tuple field referencing comptime var isn't comptime" {
496}496}
497497
498test "tuple with runtime value coerced into a slice with a sentinel" {498test "tuple with runtime value coerced into a slice with a sentinel" {
499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
500 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO499 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
502 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;501 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/union.zig-6
...@@ -208,7 +208,6 @@ const Payload = union(Letter) {...@@ -208,7 +208,6 @@ const Payload = union(Letter) {
208};208};
209209
210test "union with specified enum tag" {210test "union with specified enum tag" {
211 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
212 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;213 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
...@@ -219,7 +218,6 @@ test "union with specified enum tag" {...@@ -219,7 +218,6 @@ test "union with specified enum tag" {
219}218}
220219
221test "packed union generates correctly aligned type" {220test "packed union generates correctly aligned type" {
222 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;223 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
...@@ -605,7 +603,6 @@ fn returnAnInt(x: i32) TaggedFoo {...@@ -605,7 +603,6 @@ fn returnAnInt(x: i32) TaggedFoo {
605}603}
606604
607test "tagged union with all void fields but a meaningful tag" {605test "tagged union with all void fields but a meaningful tag" {
608 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
609 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
610 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
611608
...@@ -1032,7 +1029,6 @@ test "containers with single-field enums" {...@@ -1032,7 +1029,6 @@ test "containers with single-field enums" {
1032}1029}
10331030
1034test "@unionInit on union with tag but no fields" {1031test "@unionInit on union with tag but no fields" {
1035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1036 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1032 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1037 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1033 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10381034
...@@ -1446,8 +1442,6 @@ test "access the tag of a global tagged union" {...@@ -1446,8 +1442,6 @@ test "access the tag of a global tagged union" {
1446}1442}
14471443
1448test "coerce enum literal to union in result loc" {1444test "coerce enum literal to union in result loc" {
1449 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1450
1451 const U = union(enum) {1445 const U = union(enum) {
1452 a,1446 a,
1453 b: u8,1447 b: u8,
tools/gen_spirv_spec.zig+3-4
...@@ -89,10 +89,9 @@ pub fn main() !void {...@@ -89,10 +89,9 @@ pub fn main() !void {
89 const output = allocating.written()[0 .. allocating.written().len - 1 :0];89 const output = allocating.written()[0 .. allocating.written().len - 1 :0];
9090
91 var tree = try std.zig.Ast.parse(allocator, output, .zig);91 var tree = try std.zig.Ast.parse(allocator, output, .zig);
92 var color: std.zig.Color = .on;
9392
94 if (tree.errors.len != 0) {93 if (tree.errors.len != 0) {
95 try std.zig.printAstErrorsToStderr(allocator, tree, "", color);94 try std.zig.printAstErrorsToStderr(allocator, tree, "", .auto);
96 return;95 return;
97 }96 }
9897
...@@ -104,7 +103,7 @@ pub fn main() !void {...@@ -104,7 +103,7 @@ pub fn main() !void {
104 try wip_errors.addZirErrorMessages(zir, tree, output, "");103 try wip_errors.addZirErrorMessages(zir, tree, output, "");
105 var error_bundle = try wip_errors.toOwnedBundle("");104 var error_bundle = try wip_errors.toOwnedBundle("");
106 defer error_bundle.deinit(allocator);105 defer error_bundle.deinit(allocator);
107 error_bundle.renderToStdErr(color.renderOptions());106 error_bundle.renderToStdErr(.{}, .auto);
108 }107 }
109108
110 const formatted_output = try tree.renderAlloc(allocator);109 const formatted_output = try tree.renderAlloc(allocator);
...@@ -931,7 +930,7 @@ fn parseHexInt(text: []const u8) !u31 {...@@ -931,7 +930,7 @@ fn parseHexInt(text: []const u8) !u31 {
931}930}
932931
933fn usageAndExit(arg0: []const u8, code: u8) noreturn {932fn usageAndExit(arg0: []const u8, code: u8) noreturn {
934 const stderr = std.debug.lockStderrWriter(&.{});933 const stderr, _ = std.debug.lockStderrWriter(&.{});
935 stderr.print(934 stderr.print(
936 \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>935 \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>
937 \\936 \\
tools/generate_linux_syscalls.zig+3-1
...@@ -177,7 +177,9 @@ pub fn main() !void {...@@ -177,7 +177,9 @@ pub fn main() !void {
177177
178 const args = try std.process.argsAlloc(gpa);178 const args = try std.process.argsAlloc(gpa);
179 if (args.len < 2 or mem.eql(u8, args[1], "--help")) {179 if (args.len < 2 or mem.eql(u8, args[1], "--help")) {
180 usage(std.debug.lockStderrWriter(&.{}), args[0]) catch std.process.exit(2);180 const w, _ = std.debug.lockStderrWriter(&.{});
181 defer std.debug.unlockStderrWriter();
182 usage(w, args[0]) catch std.process.exit(2);
181 std.process.exit(1);183 std.process.exit(1);
182 }184 }
183 const linux_path = args[1];185 const linux_path = args[1];
tools/incr-check.zig+5-10
...@@ -340,8 +340,7 @@ const Eval = struct {...@@ -340,8 +340,7 @@ const Eval = struct {
340 .unknown => return,340 .unknown => return,
341 .compile_errors => |ce| ce,341 .compile_errors => |ce| ce,
342 .stdout, .exit_code => {342 .stdout, .exit_code => {
343 const color: std.zig.Color = .auto;343 error_bundle.renderToStdErr(.{}, .auto);
344 error_bundle.renderToStdErr(color.renderOptions());
345 eval.fatal("update '{s}': unexpected compile errors", .{update.name});344 eval.fatal("update '{s}': unexpected compile errors", .{update.name});
346 },345 },
347 };346 };
...@@ -350,8 +349,7 @@ const Eval = struct {...@@ -350,8 +349,7 @@ const Eval = struct {
350349
351 for (error_bundle.getMessages()) |err_idx| {350 for (error_bundle.getMessages()) |err_idx| {
352 if (expected_idx == expected.errors.len) {351 if (expected_idx == expected.errors.len) {
353 const color: std.zig.Color = .auto;352 error_bundle.renderToStdErr(.{}, .auto);
354 error_bundle.renderToStdErr(color.renderOptions());
355 eval.fatal("update '{s}': more errors than expected", .{update.name});353 eval.fatal("update '{s}': more errors than expected", .{update.name});
356 }354 }
357 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);355 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
...@@ -359,8 +357,7 @@ const Eval = struct {...@@ -359,8 +357,7 @@ const Eval = struct {
359357
360 for (error_bundle.getNotes(err_idx)) |note_idx| {358 for (error_bundle.getNotes(err_idx)) |note_idx| {
361 if (expected_idx == expected.errors.len) {359 if (expected_idx == expected.errors.len) {
362 const color: std.zig.Color = .auto;360 error_bundle.renderToStdErr(.{}, .auto);
363 error_bundle.renderToStdErr(color.renderOptions());
364 eval.fatal("update '{s}': more error notes than expected", .{update.name});361 eval.fatal("update '{s}': more error notes than expected", .{update.name});
365 }362 }
366 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);363 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
...@@ -369,8 +366,7 @@ const Eval = struct {...@@ -369,8 +366,7 @@ const Eval = struct {
369 }366 }
370367
371 if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) {368 if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) {
372 const color: std.zig.Color = .auto;369 error_bundle.renderToStdErr(.{}, .auto);
373 error_bundle.renderToStdErr(color.renderOptions());
374 eval.fatal("update '{s}': unexpected compile log output", .{update.name});370 eval.fatal("update '{s}': unexpected compile log output", .{update.name});
375 }371 }
376 }372 }
...@@ -404,8 +400,7 @@ const Eval = struct {...@@ -404,8 +400,7 @@ const Eval = struct {
404 expected.column != src.column + 1 or400 expected.column != src.column + 1 or
405 !std.mem.eql(u8, expected.msg, msg))401 !std.mem.eql(u8, expected.msg, msg))
406 {402 {
407 const color: std.zig.Color = .auto;403 eb.renderToStdErr(.{}, .auto);
408 eb.renderToStdErr(color.renderOptions());
409 eval.fatal("update '{s}': compile error did not match expected error", .{update.name});404 eval.fatal("update '{s}': compile error did not match expected error", .{update.name});
410 }405 }
411 }406 }
tools/update_clang_options.zig+3-1
...@@ -961,7 +961,9 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {...@@ -961,7 +961,9 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
961}961}
962962
963fn printUsageAndExit(arg0: []const u8) noreturn {963fn printUsageAndExit(arg0: []const u8) noreturn {
964 printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);964 const w, _ = std.debug.lockStderrWriter(&.{});
965 defer std.debug.unlockStderrWriter();
966 printUsage(w, arg0) catch std.process.exit(2);
965 std.process.exit(1);967 std.process.exit(1);
966}968}
967969
tools/update_cpu_features.zig+1-1
...@@ -2167,7 +2167,7 @@ fn processOneTarget(job: Job) void {...@@ -2167,7 +2167,7 @@ fn processOneTarget(job: Job) void {
2167}2167}
21682168
2169fn usageAndExit(arg0: []const u8, code: u8) noreturn {2169fn usageAndExit(arg0: []const u8, code: u8) noreturn {
2170 const stderr = std.debug.lockStderrWriter(&.{});2170 const stderr, _ = std.debug.lockStderrWriter(&.{});
2171 stderr.print(2171 stderr.print(
2172 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]2172 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]
2173 \\2173 \\
tools/update_crc_catalog.zig+3-1
...@@ -190,7 +190,9 @@ pub fn main() anyerror!void {...@@ -190,7 +190,9 @@ pub fn main() anyerror!void {
190}190}
191191
192fn printUsageAndExit(arg0: []const u8) noreturn {192fn printUsageAndExit(arg0: []const u8) noreturn {
193 printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2);193 const w, _ = std.debug.lockStderrWriter(&.{});
194 defer std.debug.unlockStderrWriter();
195 printUsage(w, arg0) catch std.process.exit(2);
194 std.process.exit(1);196 std.process.exit(1);
195}197}
196198