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 {
442442 if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{});
443443 }
444444
445 const stderr: std.fs.File = .stderr();
446 const ttyconf = get_tty_conf(color, stderr);
445 const ttyconf = color.detectTtyConf();
447446 switch (ttyconf) {
448447 .no_color => try graph.env_map.put("NO_COLOR", "1"),
449448 .escape_codes => try graph.env_map.put("CLICOLOR_FORCE", "1"),
......@@ -522,9 +521,9 @@ pub fn main() !void {
522521 .error_style = error_style,
523522 .multiline_errors = multiline_errors,
524523 .summary = summary orelse if (watch or webui_listen != null) .line else .failures,
525 .ttyconf = ttyconf,
526 .stderr = stderr,
527524 .thread_pool = undefined,
525
526 .ttyconf = ttyconf,
528527 };
529528 defer {
530529 run.memory_blocked_steps.deinit(gpa);
......@@ -563,9 +562,9 @@ pub fn main() !void {
563562 break :ws .init(.{
564563 .gpa = gpa,
565564 .thread_pool = &run.thread_pool,
565 .ttyconf = ttyconf,
566566 .graph = &graph,
567567 .all_steps = run.step_stack.keys(),
568 .ttyconf = run.ttyconf,
569568 .root_prog_node = main_progress_node,
570569 .watch = watch,
571570 .listen_address = listen_address,
......@@ -578,7 +577,7 @@ pub fn main() !void {
578577 }
579578
580579 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);
582581 defer std.debug.unlockStderrWriter();
583582 try bw.writeAll("\x1B[2J\x1B[3J\x1B[H");
584583 }) {
......@@ -682,13 +681,14 @@ const Run = struct {
682681 /// Allocated into `gpa`.
683682 step_stack: std.AutoArrayHashMapUnmanaged(*Step, void),
684683 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
686688 claimed_rss: usize,
687689 error_style: ErrorStyle,
688690 multiline_errors: MultilineErrors,
689691 summary: Summary,
690 ttyconf: tty.Config,
691 stderr: File,
692692};
693693
694694fn prepare(
......@@ -834,8 +834,6 @@ fn runStepNames(
834834 }
835835 }
836836
837 const ttyconf = run.ttyconf;
838
839837 if (fuzz) |mode| blk: {
840838 switch (builtin.os.tag) {
841839 // Current implementation depends on two things that need to be ported to Windows:
......@@ -863,9 +861,9 @@ fn runStepNames(
863861 gpa,
864862 io,
865863 thread_pool,
864 run.ttyconf,
866865 step_stack.keys(),
867866 parent_prog_node,
868 ttyconf,
869867 mode,
870868 ) catch |err| fatal("failed to start fuzzer: {s}", .{@errorName(err)});
871869 defer f.deinit();
......@@ -890,8 +888,9 @@ fn runStepNames(
890888 .none => break :summary,
891889 }
892890
893 const w = std.debug.lockStderrWriter(&stdio_buffer_allocation);
891 const w, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
894892 defer std.debug.unlockStderrWriter();
893 const ttyconf = run.ttyconf;
895894
896895 const total_count = success_count + failure_count + pending_count + skipped_count;
897896 ttyconf.setColor(w, .cyan) catch {};
......@@ -1399,9 +1398,10 @@ fn workerMakeOneStep(
13991398 const show_error_msgs = s.result_error_msgs.items.len > 0;
14001399 const show_stderr = s.result_stderr.len > 0;
14011400 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);
14031402 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 {};
14051405 }
14061406
14071407 handle_result: {
......@@ -1465,11 +1465,10 @@ pub fn printErrorMessages(
14651465 failing_step: *Step,
14661466 options: std.zig.ErrorBundle.RenderOptions,
14671467 stderr: *Writer,
1468 ttyconf: tty.Config,
14681469 error_style: ErrorStyle,
14691470 multiline_errors: MultilineErrors,
14701471) !void {
1471 const ttyconf = options.ttyconf;
1472
14731472 if (error_style.verboseContext()) {
14741473 // Provide context for where these error messages are coming from by
14751474 // printing the corresponding Step subtree.
......@@ -1513,7 +1512,7 @@ pub fn printErrorMessages(
15131512 }
15141513 }
15151514
1516 try failing_step.result_error_bundle.renderToWriter(options, stderr);
1515 try failing_step.result_error_bundle.renderToWriter(options, stderr, ttyconf);
15171516
15181517 for (failing_step.result_error_msgs.items) |msg| {
15191518 try ttyconf.setColor(stderr, .red);
......@@ -1759,14 +1758,6 @@ const ErrorStyle = enum {
17591758const MultilineErrors = enum { indent, newline, none };
17601759const 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
17701761fn fatalWithHint(comptime f: []const u8, args: anytype) noreturn {
17711762 std.debug.print(f ++ "\n access the help menu with 'zig build -h'\n", args);
17721763 process.exit(1);
lib/compiler/resinator/cli.zig+3-3
......@@ -124,10 +124,10 @@ pub const Diagnostics = struct {
124124 try self.errors.append(self.allocator, error_details);
125125 }
126126
127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8, config: std.Io.tty.Config) void {
128 const stderr = std.debug.lockStderrWriter(&.{});
127 pub fn renderToStdErr(self: *Diagnostics, args: []const []const u8) void {
128 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
129129 defer std.debug.unlockStderrWriter();
130 self.renderToWriter(args, stderr, config) catch return;
130 self.renderToWriter(args, stderr, ttyconf) catch return;
131131 }
132132
133133 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 {
6767 return @intCast(index);
6868 }
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 {
7171 const io = self.io;
72 const stderr = std.debug.lockStderrWriter(&.{});
72 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
7373 defer std.debug.unlockStderrWriter();
7474 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;
7676 }
7777 }
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
8479 pub fn contains(self: *const Diagnostics, err: ErrorDetails.Error) bool {
8580 for (self.errors.items) |details| {
8681 if (details.err == err) return true;
lib/compiler/resinator/main.zig+29-34
......@@ -28,13 +28,11 @@ pub fn main() !void {
2828 defer arena_state.deinit();
2929 const arena = arena_state.allocator();
3030
31 const stderr = std.fs.File.stderr();
32 const stderr_config = std.Io.tty.detectConfig(stderr);
33
3431 const args = try std.process.argsAlloc(arena);
3532
3633 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", .{});
3836 std.process.exit(1);
3937 }
4038 const zig_lib_dir = args[1];
......@@ -56,9 +54,7 @@ pub fn main() !void {
5654 .in = undefined, // won't be receiving messages
5755 },
5856 },
59 false => .{
60 .tty = stderr_config,
61 },
57 false => .stderr,
6258 };
6359
6460 var options = options: {
......@@ -75,12 +71,14 @@ pub fn main() !void {
7571
7672 if (!zig_integration) {
7773 // print any warnings/notes
78 cli_diagnostics.renderToStdErr(cli_args, stderr_config);
74 cli_diagnostics.renderToStdErr(cli_args);
7975 // If there was something printed, then add an extra newline separator
8076 // so that there is a clear separation between the cli diagnostics and whatever
8177 // gets printed after
8278 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');
8482 }
8583 }
8684 break :options options;
......@@ -130,17 +128,18 @@ pub fn main() !void {
130128 const aro_arena = aro_arena_state.allocator();
131129
132130 var stderr_buf: [512]u8 = undefined;
133 var stderr_writer = stderr.writer(&stderr_buf);
134 var diagnostics: aro.Diagnostics = switch (zig_integration) {
135 false => .{ .output = .{ .to_writer = .{
136 .writer = &stderr_writer.interface,
137 .color = stderr_config,
138 } } },
139 true => .{ .output = .{ .to_list = .{
140 .arena = .init(gpa),
141 } } },
142 };
143 defer diagnostics.deinit();
131 var diagnostics: aro.Diagnostics = .{ .output = output: {
132 if (zig_integration) break :output .{ .to_list = .{ .arena = .init(gpa) } };
133 const w, const ttyconf = std.debug.lockStderrWriter(&stderr_buf);
134 break :output .{ .to_writer = .{
135 .writer = w,
136 .color = ttyconf,
137 } };
138 } };
139 defer {
140 diagnostics.deinit();
141 if (!zig_integration) std.debug.unlockStderrWriter();
142 }
144143
145144 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());
146145 defer comp.deinit();
......@@ -307,7 +306,7 @@ pub fn main() !void {
307306
308307 // print any warnings/notes
309308 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);
311310 }
312311
313312 // write the depfile
......@@ -660,7 +659,7 @@ const SourceMappings = @import("source_mapping.zig").SourceMappings;
660659
661660const ErrorHandler = union(enum) {
662661 server: std.zig.Server,
663 tty: std.Io.tty.Config,
662 stderr,
664663
665664 pub fn emitCliDiagnostics(
666665 self: *ErrorHandler,
......@@ -675,9 +674,7 @@ const ErrorHandler = union(enum) {
675674
676675 try server.serveErrorBundle(error_bundle);
677676 },
678 .tty => {
679 diagnostics.renderToStdErr(args, self.tty);
680 },
677 .stderr => diagnostics.renderToStdErr(args),
681678 }
682679 }
683680
......@@ -698,11 +695,11 @@ const ErrorHandler = union(enum) {
698695
699696 try server.serveErrorBundle(error_bundle);
700697 },
701 .tty => {
698 .stderr => {
702699 // aro errors have already been emitted
703 const stderr = std.debug.lockStderrWriter(&.{});
700 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
704701 defer std.debug.unlockStderrWriter();
705 try renderErrorMessage(stderr, self.tty, .err, "{s}", .{fail_msg});
702 try renderErrorMessage(stderr, ttyconf, .err, "{s}", .{fail_msg});
706703 },
707704 }
708705 }
......@@ -722,9 +719,7 @@ const ErrorHandler = union(enum) {
722719
723720 try server.serveErrorBundle(error_bundle);
724721 },
725 .tty => {
726 diagnostics.renderToStdErr(cwd, source, self.tty, mappings);
727 },
722 .stderr => diagnostics.renderToStdErr(cwd, source, mappings),
728723 }
729724 }
730725
......@@ -745,10 +740,10 @@ const ErrorHandler = union(enum) {
745740
746741 try server.serveErrorBundle(error_bundle);
747742 },
748 .tty => {
749 const stderr = std.debug.lockStderrWriter(&.{});
743 .stderr => {
744 const stderr, const ttyconf = std.debug.lockStderrWriter(&.{});
750745 defer std.debug.unlockStderrWriter();
751 try renderErrorMessage(stderr, self.tty, msg_type, format, args);
746 try renderErrorMessage(stderr, ttyconf, msg_type, format, args);
752747 },
753748 }
754749 }
lib/compiler/std-docs.zig+1-2
......@@ -394,8 +394,7 @@ fn buildWasmBinary(
394394 }
395395
396396 if (result_error_bundle.errorMessageCount() > 0) {
397 const color = std.zig.Color.auto;
398 result_error_bundle.renderToStdErr(color.renderOptions());
397 result_error_bundle.renderToStdErr(.{}, true);
399398 std.log.err("the following command failed with {d} compilation errors:\n{s}", .{
400399 result_error_bundle.errorMessageCount(),
401400 try std.Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/Build.zig+5-7
......@@ -2257,8 +2257,8 @@ pub const GeneratedFile = struct {
22572257
22582258 pub fn getPath2(gen: GeneratedFile, src_builder: *Build, asking_step: ?*Step) []const u8 {
22592259 return gen.path orelse {
2260 const w = debug.lockStderrWriter(&.{});
2261 dumpBadGetPathHelp(gen.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
2260 const w, const ttyconf = debug.lockStderrWriter(&.{});
2261 dumpBadGetPathHelp(gen.step, w, ttyconf, src_builder, asking_step) catch {};
22622262 debug.unlockStderrWriter();
22632263 @panic("misconfigured build script");
22642264 };
......@@ -2466,8 +2466,8 @@ pub const LazyPath = union(enum) {
24662466 var file_path: Cache.Path = .{
24672467 .root_dir = Cache.Directory.cwd(),
24682468 .sub_path = gen.file.path orelse {
2469 const w = debug.lockStderrWriter(&.{});
2470 dumpBadGetPathHelp(gen.file.step, w, .detect(.stderr()), src_builder, asking_step) catch {};
2469 const w, const ttyconf = debug.lockStderrWriter(&.{});
2470 dumpBadGetPathHelp(gen.file.step, w, ttyconf, src_builder, asking_step) catch {};
24712471 debug.unlockStderrWriter();
24722472 @panic("misconfigured build script");
24732473 },
......@@ -2558,13 +2558,11 @@ fn dumpBadDirnameHelp(
25582558 comptime msg: []const u8,
25592559 args: anytype,
25602560) anyerror!void {
2561 const w = debug.lockStderrWriter(&.{});
2561 const w, const tty_config = debug.lockStderrWriter(&.{});
25622562 defer debug.unlockStderrWriter();
25632563
25642564 try w.print(msg, args);
25652565
2566 const tty_config = std.Io.tty.detectConfig(.stderr());
2567
25682566 if (fail_step) |s| {
25692567 tty_config.setColor(w, .red) catch {};
25702568 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");
1616
1717gpa: Allocator,
1818io: Io,
19ttyconf: tty.Config,
1920mode: Mode,
2021
2122/// Allocated into `gpa`.
......@@ -25,7 +26,6 @@ wait_group: std.Thread.WaitGroup,
2526root_prog_node: std.Progress.Node,
2627prog_node: std.Progress.Node,
2728thread_pool: *std.Thread.Pool,
28ttyconf: tty.Config,
2929
3030/// Protects `coverage_files`.
3131coverage_mutex: std.Thread.Mutex,
......@@ -79,9 +79,9 @@ pub fn init(
7979 gpa: Allocator,
8080 io: Io,
8181 thread_pool: *std.Thread.Pool,
82 ttyconf: tty.Config,
8283 all_steps: []const *Build.Step,
8384 root_prog_node: std.Progress.Node,
84 ttyconf: tty.Config,
8585 mode: Mode,
8686) Allocator.Error!Fuzz {
8787 const run_steps: []const *Step.Run = steps: {
......@@ -115,11 +115,11 @@ pub fn init(
115115 return .{
116116 .gpa = gpa,
117117 .io = io,
118 .ttyconf = ttyconf,
118119 .mode = mode,
119120 .run_steps = run_steps,
120121 .wait_group = .{},
121122 .thread_pool = thread_pool,
122 .ttyconf = ttyconf,
123123 .root_prog_node = root_prog_node,
124124 .prog_node = .none,
125125 .coverage_files = .empty,
......@@ -158,7 +158,7 @@ pub fn deinit(fuzz: *Fuzz) void {
158158 fuzz.gpa.free(fuzz.run_steps);
159159}
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 {
162162 rebuildTestsWorkerRunFallible(run, gpa, ttyconf, parent_prog_node) catch |err| {
163163 const compile = run.producer.?;
164164 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
167167 };
168168}
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 {
171171 const compile = run.producer.?;
172172 const prog_node = parent_prog_node.start(compile.step.name, 0);
173173 defer prog_node.end();
......@@ -180,9 +180,9 @@ fn rebuildTestsWorkerRunFallible(run: *Step.Run, gpa: Allocator, ttyconf: std.Io
180180
181181 if (show_error_msgs or show_compile_errors or show_stderr) {
182182 var buf: [256]u8 = undefined;
183 const w = std.debug.lockStderrWriter(&buf);
183 const w, _ = std.debug.lockStderrWriter(&buf);
184184 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 {};
186186 }
187187
188188 const rebuilt_bin_path = result catch |err| switch (err) {
......@@ -206,9 +206,9 @@ fn fuzzWorkerRun(
206206 run.rerunInFuzzMode(fuzz, unit_test_index, prog_node) catch |err| switch (err) {
207207 error.MakeFailed => {
208208 var buf: [256]u8 = undefined;
209 const w = std.debug.lockStderrWriter(&buf);
209 const w, _ = std.debug.lockStderrWriter(&buf);
210210 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 {};
212212 return;
213213 },
214214 else => {
lib/std/Build/Step/Compile.zig+5-6
......@@ -1056,15 +1056,15 @@ fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking
10561056 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
10571057
10581058 const generated_file = maybe_path orelse {
1059 const w = std.debug.lockStderrWriter(&.{});
1060 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
1059 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1060 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
10611061 std.debug.unlockStderrWriter();
10621062 @panic("missing emit option for " ++ tag_name);
10631063 };
10641064
10651065 const path = generated_file.path orelse {
1066 const w = std.debug.lockStderrWriter(&.{});
1067 std.Build.dumpBadGetPathHelp(&compile.step, w, .detect(.stderr()), compile.step.owner, asking_step) catch {};
1066 const w, const ttyconf = std.debug.lockStderrWriter(&.{});
1067 std.Build.dumpBadGetPathHelp(&compile.step, w, ttyconf, compile.step.owner, asking_step) catch {};
10681068 std.debug.unlockStderrWriter();
10691069 @panic(tag_name ++ " is null. Is there a missing step dependency?");
10701070 };
......@@ -2027,10 +2027,9 @@ fn checkCompileErrors(compile: *Compile) !void {
20272027 var aw: std.Io.Writer.Allocating = .init(arena);
20282028 defer aw.deinit();
20292029 try actual_eb.renderToWriter(.{
2030 .ttyconf = .no_color,
20312030 .include_reference_trace = false,
20322031 .include_source_line = false,
2033 }, &aw.writer);
2032 }, &aw.writer, .no_color);
20342033 break :ae try aw.toOwnedSlice();
20352034 };
20362035
lib/std/Build/Step/Run.zig+9-5
......@@ -1587,11 +1587,15 @@ fn spawnChildAndCollect(
15871587 run.step.test_results = res.test_results;
15881588 if (res.test_metadata) |tm| {
15891589 run.cached_test_metadata = tm.toCachedTestMetadata();
1590 if (options.web_server) |ws| ws.updateTimeReportRunTest(
1591 run,
1592 &run.cached_test_metadata.?,
1593 tm.ns_per_test,
1594 );
1590 if (options.web_server) |ws| {
1591 if (b.graph.time_report) {
1592 ws.updateTimeReportRunTest(
1593 run,
1594 &run.cached_test_metadata.?,
1595 tm.ns_per_test,
1596 );
1597 }
1598 }
15951599 }
15961600 return null;
15971601 } else {
lib/std/Build/WebServer.zig+4-5
......@@ -54,9 +54,9 @@ pub fn notifyUpdate(ws: *WebServer) void {
5454pub const Options = struct {
5555 gpa: Allocator,
5656 thread_pool: *std.Thread.Pool,
57 ttyconf: Io.tty.Config,
5758 graph: *const std.Build.Graph,
5859 all_steps: []const *Build.Step,
59 ttyconf: Io.tty.Config,
6060 root_prog_node: std.Progress.Node,
6161 watch: bool,
6262 listen_address: net.IpAddress,
......@@ -101,10 +101,10 @@ pub fn init(opts: Options) WebServer {
101101 return .{
102102 .gpa = opts.gpa,
103103 .thread_pool = opts.thread_pool,
104 .ttyconf = opts.ttyconf,
104105 .graph = opts.graph,
105106 .all_steps = all_steps,
106107 .listen_address = opts.listen_address,
107 .ttyconf = opts.ttyconf,
108108 .root_prog_node = opts.root_prog_node,
109109 .watch = opts.watch,
110110
......@@ -236,9 +236,9 @@ pub fn finishBuild(ws: *WebServer, opts: struct {
236236 ws.gpa,
237237 ws.graph.io,
238238 ws.thread_pool,
239 ws.ttyconf,
239240 ws.all_steps,
240241 ws.root_prog_node,
241 ws.ttyconf,
242242 .{ .forever = .{ .ws = ws } },
243243 ) catch |err| std.process.fatal("failed to start fuzzer: {s}", .{@errorName(err)});
244244 ws.fuzz.?.start();
......@@ -655,8 +655,7 @@ fn buildClientWasm(ws: *WebServer, arena: Allocator, optimize: std.builtin.Optim
655655 }
656656
657657 if (result_error_bundle.errorMessageCount() > 0) {
658 const color = std.zig.Color.auto;
659 result_error_bundle.renderToStdErr(color.renderOptions());
658 result_error_bundle.renderToStdErr(.{}, .auto);
660659 log.err("the following command failed with {d} compilation errors:\n{s}", .{
661660 result_error_bundle.errorMessageCount(),
662661 try Build.Step.allocPrintCmd(arena, null, argv.items),
lib/std/debug.zig+19-19
......@@ -272,7 +272,7 @@ pub fn unlockStdErr() void {
272272 std.Progress.unlockStdErr();
273273}
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.
276276///
277277/// During the lock, any `std.Progress` information is cleared from the terminal.
278278///
......@@ -282,8 +282,16 @@ pub fn unlockStdErr() void {
282282///
283283/// The returned `Writer` does not need to be manually flushed: flushing is performed automatically
284284/// when the matching `unlockStderrWriter` call occurs.
285pub fn lockStderrWriter(buffer: []u8) *Writer {
286 return std.Progress.lockStderrWriter(buffer);
285pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } {
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.? };
287295}
288296
289297pub fn unlockStderrWriter() void {
......@@ -297,7 +305,7 @@ pub fn unlockStderrWriter() void {
297305/// function returns.
298306pub fn print(comptime fmt: []const u8, args: anytype) void {
299307 var buffer: [64]u8 = undefined;
300 const bw = lockStderrWriter(&buffer);
308 const bw, _ = lockStderrWriter(&buffer);
301309 defer unlockStderrWriter();
302310 nosuspend bw.print(fmt, args) catch return;
303311}
......@@ -314,9 +322,8 @@ pub inline fn getSelfDebugInfo() !*SelfInfo {
314322/// Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
315323/// Obtains the stderr mutex while dumping.
316324pub fn dumpHex(bytes: []const u8) void {
317 const bw = lockStderrWriter(&.{});
325 const bw, const ttyconf = lockStderrWriter(&.{});
318326 defer unlockStderrWriter();
319 const ttyconf = tty.detectConfig(.stderr());
320327 dumpHexFallible(bw, ttyconf, bytes) catch {};
321328}
322329
......@@ -538,9 +545,7 @@ pub fn defaultPanic(
538545 _ = panicking.fetchAdd(1, .seq_cst);
539546
540547 trace: {
541 const tty_config = tty.detectConfig(.stderr());
542
543 const stderr = lockStderrWriter(&.{});
548 const stderr, const tty_config = lockStderrWriter(&.{});
544549 defer unlockStderrWriter();
545550
546551 if (builtin.single_threaded) {
......@@ -743,8 +748,7 @@ pub noinline fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Wri
743748}
744749/// A thin wrapper around `writeCurrentStackTrace` which writes to stderr and ignores write errors.
745750pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
746 const tty_config = tty.detectConfig(.stderr());
747 const stderr = lockStderrWriter(&.{});
751 const stderr, const tty_config = lockStderrWriter(&.{});
748752 defer unlockStderrWriter();
749753 writeCurrentStackTrace(.{
750754 .first_address = a: {
......@@ -809,8 +813,7 @@ pub fn writeStackTrace(st: *const StackTrace, writer: *Writer, tty_config: tty.C
809813}
810814/// A thin wrapper around `writeStackTrace` which writes to stderr and ignores write errors.
811815pub fn dumpStackTrace(st: *const StackTrace) void {
812 const tty_config = tty.detectConfig(.stderr());
813 const stderr = lockStderrWriter(&.{});
816 const stderr, const tty_config = lockStderrWriter(&.{});
814817 defer unlockStderrWriter();
815818 writeStackTrace(st, stderr, tty_config) catch |err| switch (err) {
816819 error.WriteFailed => {},
......@@ -1552,9 +1555,7 @@ pub fn defaultHandleSegfault(addr: ?usize, name: []const u8, opt_ctx: ?CpuContex
15521555 _ = panicking.fetchAdd(1, .seq_cst);
15531556
15541557 trace: {
1555 const tty_config = tty.detectConfig(.stderr());
1556
1557 const stderr = lockStderrWriter(&.{});
1558 const stderr, const tty_config = lockStderrWriter(&.{});
15581559 defer unlockStderrWriter();
15591560
15601561 if (addr) |a| {
......@@ -1612,7 +1613,7 @@ test "manage resources correctly" {
16121613 &di,
16131614 &discarding.writer,
16141615 S.showMyTrace(),
1615 tty.detectConfig(.stderr()),
1616 .no_color,
16161617 );
16171618}
16181619
......@@ -1674,8 +1675,7 @@ pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize
16741675 pub fn dump(t: @This()) void {
16751676 if (!enabled) return;
16761677
1677 const tty_config = tty.detectConfig(.stderr());
1678 const stderr = lockStderrWriter(&.{});
1678 const stderr, const tty_config = lockStderrWriter(&.{});
16791679 defer unlockStderrWriter();
16801680 const end = @min(t.index, size);
16811681 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) {
4747 }
4848
4949 pub fn dump(v: Value) void {
50 const w = std.debug.lockStderrWriter(&.{});
50 const w, _ = std.debug.lockStderrWriter(&.{});
5151 defer std.debug.unlockStderrWriter();
5252
5353 json.Stringify.value(v, .{}, w) catch return;
lib/std/log.zig+34-77
......@@ -13,63 +13,15 @@
1313//! `const log = std.log.scoped(.libfoo);` to use .libfoo as the scope of its
1414//! log messages.
1515//!
16//! An example `logFn` might look something like this:
17//!
18//! ```
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//! }
16//! For an example implementation of the `logFn` function, see `defaultLog`,
17//! which is the default implementation. It outputs to stderr, using color if
18//! the detected `std.Io.tty.Config` supports it. Its output looks like this:
6819//! ```
69//! Which produces the following output:
70//! ```
71//! [info] (default): Flux capacitor is starting to overheat
72//! [warning] (nice_library): Something went very wrong, sorry
20//! error: this is an error
21//! error(scope): this is an error with a non-default scope
22//! warning: this is a warning
23//! info: this is an informative message
24//! debug: this is a debugging message
7325//! ```
7426
7527const std = @import("std.zig");
......@@ -104,37 +56,28 @@ pub const default_level: Level = switch (builtin.mode) {
10456 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => .info,
10557};
10658
107const level = std.options.log_level;
108
10959pub const ScopeLevel = struct {
11060 scope: @Type(.enum_literal),
11161 level: Level,
11262};
11363
114const scope_levels = std.options.log_scope_levels;
115
11664fn log(
117 comptime message_level: Level,
65 comptime level: Level,
11866 comptime scope: @Type(.enum_literal),
11967 comptime format: []const u8,
12068 args: anytype,
12169) 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);
12573}
12674
12775/// 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 {
129 inline for (scope_levels) |scope_level| {
130 if (scope_level.scope == scope) return @intFromEnum(message_level) <= @intFromEnum(scope_level.level);
76pub fn logEnabled(comptime level: Level, comptime scope: @Type(.enum_literal)) bool {
77 inline for (std.options.log_scope_levels) |scope_level| {
78 if (scope_level.scope == scope) return @intFromEnum(level) <= @intFromEnum(scope_level.level);
13179 }
132 return @intFromEnum(message_level) <= @intFromEnum(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);
80 return @intFromEnum(level) <= @intFromEnum(std.options.log_level);
13881}
13982
14083/// The default implementation for the log function. Custom log functions may
......@@ -143,17 +86,31 @@ pub fn defaultLogEnabled(comptime message_level: Level) bool {
14386/// Uses a 64-byte buffer for formatted printing which is flushed before this
14487/// function returns.
14588pub fn defaultLog(
146 comptime message_level: Level,
89 comptime level: Level,
14790 comptime scope: @Type(.enum_literal),
14891 comptime format: []const u8,
14992 args: anytype,
15093) void {
151 const level_txt = comptime message_level.asText();
152 const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
15394 var buffer: [64]u8 = undefined;
154 const stderr = std.debug.lockStderrWriter(&buffer);
95 const stderr, const ttyconf = std.debug.lockStderrWriter(&buffer);
15596 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;
157114}
158115
159116/// Returns a scoped logging namespace that logs all messages using the scope
lib/std/testing.zig+4-4
......@@ -355,7 +355,7 @@ test expectApproxEqRel {
355355/// This function is intended to be used only in tests. When the two slices are not
356356/// equal, prints diagnostics to stderr to show exactly how they are not equal (with
357357/// 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`.
359359/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
360360pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
361361 const diff_index: usize = diff_index: {
......@@ -367,9 +367,9 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
367367 break :diff_index if (expected.len == actual.len) return else shortest;
368368 };
369369 if (!backend_can_print) return error.TestExpectedEqual;
370 const stderr_w = std.debug.lockStderrWriter(&.{});
370 const stderr_w, const ttyconf = std.debug.lockStderrWriter(&.{});
371371 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 {};
373373 return error.TestExpectedEqual;
374374}
375375
......@@ -379,6 +379,7 @@ fn failEqualSlices(
379379 actual: []const T,
380380 diff_index: usize,
381381 w: *std.Io.Writer,
382 ttyconf: std.Io.tty.Config,
382383) !void {
383384 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(
398399 const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
399400 const actual_truncated = window_start + actual_window.len < actual.len;
400401
401 const ttyconf = std.Io.tty.detectConfig(.stderr());
402402 var differ = if (T == u8) BytesDiffer{
403403 .expected = expected_window,
404404 .actual = actual_window,
lib/std/zig.zig+8-7
......@@ -53,17 +53,18 @@ pub const Color = enum {
5353 /// Assume stderr is a terminal.
5454 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 {
5757 return switch (color) {
58 .auto => Io.tty.detectConfig(std.fs.File.stderr()),
58 .auto => detected,
5959 .on => .escape_codes,
6060 .off => .no_color,
6161 };
6262 }
63
64 pub fn renderOptions(color: Color) std.zig.ErrorBundle.RenderOptions {
65 return .{
66 .ttyconf = get_tty_conf(color),
63 pub fn detectTtyConf(color: Color) Io.tty.Config {
64 return switch (color) {
65 .auto => .detect(.stderr()),
66 .on => .escape_codes,
67 .off => .no_color,
6768 };
6869 }
6970};
......@@ -606,7 +607,7 @@ pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color
606607
607608 var error_bundle = try wip_errors.toOwnedBundle("");
608609 defer error_bundle.deinit(gpa);
609 error_bundle.renderToStdErr(color.renderOptions());
610 error_bundle.renderToStdErr(.{}, color);
610611}
611612
612613pub fn putAstErrorsIntoBundle(
lib/std/zig/ErrorBundle.zig+8-9
......@@ -157,23 +157,22 @@ pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {
157157}
158158
159159pub const RenderOptions = struct {
160 ttyconf: Io.tty.Config,
161160 include_reference_trace: bool = true,
162161 include_source_line: bool = true,
163162 include_log_text: bool = true,
164163};
165164
166pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions) void {
165pub fn renderToStdErr(eb: ErrorBundle, options: RenderOptions, color: std.zig.Color) void {
167166 var buffer: [256]u8 = undefined;
168 const w = std.debug.lockStderrWriter(&buffer);
167 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
169168 defer std.debug.unlockStderrWriter();
170 renderToWriter(eb, options, w) catch return;
169 renderToWriter(eb, options, w, color.getTtyConf(ttyconf)) catch return;
171170}
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 {
174173 if (eb.extra.len == 0) return;
175174 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);
177176 }
178177
179178 if (options.include_log_text) {
......@@ -190,11 +189,11 @@ fn renderErrorMessageToWriter(
190189 options: RenderOptions,
191190 err_msg_index: MessageIndex,
192191 w: *Writer,
192 ttyconf: Io.tty.Config,
193193 kind: []const u8,
194194 color: Io.tty.Color,
195195 indent: usize,
196196) (Writer.Error || std.posix.UnexpectedError)!void {
197 const ttyconf = options.ttyconf;
198197 const err_msg = eb.getErrorMessage(err_msg_index);
199198 if (err_msg.src_loc != .none) {
200199 const src = eb.extraData(SourceLocation, @intFromEnum(err_msg.src_loc));
......@@ -251,7 +250,7 @@ fn renderErrorMessageToWriter(
251250 try ttyconf.setColor(w, .reset);
252251 }
253252 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);
255254 }
256255 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
257256 try ttyconf.setColor(w, .reset);
......@@ -300,7 +299,7 @@ fn renderErrorMessageToWriter(
300299 }
301300 try ttyconf.setColor(w, .reset);
302301 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);
304303 }
305304 }
306305}
lib/std/zig/parser_test.zig+1-1
......@@ -6386,7 +6386,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
63866386
63876387fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {
63886388 var buffer: [64]u8 = undefined;
6389 const stderr = std.debug.lockStderrWriter(&buffer);
6389 const stderr, _ = std.debug.lockStderrWriter(&buffer);
63906390 defer std.debug.unlockStderrWriter();
63916391
63926392 var tree = try std.zig.Ast.parse(allocator, source, .zig);
src/Air/print.zig+2-2
......@@ -73,13 +73,13 @@ pub fn writeInst(
7373}
7474
7575pub 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(&.{});
7777 defer std.debug.unlockStderrWriter();
7878 air.write(stderr_bw, pt, liveness);
7979}
8080
8181pub 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(&.{});
8383 defer std.debug.unlockStderrWriter();
8484 air.writeInst(stderr_bw, inst, pt, liveness);
8585}
src/Compilation.zig+3-3
......@@ -2093,7 +2093,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
20932093
20942094 if (options.verbose_llvm_cpu_features) {
20952095 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(&.{});
20972097 defer std.debug.unlockStderrWriter();
20982098 stderr_w.print("compilation: {s}\n", .{options.root_name}) catch break :print;
20992099 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 {
42704270 // However, we haven't reported any such error.
42714271 // This is a compiler bug.
42724272 print_ctx: {
4273 var stderr_w = std.debug.lockStderrWriter(&.{});
4273 var stderr_w, _ = std.debug.lockStderrWriter(&.{});
42744274 defer std.debug.unlockStderrWriter();
42754275 stderr_w.writeAll("referenced transitive analysis errors, but none actually emitted\n") catch break :print_ctx;
42764276 stderr_w.print("{f} [transitive failure]\n", .{zcu.fmtAnalUnit(failed_unit)}) catch break :print_ctx;
......@@ -7752,7 +7752,7 @@ pub fn lockAndSetMiscFailure(
77527752
77537753pub fn dump_argv(argv: []const []const u8) void {
77547754 var buffer: [64]u8 = undefined;
7755 const stderr = std.debug.lockStderrWriter(&buffer);
7755 const stderr, _ = std.debug.lockStderrWriter(&buffer);
77567756 defer std.debug.unlockStderrWriter();
77577757 nosuspend {
77587758 for (argv, 0..) |arg, i| {
src/InternPool.zig+2-2
......@@ -11330,7 +11330,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
1133011330
1133111331fn dumpAllFallible(ip: *const InternPool) anyerror!void {
1133211332 var buffer: [4096]u8 = undefined;
11333 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11333 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
1133411334 defer std.debug.unlockStderrWriter();
1133511335 for (ip.locals, 0..) |*local, tid| {
1133611336 const items = local.shared.items.view();
......@@ -11462,7 +11462,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
1146211462 }
1146311463
1146411464 var buffer: [4096]u8 = undefined;
11465 const stderr_bw = std.debug.lockStderrWriter(&buffer);
11465 const stderr_bw, _ = std.debug.lockStderrWriter(&buffer);
1146611466 defer std.debug.unlockStderrWriter();
1146711467
1146811468 const SortContext = struct {
src/Package/Fetch.zig+2-2
......@@ -2043,7 +2043,7 @@ const UnpackResult = struct {
20432043 defer errors.deinit(gpa);
20442044 var aw: Io.Writer.Allocating = .init(gpa);
20452045 defer aw.deinit();
2046 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
2046 try errors.renderToWriter(.{}, &aw.writer, .no_color);
20472047 try std.testing.expectEqualStrings(
20482048 \\error: unable to unpack
20492049 \\ note: unable to create symlink from 'dir2/file2' to 'filename': SymlinkError
......@@ -2360,7 +2360,7 @@ const TestFetchBuilder = struct {
23602360 }
23612361 var aw: Io.Writer.Allocating = .init(std.testing.allocator);
23622362 defer aw.deinit();
2363 try errors.renderToWriter(.{ .ttyconf = .no_color }, &aw.writer);
2363 try errors.renderToWriter(.{}, &aw.writer, .no_color);
23642364 try std.testing.expectEqualStrings(msg, aw.written());
23652365 }
23662366};
src/Sema.zig+1-1
......@@ -2631,7 +2631,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg
26312631 Compilation.addModuleErrorMsg(zcu, &wip_errors, err_msg.*, false) catch @panic("out of memory");
26322632 std.debug.print("compile error during Sema:\n", .{});
26332633 var error_bundle = wip_errors.toOwnedBundle("") catch @panic("out of memory");
2634 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
2634 error_bundle.renderToStdErr(.{}, .auto);
26352635 std.debug.panicExtra(@returnAddress(), "unexpected compile error occurred", .{});
26362636 }
26372637
src/Zcu/PerThread.zig+1-1
......@@ -4473,7 +4473,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
44734473 defer if (liveness) |*l| l.deinit(gpa);
44744474
44754475 if (build_options.enable_debug_extensions and comp.verbose_air) {
4476 const stderr = std.debug.lockStderrWriter(&.{});
4476 const stderr, _ = std.debug.lockStderrWriter(&.{});
44774477 defer std.debug.unlockStderrWriter();
44784478 stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
44794479 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
7474 dis.operands_separator,
7575 imm12,
7676 });
77 return if (!elide_shift) writer.print("{s}{f} #{s}", .{
77 return if (!elide_shift) writer.print("{s}{f} #{t}", .{
7878 dis.operands_separator,
7979 fmtCase(.lsl, dis.case),
80 @tagName(sh),
80 sh,
8181 });
8282 },
8383 .add_subtract_immediate_with_tags => |add_subtract_immediate_with_tags| {
......@@ -176,10 +176,10 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
176176 dis.operands_separator,
177177 imm16,
178178 });
179 return if (!elide_shift) writer.print("{s}{f} #{s}", .{
179 return if (!elide_shift) writer.print("{s}{f} #{t}", .{
180180 dis.operands_separator,
181181 fmtCase(.lsl, dis.case),
182 @tagName(hw),
182 hw,
183183 });
184184 },
185185 .bitfield => |bitfield| {
......@@ -833,8 +833,36 @@ pub fn printInstruction(dis: Disassemble, inst: aarch64.encoding.Instruction, wr
833833 },
834834 .rotate_right_into_flags => {},
835835 .evaluate_into_flags => {},
836 .conditional_compare_register => {},
837 .conditional_compare_immediate => {},
836 .conditional_compare_register => |conditional_compare_register| {
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 },
838866 .conditional_select => |conditional_select| {
839867 const decoded = conditional_select.decode();
840868 if (decoded == .unallocated) break :unallocated;
src/codegen/aarch64/Mir.zig+61-19
......@@ -107,6 +107,7 @@ pub fn emit(
107107 mir.body[nav_reloc.reloc.label],
108108 body_end - Instruction.size * (1 + nav_reloc.reloc.label),
109109 nav_reloc.reloc.addend,
110 if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
110111 );
111112 for (mir.uav_relocs) |uav_reloc| try emitReloc(
112113 lf,
......@@ -124,6 +125,7 @@ pub fn emit(
124125 mir.body[uav_reloc.reloc.label],
125126 body_end - Instruction.size * (1 + uav_reloc.reloc.label),
126127 uav_reloc.reloc.addend,
128 .direct,
127129 );
128130 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
129131 lf,
......@@ -136,10 +138,11 @@ pub fn emit(
136138 mf.getZigObject().?.getOrCreateMetadataForLazySymbol(mf, pt, lazy_reloc.symbol) catch |err|
137139 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)})
138140 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}),
140142 mir.body[lazy_reloc.reloc.label],
141143 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
142144 lazy_reloc.reloc.addend,
145 .direct,
143146 );
144147 for (mir.global_relocs) |global_reloc| try emitReloc(
145148 lf,
......@@ -150,10 +153,11 @@ pub fn emit(
150153 else if (lf.cast(.macho)) |mf|
151154 try mf.getGlobalSymbol(std.mem.span(global_reloc.name), null)
152155 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}),
154157 mir.body[global_reloc.reloc.label],
155158 body_end - Instruction.size * (1 + global_reloc.reloc.label),
156159 global_reloc.reloc.addend,
160 .direct,
157161 );
158162 const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
159163 for (mir.literal_relocs) |literal_reloc| {
......@@ -188,6 +192,7 @@ fn emitReloc(
188192 instruction: Instruction,
189193 offset: u32,
190194 addend: u64,
195 kind: enum { direct, got_load },
191196) !void {
192197 const gpa = zcu.gpa;
193198 switch (instruction.decode()) {
......@@ -198,11 +203,20 @@ fn emitReloc(
198203 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
199204 else => unreachable,
200205 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
201 .adr => .ADR_PREL_LO21,
202 .adrp => .ADR_PREL_PG_HI21,
206 .adr => switch (kind) {
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 },
203214 },
204215 .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 },
206220 .sub => unreachable,
207221 },
208222 };
......@@ -223,7 +237,10 @@ fn emitReloc(
223237 .offset = offset,
224238 .target = sym_index,
225239 .addend = @bitCast(addend),
226 .type = .page,
240 .type = switch (kind) {
241 .direct => .page,
242 .got_load => .got_load_page,
243 },
227244 .meta = .{
228245 .pcrel = true,
229246 .has_subtractor = false,
......@@ -238,7 +255,10 @@ fn emitReloc(
238255 .offset = offset,
239256 .target = sym_index,
240257 .addend = @bitCast(addend),
241 .type = .pageoff,
258 .type = switch (kind) {
259 .direct => .pageoff,
260 .got_load => .got_load_pageoff,
261 },
242262 .meta = .{
243263 .pcrel = false,
244264 .has_subtractor = false,
......@@ -285,20 +305,39 @@ fn emitReloc(
285305 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
286306 .integer => |integer| switch (integer.decode()) {
287307 .unallocated, .prfm => unreachable,
288 .strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
289 .strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
290 .ldrsw => .LDST32_ABS_LO12_NC,
291 inline .str, .ldr => |encoded| switch (encoded.sf) {
308 .strb, .ldrb, .ldrsb => switch (kind) {
309 .direct => .LDST8_ABS_LO12_NC,
310 .got_load => unreachable,
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) {
292321 .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 },
294330 },
295331 },
296 .vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
297 .byte => .LDST8_ABS_LO12_NC,
298 .half => .LDST16_ABS_LO12_NC,
299 .single => .LDST32_ABS_LO12_NC,
300 .double => .LDST64_ABS_LO12_NC,
301 .quad => .LDST128_ABS_LO12_NC,
332 .vector => |vector| switch (kind) {
333 .direct => switch (vector.group.opc1.decode(vector.group.size)) {
334 .byte => .LDST8_ABS_LO12_NC,
335 .half => .LDST16_ABS_LO12_NC,
336 .single => .LDST32_ABS_LO12_NC,
337 .double => .LDST64_ABS_LO12_NC,
338 .quad => .LDST128_ABS_LO12_NC,
339 },
340 .got_load => unreachable,
302341 },
303342 };
304343 try atom.addReloc(gpa, .{
......@@ -314,7 +353,10 @@ fn emitReloc(
314353 .offset = offset,
315354 .target = sym_index,
316355 .addend = @bitCast(addend),
317 .type = .pageoff,
356 .type = switch (kind) {
357 .direct => .pageoff,
358 .got_load => .got_load_pageoff,
359 },
318360 .meta = .{
319361 .pcrel = false,
320362 .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,
961961 .inst_index = undefined,
962962 };
963963 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}),
965965 .arg => {
966966 const arg_vi = isel.live_values.fetchRemove(air.inst_index).?.value;
967967 defer arg_vi.deref(isel);
......@@ -1117,12 +1117,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
11171117
11181118 const bin_op = air.data(air.inst_index).bin_op;
11191119 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) });
11211121 const int_info = ty.intInfo(zcu);
11221122 switch (int_info.bits) {
11231123 0 => unreachable,
11241124 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) }),
11261126 .unsigned => {
11271127 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
11281128 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,
11601160 try lhs_mat.finish(isel);
11611161 },
11621162 },
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) }),
11641164 }
11651165 }
11661166 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,
11721172 const bin_op = air.data(air.inst_index).bin_op;
11731173 const ty = isel.air.typeOf(bin_op.lhs, ip);
11741174 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) });
11761176 const int_info = ty.intInfo(zcu);
11771177 switch (int_info.bits) {
11781178 0 => unreachable,
......@@ -1318,7 +1318,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
13181318 try rhs_lo64_mat.finish(isel);
13191319 try lhs_lo64_mat.finish(isel);
13201320 },
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) }),
13221322 }
13231323 } else switch (ty.floatBits(isel.target)) {
13241324 else => unreachable,
......@@ -1421,7 +1421,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
14211421
14221422 const bin_op = air.data(air.inst_index).bin_op;
14231423 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) });
14251425 const int_info = ty.intInfo(zcu);
14261426 switch (int_info.signedness) {
14271427 .signed => switch (int_info.bits) {
......@@ -1443,7 +1443,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
14431443 try rhs_mat.finish(isel);
14441444 try lhs_mat.finish(isel);
14451445 },
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) }),
14471447 },
14481448 .unsigned => switch (int_info.bits) {
14491449 0 => unreachable,
......@@ -1545,8 +1545,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
15451545 try rhs_mat.finish(isel);
15461546 try lhs_mat.finish(isel);
15471547 },
1548 65...128 => return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) }),
1549 else => return isel.fail("too big {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 {t} {f}", .{ air_tag, isel.fmtType(ty) }),
15501550 },
15511551 }
15521552 }
......@@ -1558,7 +1558,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
15581558
15591559 const bin_op = air.data(air.inst_index).bin_op;
15601560 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) });
15621562 const int_info = ty.intInfo(zcu);
15631563 switch (int_info.bits) {
15641564 0 => unreachable,
......@@ -1784,7 +1784,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
17841784 try rhs_mat.finish(isel);
17851785 try lhs_mat.finish(isel);
17861786 },
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) }),
17881788 }
17891789 }
17901790 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,
18971897 const bin_op = air.data(air.inst_index).bin_op;
18981898 const ty = isel.air.typeOf(bin_op.lhs, ip);
18991899 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) });
19011901 const int_info = ty.intInfo(zcu);
19021902 switch (int_info.bits) {
19031903 0 => unreachable,
......@@ -1970,7 +1970,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
19701970 else => unreachable,
19711971 .div_trunc, .div_exact => {},
19721972 .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}),
19741974 .unsigned => {},
19751975 },
19761976 }
......@@ -2012,7 +2012,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
20122012 try call.paramLiveOut(isel, lhs_lo64_vi.?, .r0);
20132013 try call.finishParams(isel);
20142014 },
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) }),
20162016 }
20172017 } else switch (ty.floatBits(isel.target)) {
20182018 else => unreachable,
......@@ -2169,9 +2169,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
21692169 const bin_op = air.data(air.inst_index).bin_op;
21702170 const ty = isel.air.typeOf(bin_op.lhs, ip);
21712171 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) });
21732173 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
21762176 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
21772177 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,
24942494 const bin_op = air.data(air.inst_index).bin_op;
24952495 const ty = isel.air.typeOf(bin_op.lhs, ip);
24962496 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) });
24982498 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
25012501 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
25022502 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,
29202920 else if (ty.isAbiInt(zcu))
29212921 ty.intInfo(zcu)
29222922 else
2923 return isel.fail("bad {s} {f}", .{ @tagName(air_tag), isel.fmtType(ty) });
2924 if (int_info.bits > 128) return isel.fail("too big {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 {t} {f}", .{ air_tag, isel.fmtType(ty) });
29252925
29262926 const lhs_vi = try isel.use(bin_op.lhs);
29272927 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,
29682968
29692969 const bin_op = air.data(air.inst_index).bin_op;
29702970 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) });
29722972 const int_info = ty.intInfo(zcu);
29732973 switch (int_info.bits) {
29742974 0 => unreachable,
......@@ -3161,7 +3161,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
31613161 try lhs_hi64_mat.finish(isel);
31623162 break :unused;
31633163 },
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) }),
31653165 }
31663166 }
31673167 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,
31743174 const ty = ty_op.ty.toType();
31753175 const int_info: std.builtin.Type.Int = int_info: {
31763176 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) });
31783178 break :int_info ty.intInfo(zcu);
31793179 };
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
31823182 const src_vi = try isel.use(ty_op.operand);
31833183 var offset = res_vi.value.size(isel);
......@@ -3302,7 +3302,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
33023302 }
33033303 },
33043304 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) }),
33063306 }
33073307 } else if ((dst_ty.isPtrAtRuntime(zcu) or dst_ty.isAbiInt(zcu)) and (src_ty.isPtrAtRuntime(zcu) or src_ty.isAbiInt(zcu))) {
33083308 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,
33133313 src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));
33143314 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
33153315 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) });
33173317 } else if (dst_tag == .float and src_tag == .float) {
33183318 assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target));
33193319 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,
34833483 try call.paramAddress(isel, src_vi, .r1);
34843484 try call.paramAddress(isel, dst_vi.value, .r0);
34853485 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) });
34873487 } else if (dst_tag == .array and dst_ty.childType(zcu).isAbiInt(zcu) and src_ty.isAbiInt(zcu)) {
34883488 const dst_child_int_info = dst_ty.childType(zcu).intInfo(zcu);
34893489 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,
35103510 try call.paramAddress(isel, src_vi, .r1);
35113511 try call.paramAddress(isel, dst_vi.value, .r0);
35123512 try call.finishParams(isel);
3513 } 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 {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 {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
35153515 }
35163516 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
35173517 },
......@@ -3737,7 +3737,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
37373737
37383738 const ty_op = air.data(air.inst_index).ty_op;
37393739 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) });
37413741 const int_info = ty.intInfo(zcu);
37423742 switch (int_info.bits) {
37433743 0 => unreachable,
......@@ -3769,7 +3769,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
37693769 try src_hi64_mat.finish(isel);
37703770 try src_lo64_mat.finish(isel);
37713771 },
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) }),
37733773 }
37743774 }
37753775 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,
37803780
37813781 const ty_op = air.data(air.inst_index).ty_op;
37823782 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) });
37843784 const int_info = ty.intInfo(zcu);
37853785 switch (int_info.bits) {
37863786 0 => unreachable,
......@@ -3812,7 +3812,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
38123812 try src_hi64_mat.finish(isel);
38133813 try src_lo64_mat.finish(isel);
38143814 },
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) }),
38163816 }
38173817 }
38183818 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,
38233823
38243824 const ty_op = air.data(air.inst_index).ty_op;
38253825 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) });
38273827 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
38303830 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
38313831 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,
38773877
38783878 const ty_op = air.data(air.inst_index).ty_op;
38793879 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) });
38813881 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
38843884 if (int_info.bits == 8) break :unused try res_vi.value.move(isel, ty_op.operand);
38853885 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,
39413941
39423942 const ty_op = air.data(air.inst_index).ty_op;
39433943 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) });
39453945 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
39483948 const res_ra = try res_vi.value.defReg(isel) orelse break :unused;
39493949 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,
42444244 const ty_op = air.data(air.inst_index).ty_op;
42454245 const ty = ty_op.ty.toType();
42464246 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) });
42484248 switch (ty.intInfo(zcu).bits) {
42494249 0 => unreachable,
42504250 1...32 => {
......@@ -4306,7 +4306,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
43064306 try src_lo64_mat.finish(isel);
43074307 try src_hi64_mat.finish(isel);
43084308 },
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) }),
43104310 }
43114311 } else switch (ty.floatBits(isel.target)) {
43124312 else => unreachable,
......@@ -4465,216 +4465,61 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
44654465 if (isel.live_values.fetchRemove(air.inst_index)) |res_vi| unused: {
44664466 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;
44694469 const ty = isel.air.typeOf(bin_op.lhs, ip);
4470 if (!ty.isRuntimeFloat()) {
4471 const int_info: std.builtin.Type.Int = if (ty.toIntern() == .bool_type)
4472 .{ .signedness = .unsigned, .bits = 1 }
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) {
4470 switch (ip.indexToKey(ty.toIntern())) {
4471 else => {},
4472 .opt_type => |payload_ty| switch (air_tag) {
44834473 else => unreachable,
4484 .cmp_lt => switch (int_info.signedness) {
4485 .signed => .lt,
4486 .unsigned => .lo,
4487 },
4488 .cmp_lte => switch (int_info.bits) {
4489 else => unreachable,
4490 1...64 => switch (int_info.signedness) {
4491 .signed => .le,
4492 .unsigned => .ls,
4493 },
4494 65...128 => {
4495 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
4496 continue :cond .cmp_gte;
4497 },
4498 },
4499 .cmp_eq => .eq,
4500 .cmp_gte => switch (int_info.signedness) {
4501 .signed => .ge,
4502 .unsigned => .hs,
4503 },
4504 .cmp_gt => switch (int_info.bits) {
4505 else => unreachable,
4506 1...64 => switch (int_info.signedness) {
4507 .signed => .gt,
4508 .unsigned => .hi,
4509 },
4510 65...128 => {
4511 std.mem.swap(Air.Inst.Ref, &bin_op.lhs, &bin_op.rhs);
4512 continue :cond .cmp_lt;
4513 },
4474 .cmp_eq, .cmp_neq => if (!ty.optionalReprIsPayload(zcu)) {
4475 const lhs_vi = try isel.use(bin_op.lhs);
4476 const rhs_vi = try isel.use(bin_op.rhs);
4477 const payload_size = ZigType.abiSize(.fromInterned(payload_ty), zcu);
4478 var lhs_payload_part_it = lhs_vi.field(ty, 0, payload_size);
4479 const lhs_payload_part_vi = try lhs_payload_part_it.only(isel);
4480 var rhs_payload_part_it = rhs_vi.field(ty, 0, payload_size);
4481 const rhs_payload_part_vi = try rhs_payload_part_it.only(isel);
4482 const cmp_info = try isel.cmp(
4483 try res_vi.value.defReg(isel) orelse break :unused,
4484 .fromInterned(payload_ty),
4485 lhs_payload_part_vi.?,
4486 air_tag.toCmpOp().?,
4487 rhs_payload_part_vi.?,
4488 );
4489 try isel.emit(.@"b."(
4490 .vc,
4491 @intCast((isel.instructions.items.len + 1 - cmp_info.cset_label) << 2),
4492 ));
4493 var lhs_has_value_part_it = lhs_vi.field(ty, payload_size, 1);
4494 const lhs_has_value_part_vi = try lhs_has_value_part_it.only(isel);
4495 const lhs_has_value_part_mat = try lhs_has_value_part_vi.?.matReg(isel);
4496 var rhs_has_value_part_it = rhs_vi.field(ty, payload_size, 1);
4497 const rhs_has_value_part_vi = try rhs_has_value_part_it.only(isel);
4498 const rhs_has_value_part_mat = try rhs_has_value_part_vi.?.matReg(isel);
4499 try isel.emit(.ccmp(
4500 lhs_has_value_part_mat.ra.w(),
4501 .{ .register = rhs_has_value_part_mat.ra.w() },
4502 .{ .n = false, .z = false, .c = false, .v = true },
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;
45144513 },
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);
46764514 },
46774515 }
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 );
46784523 }
46794524 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
46804525 },
......@@ -5497,7 +5342,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
54975342 try src_mat.finish(isel);
54985343 },
54995344 };
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) });
55015346 }
55025347 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
55035348 },
......@@ -5517,7 +5362,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
55175362 .int => .integer_out_of_bounds,
55185363 .@"enum" => {
55195364 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) });
55215366 }
55225367 break :panic_id .invalid_enum_value;
55235368 },
......@@ -5599,7 +5444,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
55995444 try src_mat.finish(isel);
56005445 }
56015446 }
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) });
56035448 }
56045449 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
56055450 },
......@@ -5610,7 +5455,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
56105455 const ty_op = air.data(air.inst_index).ty_op;
56115456 const dst_ty = ty_op.ty.toType();
56125457 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) });
56145459 const dst_int_info = dst_ty.intInfo(zcu);
56155460 switch (dst_int_info.bits) {
56165461 0 => unreachable,
......@@ -5683,9 +5528,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
56835528 try src_lo64_vi.?.liveOut(isel, dst_lo64_ra);
56845529 }
56855530 },
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) }),
56875532 },
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) }),
56895534 }
56905535 }
56915536 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,
64876332 const ty_op = air.data(air.inst_index).ty_op;
64886333 const dst_ty = ty_op.ty.toType();
64896334 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) });
64916336 const dst_int_info = dst_ty.intInfo(zcu);
64926337 const src_bits = src_ty.floatBits(isel.target);
64936338 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,
66176462 }
66186463 try call.finishParams(isel);
66196464 },
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) }),
66216466 }
66226467 }
66236468 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,
66306475 const dst_ty = ty_op.ty.toType();
66316476 const src_ty = isel.air.typeOf(ty_op.operand, ip);
66326477 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) });
66346479 const src_int_info = src_ty.intInfo(zcu);
66356480 switch (@max(dst_bits, src_int_info.bits)) {
66366481 0 => unreachable,
......@@ -6757,7 +6602,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
67576602 }
67586603 try call.finishParams(isel);
67596604 },
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) }),
67616606 }
67626607 }
67636608 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,
68366681
68376682 break :air_tag if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
68386683 },
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) }),
68406685 }
68416686 };
68426687
......@@ -7157,7 +7002,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
71577002 else => unreachable,
71587003 },
71597004 }),
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) }),
71617006 }
71627007 }
71637008 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,
74127257 .nav = ty_nav.nav,
74137258 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
74147259 });
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 }));
74167264 try isel.nav_relocs.append(gpa, .{
74177265 .nav = ty_nav.nav,
74187266 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
......@@ -8499,6 +8347,217 @@ fn ctzLimb(
84998347 }
85008348}
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
85028561fn loadReg(
85038562 isel: *Select,
85048563 ra: Register.Alias,
......@@ -9272,9 +9331,9 @@ pub const Value = struct {
92729331 opts: AddOrSubtractOptions,
92739332 ) !void {
92749333 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) });
92769335 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) });
92789337 var part_offset = res_vi.size(isel);
92799338 var need_wrap = switch (opts.overflow) {
92809339 .@"unreachable" => false,
......@@ -10783,7 +10842,7 @@ pub const Value = struct {
1078310842 .err_name => continue :constant_key .{ .undef = error_union_type.payload_type },
1078410843 .payload => |payload| {
1078510844 constant = payload;
10786 constant_key = ip.indexToKey(payload);
10845 constant_key = ip.indexToKey(constant);
1078710846 continue :constant_key constant_key;
1078810847 },
1078910848 }
......@@ -10915,7 +10974,10 @@ pub const Value = struct {
1091510974 .addend = ptr.byte_offset,
1091610975 },
1091710976 });
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 }));
1091910981 try isel.nav_relocs.append(zcu.gpa, .{
1092010982 .nav = nav,
1092110983 .reloc = .{
......@@ -11017,7 +11079,7 @@ pub const Value = struct {
1101711079 } } else .{ .undef = child_ty },
1101811080 else => |child| {
1101911081 constant = child;
11020 constant_key = ip.indexToKey(child);
11082 constant_key = ip.indexToKey(constant);
1102111083 continue :constant_key constant_key;
1102211084 },
1102311085 };
......@@ -11040,7 +11102,7 @@ pub const Value = struct {
1104011102 },
1104111103 .repeated_elem => |repeated_elem| {
1104211104 constant = repeated_elem;
11043 constant_key = ip.indexToKey(repeated_elem);
11105 constant_key = ip.indexToKey(constant);
1104411106 continue :constant_key constant_key;
1104511107 },
1104611108 };
......@@ -11099,6 +11161,28 @@ pub const Value = struct {
1109911161 }
1110011162 },
1110111163 },
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 },
1110211186 else => {},
1110311187 }
1110411188 var buffer: [16]u8 = @splat(0);
......@@ -11188,7 +11272,7 @@ fn initValueAdvanced(
1118811272}
1118911273pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1119011274 errdefer |err| @panic(@errorName(err));
11191 const stderr = std.debug.lockStderrWriter(&.{});
11275 const stderr, _ = std.debug.lockStderrWriter(&.{});
1119211276 defer std.debug.unlockStderrWriter();
1119311277
1119411278 const zcu = isel.pt.zcu;
......@@ -11259,7 +11343,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1125911343 first = false;
1126011344 };
1126111345 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 });
1126311347 first = false;
1126411348 }
1126511349 }
......@@ -11267,8 +11351,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1126711351 switch (value.flags.parent_tag) {
1126811352 .unallocated => if (value.offset_from_parent != 0) try stderr.print(" +0x{x}", .{value.offset_from_parent}),
1126911353 .stack_slot => {
11270 try stderr.print(" [{s}, #{s}0x{x}", .{
11271 @tagName(value.parent_payload.stack_slot.base),
11354 try stderr.print(" [{t}, #{s}0x{x}", .{
11355 value.parent_payload.stack_slot.base,
1127211356 if (value.parent_payload.stack_slot.offset < 0) "-" else "",
1127311357 @abs(value.parent_payload.stack_slot.offset),
1127411358 });
......@@ -11282,7 +11366,7 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1128211366 isel.fmtConstant(value.parent_payload.constant),
1128311367 }),
1128411368 }
11285 try stderr.print(" align({s})", .{@tagName(value.flags.alignment)});
11369 try stderr.print(" align({t})", .{value.flags.alignment});
1128611370 switch (value.flags.location_tag) {
1128711371 .large => try stderr.print(" size=0x{x} large", .{value.location_payload.large.size}),
1128811372 .small => {
......@@ -11292,8 +11376,8 @@ pub fn dumpValues(isel: *Select, which: enum { only_referenced, all }) void {
1129211376 .unsigned => {},
1129311377 .signed => try stderr.writeAll(" signed"),
1129411378 }
11295 if (loc.hint != .zr) try stderr.print(" hint={s}", .{@tagName(loc.hint)});
11296 if (loc.register != .zr) try stderr.print(" loc={s}", .{@tagName(loc.register)});
11379 if (loc.hint != .zr) try stderr.print(" hint={t}", .{loc.hint});
11380 if (loc.register != .zr) try stderr.print(" loc={t}", .{loc.register});
1129711381 },
1129811382 }
1129911383 try stderr.print(" refs={d}\n", .{value.refs});
src/crash_report.zig+1-1
......@@ -95,7 +95,7 @@ fn dumpCrashContext() Io.Writer.Error!void {
9595
9696 // TODO: this does mean that a different thread could grab the stderr mutex between the context
9797 // and the actual panic printing, which would be quite confusing.
98 const stderr = std.debug.lockStderrWriter(&.{});
98 const stderr, _ = std.debug.lockStderrWriter(&.{});
9999 defer std.debug.unlockStderrWriter();
100100
101101 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) !
124124 try wip_errors.addZirErrorMessages(zir, tree, source_code, "<stdin>");
125125 var error_bundle = try wip_errors.toOwnedBundle("");
126126 defer error_bundle.deinit(gpa);
127 error_bundle.renderToStdErr(color.renderOptions());
127 error_bundle.renderToStdErr(.{}, color);
128128 process.exit(2);
129129 }
130130 } else {
......@@ -138,7 +138,7 @@ pub fn run(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !
138138 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, "<stdin>");
139139 var error_bundle = try wip_errors.toOwnedBundle("");
140140 defer error_bundle.deinit(gpa);
141 error_bundle.renderToStdErr(color.renderOptions());
141 error_bundle.renderToStdErr(.{}, color);
142142 process.exit(2);
143143 }
144144 }
......@@ -317,7 +317,7 @@ fn fmtPathFile(
317317 try wip_errors.addZirErrorMessages(zir, tree, source_code, file_path);
318318 var error_bundle = try wip_errors.toOwnedBundle("");
319319 defer error_bundle.deinit(gpa);
320 error_bundle.renderToStdErr(fmt.color.renderOptions());
320 error_bundle.renderToStdErr(.{}, fmt.color);
321321 fmt.any_error = true;
322322 }
323323 },
......@@ -332,7 +332,7 @@ fn fmtPathFile(
332332 try wip_errors.addZoirErrorMessages(zoir, tree, source_code, file_path);
333333 var error_bundle = try wip_errors.toOwnedBundle("");
334334 defer error_bundle.deinit(gpa);
335 error_bundle.renderToStdErr(fmt.color.renderOptions());
335 error_bundle.renderToStdErr(.{}, fmt.color);
336336 fmt.any_error = true;
337337 }
338338 },
src/libs/mingw.zig+4-4
......@@ -312,7 +312,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
312312 const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" });
313313
314314 if (comp.verbose_cc) print: {
315 var stderr = std.debug.lockStderrWriter(&.{});
315 var stderr, _ = std.debug.lockStderrWriter(&.{});
316316 defer std.debug.unlockStderrWriter();
317317 nosuspend stderr.print("def file: {s}\n", .{def_file_path}) catch break :print;
318318 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 {
332332
333333 if (aro_comp.diagnostics.output.to_list.messages.items.len != 0) {
334334 var buffer: [64]u8 = undefined;
335 const w = std.debug.lockStderrWriter(&buffer);
335 const w, const ttyconf = std.debug.lockStderrWriter(&buffer);
336336 defer std.debug.unlockStderrWriter();
337337 for (aro_comp.diagnostics.output.to_list.messages.items) |msg| {
338338 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 {};
340340 return error.AroPreprocessorFailed;
341341 }
342342 }
......@@ -356,7 +356,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
356356 error.OutOfMemory => |e| return e,
357357 error.ParseError => {
358358 var buffer: [64]u8 = undefined;
359 const w = std.debug.lockStderrWriter(&buffer);
359 const w, _ = std.debug.lockStderrWriter(&buffer);
360360 defer std.debug.unlockStderrWriter();
361361 try w.writeAll("error: ");
362362 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
10281028 const module = parse(std.testing.allocator, source, machine_type, .mingw, &diagnostics) catch |err| switch (err) {
10291029 error.OutOfMemory => |e| return e,
10301030 error.ParseError => {
1031 const stderr = std.debug.lockStderrWriter(&.{});
1031 const stderr, _ = std.debug.lockStderrWriter(&.{});
10321032 defer std.debug.unlockStderrWriter();
10331033 try diagnostics.writeMsg(stderr, source);
10341034 try stderr.writeByte('\n');
src/link.zig+1-1
......@@ -2215,7 +2215,7 @@ fn resolvePathInputLib(
22152215 var error_bundle = try wip_errors.toOwnedBundle("");
22162216 defer error_bundle.deinit(gpa);
22172217
2218 error_bundle.renderToStdErr(color.renderOptions());
2218 error_bundle.renderToStdErr(.{}, color);
22192219
22202220 std.process.exit(1);
22212221 }
src/link/Coff.zig+1-1
......@@ -2335,7 +2335,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
23352335}
23362336
23372337pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) void {
2338 const w = std.debug.lockStderrWriter(&.{});
2338 const w, _ = std.debug.lockStderrWriter(&.{});
23392339 defer std.debug.unlockStderrWriter();
23402340 coff.printNode(tid, w, .root, 0) catch {};
23412341}
src/link/Elf2.zig+1-1
......@@ -1965,7 +1965,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
19651965}
19661966
19671967pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) void {
1968 const w = std.debug.lockStderrWriter(&.{});
1968 const w, _ = std.debug.lockStderrWriter(&.{});
19691969 defer std.debug.unlockStderrWriter();
19701970 elf.printNode(tid, w, .root, 0) catch {};
19711971}
src/main.zig+9-9
......@@ -4520,7 +4520,7 @@ fn updateModule(comp: *Compilation, color: Color, prog_node: std.Progress.Node)
45204520 defer errors.deinit(comp.gpa);
45214521
45224522 if (errors.errorMessageCount() > 0) {
4523 errors.renderToStdErr(color.renderOptions());
4523 errors.renderToStdErr(.{}, color);
45244524 return error.CompileErrorsReported;
45254525 }
45264526}
......@@ -4573,7 +4573,7 @@ fn cmdTranslateC(
45734573 return;
45744574 } else {
45754575 const color: Color = .auto;
4576 result.errors.renderToStdErr(color.renderOptions());
4576 result.errors.renderToStdErr(.{}, color);
45774577 process.exit(1);
45784578 }
45794579 }
......@@ -5199,7 +5199,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
51995199
52005200 if (fetch.error_bundle.root_list.items.len > 0) {
52015201 var errors = try fetch.error_bundle.toOwnedBundle("");
5202 errors.renderToStdErr(color.renderOptions());
5202 errors.renderToStdErr(.{}, color);
52035203 process.exit(1);
52045204 }
52055205
......@@ -6135,7 +6135,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
61356135 try wip_errors.init(arena);
61366136 try wip_errors.addZirErrorMessages(zir, tree, source, display_path);
61376137 var error_bundle = try wip_errors.toOwnedBundle("");
6138 error_bundle.renderToStdErr(color.renderOptions());
6138 error_bundle.renderToStdErr(.{}, color);
61396139 if (zir.loweringFailed()) {
61406140 process.exit(1);
61416141 }
......@@ -6206,7 +6206,7 @@ fn cmdAstCheck(arena: Allocator, io: Io, args: []const []const u8) !void {
62066206 try wip_errors.init(arena);
62076207 try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path);
62086208 var error_bundle = try wip_errors.toOwnedBundle("");
6209 error_bundle.renderToStdErr(color.renderOptions());
6209 error_bundle.renderToStdErr(.{}, color);
62106210 process.exit(1);
62116211 }
62126212
......@@ -6479,7 +6479,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
64796479 try wip_errors.init(arena);
64806480 try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path);
64816481 var error_bundle = try wip_errors.toOwnedBundle("");
6482 error_bundle.renderToStdErr(color.renderOptions());
6482 error_bundle.renderToStdErr(.{}, color);
64836483 process.exit(1);
64846484 }
64856485
......@@ -6491,7 +6491,7 @@ fn cmdChangelist(arena: Allocator, io: Io, args: []const []const u8) !void {
64916491 try wip_errors.init(arena);
64926492 try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path);
64936493 var error_bundle = try wip_errors.toOwnedBundle("");
6494 error_bundle.renderToStdErr(color.renderOptions());
6494 error_bundle.renderToStdErr(.{}, color);
64956495 process.exit(1);
64966496 }
64976497
......@@ -6948,7 +6948,7 @@ fn cmdFetch(
69486948
69496949 if (fetch.error_bundle.root_list.items.len > 0) {
69506950 var errors = try fetch.error_bundle.toOwnedBundle("");
6951 errors.renderToStdErr(color.renderOptions());
6951 errors.renderToStdErr(.{}, color);
69526952 process.exit(1);
69536953 }
69546954
......@@ -7304,7 +7304,7 @@ fn loadManifest(
73047304
73057305 var error_bundle = try wip_errors.toOwnedBundle("");
73067306 defer error_bundle.deinit(gpa);
7307 error_bundle.renderToStdErr(options.color.renderOptions());
7307 error_bundle.renderToStdErr(.{}, options.color);
73087308
73097309 process.exit(2);
73107310 }
test/behavior/enum.zig-2
......@@ -899,7 +899,6 @@ test "enum value allocation" {
899899}
900900
901901test "enum literal casting to tagged union" {
902 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
903902 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
904903 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" {
935934}
936935
937936test "constant enum initialization with differing sizes" {
938 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
939937 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
940938 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
941939 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/optional.zig-2
......@@ -149,7 +149,6 @@ test "nested optional field in struct" {
149149}
150150
151151test "equality compare optionals and non-optionals" {
152 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
153152 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
154153 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
155154 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -209,7 +208,6 @@ test "equality compare optionals and non-optionals" {
209208}
210209
211210test "compare optionals with modified payloads" {
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213211 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
214212
215213 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" {
576576}
577577
578578test "switch prongs with cases with identical payload types" {
579 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
580579 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
581580 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
582581
......@@ -824,7 +823,6 @@ test "comptime inline switch" {
824823}
825824
826825test "switch capture peer type resolution" {
827 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
828826 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
829827
830828 const U = union(enum) {
test/behavior/tuple.zig-1
......@@ -496,7 +496,6 @@ test "anon tuple field referencing comptime var isn't comptime" {
496496}
497497
498498test "tuple with runtime value coerced into a slice with a sentinel" {
499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
500499 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
501500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
502501 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/union.zig-6
......@@ -208,7 +208,6 @@ const Payload = union(Letter) {
208208};
209209
210210test "union with specified enum tag" {
211 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
212211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
213212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
214213 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
......@@ -219,7 +218,6 @@ test "union with specified enum tag" {
219218}
220219
221220test "packed union generates correctly aligned type" {
222 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
223221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
224222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225223 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
......@@ -605,7 +603,6 @@ fn returnAnInt(x: i32) TaggedFoo {
605603}
606604
607605test "tagged union with all void fields but a meaningful tag" {
608 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
609606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
610607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
611608
......@@ -1032,7 +1029,6 @@ test "containers with single-field enums" {
10321029}
10331030
10341031test "@unionInit on union with tag but no fields" {
1035 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10361032 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10371033 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10381034
......@@ -1446,8 +1442,6 @@ test "access the tag of a global tagged union" {
14461442}
14471443
14481444test "coerce enum literal to union in result loc" {
1449 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1450
14511445 const U = union(enum) {
14521446 a,
14531447 b: u8,
tools/gen_spirv_spec.zig+3-4
......@@ -89,10 +89,9 @@ pub fn main() !void {
8989 const output = allocating.written()[0 .. allocating.written().len - 1 :0];
9090
9191 var tree = try std.zig.Ast.parse(allocator, output, .zig);
92 var color: std.zig.Color = .on;
9392
9493 if (tree.errors.len != 0) {
95 try std.zig.printAstErrorsToStderr(allocator, tree, "", color);
94 try std.zig.printAstErrorsToStderr(allocator, tree, "", .auto);
9695 return;
9796 }
9897
......@@ -104,7 +103,7 @@ pub fn main() !void {
104103 try wip_errors.addZirErrorMessages(zir, tree, output, "");
105104 var error_bundle = try wip_errors.toOwnedBundle("");
106105 defer error_bundle.deinit(allocator);
107 error_bundle.renderToStdErr(color.renderOptions());
106 error_bundle.renderToStdErr(.{}, .auto);
108107 }
109108
110109 const formatted_output = try tree.renderAlloc(allocator);
......@@ -931,7 +930,7 @@ fn parseHexInt(text: []const u8) !u31 {
931930}
932931
933932fn usageAndExit(arg0: []const u8, code: u8) noreturn {
934 const stderr = std.debug.lockStderrWriter(&.{});
933 const stderr, _ = std.debug.lockStderrWriter(&.{});
935934 stderr.print(
936935 \\Usage: {s} <SPIRV-Headers repository path> <path/to/zig/src/codegen/spirv/extinst.zig.grammar.json>
937936 \\
tools/generate_linux_syscalls.zig+3-1
......@@ -177,7 +177,9 @@ pub fn main() !void {
177177
178178 const args = try std.process.argsAlloc(gpa);
179179 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);
181183 std.process.exit(1);
182184 }
183185 const linux_path = args[1];
tools/incr-check.zig+5-10
......@@ -340,8 +340,7 @@ const Eval = struct {
340340 .unknown => return,
341341 .compile_errors => |ce| ce,
342342 .stdout, .exit_code => {
343 const color: std.zig.Color = .auto;
344 error_bundle.renderToStdErr(color.renderOptions());
343 error_bundle.renderToStdErr(.{}, .auto);
345344 eval.fatal("update '{s}': unexpected compile errors", .{update.name});
346345 },
347346 };
......@@ -350,8 +349,7 @@ const Eval = struct {
350349
351350 for (error_bundle.getMessages()) |err_idx| {
352351 if (expected_idx == expected.errors.len) {
353 const color: std.zig.Color = .auto;
354 error_bundle.renderToStdErr(color.renderOptions());
352 error_bundle.renderToStdErr(.{}, .auto);
355353 eval.fatal("update '{s}': more errors than expected", .{update.name});
356354 }
357355 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx);
......@@ -359,8 +357,7 @@ const Eval = struct {
359357
360358 for (error_bundle.getNotes(err_idx)) |note_idx| {
361359 if (expected_idx == expected.errors.len) {
362 const color: std.zig.Color = .auto;
363 error_bundle.renderToStdErr(color.renderOptions());
360 error_bundle.renderToStdErr(.{}, .auto);
364361 eval.fatal("update '{s}': more error notes than expected", .{update.name});
365362 }
366363 try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx);
......@@ -369,8 +366,7 @@ const Eval = struct {
369366 }
370367
371368 if (!std.mem.eql(u8, error_bundle.getCompileLogOutput(), expected.compile_log_output)) {
372 const color: std.zig.Color = .auto;
373 error_bundle.renderToStdErr(color.renderOptions());
369 error_bundle.renderToStdErr(.{}, .auto);
374370 eval.fatal("update '{s}': unexpected compile log output", .{update.name});
375371 }
376372 }
......@@ -404,8 +400,7 @@ const Eval = struct {
404400 expected.column != src.column + 1 or
405401 !std.mem.eql(u8, expected.msg, msg))
406402 {
407 const color: std.zig.Color = .auto;
408 eb.renderToStdErr(color.renderOptions());
403 eb.renderToStdErr(.{}, .auto);
409404 eval.fatal("update '{s}': compile error did not match expected error", .{update.name});
410405 }
411406 }
tools/update_clang_options.zig+3-1
......@@ -961,7 +961,9 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool {
961961}
962962
963963fn 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);
965967 std.process.exit(1);
966968}
967969
tools/update_cpu_features.zig+1-1
......@@ -2167,7 +2167,7 @@ fn processOneTarget(job: Job) void {
21672167}
21682168
21692169fn usageAndExit(arg0: []const u8, code: u8) noreturn {
2170 const stderr = std.debug.lockStderrWriter(&.{});
2170 const stderr, _ = std.debug.lockStderrWriter(&.{});
21712171 stderr.print(
21722172 \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter]
21732173 \\
tools/update_crc_catalog.zig+3-1
......@@ -190,7 +190,9 @@ pub fn main() anyerror!void {
190190}
191191
192192fn 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);
194196 std.process.exit(1);
195197}
196198