authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-04-21 23:28:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-01 16:35:28-07:00
logfceec91f7787613256d95b20891c18659adc0494
tree1b5f6a2bb6d1214c10386aa4717bcdcc08d744c9
parent4dc3a9444cd94d2d10b427d8dd7a3515f9dc96ea

cbe: port to new `std.io.BufferedWriter` API

when rebasing I gave up on the conflicts of src/link/C.zig and copied the file from origin/master which was 710632b45cd7a7081af82af418eb3e405f7aa35e

15 files changed, 2057 insertions(+), 1963 deletions(-)

lib/std/Build/Step/CheckObject.zig+2-2
......@@ -1790,7 +1790,7 @@ const ElfDumper = struct {
17901790 .p32 => @sizeOf(u32),
17911791 .p64 => @sizeOf(u64),
17921792 };
1793 try br.discard(num * ptr_size);
1793 _ = try br.discard(.limited(num * ptr_size));
17941794 const strtab = br.bufferContents();
17951795
17961796 assert(ctx.symtab.len == 0);
......@@ -2569,7 +2569,7 @@ const WasmDumper = struct {
25692569 if (!flags.passive) try parseDumpInit(step, br, bw);
25702570 const size = try br.takeLeb128(u32);
25712571 try bw.print("size {d}\n", .{size});
2572 try br.discard(size); // we do not care about the content of the segments
2572 _ = try br.discard(.limited(size)); // we do not care about the content of the segments
25732573 }
25742574 },
25752575 else => unreachable,
lib/std/debug.zig+1-1
......@@ -304,8 +304,8 @@ pub fn dumpHexFallible(bw: *std.io.BufferedWriter, ttyconf: std.io.tty.Config, b
304304test dumpHexFallible {
305305 const bytes: []const u8 = &.{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x12, 0x13 };
306306 var aw: std.io.AllocatingWriter = undefined;
307 defer aw.deinit();
308307 var bw = aw.init(std.testing.allocator);
308 defer aw.deinit();
309309
310310 try dumpHexFallible(&bw, .no_color, bytes);
311311 const expected = try std.fmt.allocPrint(std.testing.allocator,
lib/std/fmt.zig+2
......@@ -856,6 +856,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) usize {
856856pub fn allocPrint(gpa: Allocator, comptime fmt: []const u8, args: anytype) Allocator.Error![]u8 {
857857 var aw: std.io.AllocatingWriter = undefined;
858858 try aw.initCapacity(gpa, fmt.len);
859 defer aw.deinit();
859860 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {
860861 error.WriteFailed => return error.OutOfMemory,
861862 };
......@@ -870,6 +871,7 @@ pub fn allocPrintSentinel(
870871) Allocator.Error![:sentinel]u8 {
871872 var aw: std.io.AllocatingWriter = undefined;
872873 try aw.initCapacity(gpa, fmt.len);
874 defer aw.deinit();
873875 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {
874876 error.WriteFailed => return error.OutOfMemory,
875877 };
lib/std/fs/File.zig+2-2
......@@ -934,7 +934,7 @@ pub fn writeFileAll(self: File, in_file: File, options: BufferedWriter.WriteFile
934934 var buffer: [2000]u8 = undefined;
935935 var bw = file_writer.interface().buffered(&buffer);
936936 bw.writeFileAll(in_file, options) catch |err| switch (err) {
937 error.WriteFailed => if (file_writer.err) |_| unreachable else |e| return e,
937 error.WriteFailed => return file_writer.err.?,
938938 else => |e| return e,
939939 };
940940}
......@@ -1232,7 +1232,7 @@ pub const Reader = struct {
12321232
12331233pub const Writer = struct {
12341234 file: File,
1235 err: WriteError!void = {},
1235 err: ?WriteError = null,
12361236 mode: Writer.Mode = .positional,
12371237 pos: u64 = 0,
12381238 sendfile_err: ?SendfileError = null,
lib/std/io/BufferedReader.zig+1-1
......@@ -73,7 +73,7 @@ pub fn readVecAll(br: *BufferedReader, data: [][]u8) Reader.Error!void {
7373 defer data[index] = untruncated;
7474 truncate += try br.readVec(data[index..]);
7575 }
76 while (index < data.len and truncate <= data[index].len) {
76 while (index < data.len and truncate >= data[index].len) {
7777 truncate -= data[index].len;
7878 index += 1;
7979 }
lib/std/io/BufferedWriter.zig+1-1
......@@ -150,7 +150,7 @@ pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void {
150150 defer data[index] = untruncated;
151151 truncate += try bw.writeVec(data[index..]);
152152 }
153 while (index < data.len and truncate <= data[index].len) {
153 while (index < data.len and truncate >= data[index].len) {
154154 truncate -= data[index].len;
155155 index += 1;
156156 }
lib/std/io/Reader.zig+1-1
......@@ -177,8 +177,8 @@ pub const ReadAllocError = std.mem.Allocator.Error || ShortError;
177177pub fn readAlloc(r: Reader, gpa: std.mem.Allocator, max_size: usize) ReadAllocError![]u8 {
178178 const readFn = r.vtable.read;
179179 var aw: std.io.AllocatingWriter = undefined;
180 errdefer aw.deinit();
181180 aw.init(gpa);
181 errdefer aw.deinit();
182182 var remaining = max_size;
183183 while (remaining > 0) {
184184 const n = readFn(r.context, &aw.buffered_writer, .limited(remaining)) catch |err| switch (err) {
lib/std/zon/stringify.zig+10-10
......@@ -1053,8 +1053,8 @@ fn expectSerializeEqual(
10531053 options: SerializeOptions,
10541054) !void {
10551055 var aw: std.io.AllocatingWriter = undefined;
1056 defer aw.deinit();
10571056 const bw = aw.init(std.testing.allocator);
1057 defer aw.deinit();
10581058
10591059 try serialize(value, options, bw);
10601060 try std.testing.expectEqualStrings(expected, aw.getWritten());
......@@ -1155,8 +1155,8 @@ test "std.zon stringify whitespace, high level API" {
11551155
11561156test "std.zon stringify whitespace, low level API" {
11571157 var aw: std.io.AllocatingWriter = undefined;
1158 defer aw.deinit();
11591158 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1159 defer aw.deinit();
11601160
11611161 for ([2]bool{ true, false }) |whitespace| {
11621162 s.options = .{ .whitespace = whitespace };
......@@ -1512,8 +1512,8 @@ test "std.zon stringify whitespace, low level API" {
15121512
15131513test "std.zon stringify utf8 codepoints" {
15141514 var aw: std.io.AllocatingWriter = undefined;
1515 defer aw.deinit();
15161515 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1516 defer aw.deinit();
15171517
15181518 // Printable ASCII
15191519 try s.int('a');
......@@ -1622,8 +1622,8 @@ test "std.zon stringify utf8 codepoints" {
16221622
16231623test "std.zon stringify strings" {
16241624 var aw: std.io.AllocatingWriter = undefined;
1625 defer aw.deinit();
16261625 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1626 defer aw.deinit();
16271627
16281628 // Minimal case
16291629 try s.string("abc⚡\n");
......@@ -1692,8 +1692,8 @@ test "std.zon stringify strings" {
16921692
16931693test "std.zon stringify multiline strings" {
16941694 var aw: std.io.AllocatingWriter = undefined;
1695 defer aw.deinit();
16961695 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1696 defer aw.deinit();
16971697
16981698 inline for (.{ true, false }) |whitespace| {
16991699 s.options.whitespace = whitespace;
......@@ -1912,8 +1912,8 @@ test "std.zon stringify skip default fields" {
19121912
19131913test "std.zon depth limits" {
19141914 var aw: std.io.AllocatingWriter = undefined;
1915 defer aw.deinit();
19161915 const bw = aw.init(std.testing.allocator);
1916 defer aw.deinit();
19171917
19181918 const Recurse = struct { r: []const @This() };
19191919
......@@ -2173,8 +2173,8 @@ test "std.zon stringify primitives" {
21732173
21742174test "std.zon stringify ident" {
21752175 var aw: std.io.AllocatingWriter = undefined;
2176 defer aw.deinit();
21772176 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2177 defer aw.deinit();
21782178
21792179 try expectSerializeEqual(".{ .a = 0 }", .{ .a = 0 }, .{});
21802180 try s.ident("a");
......@@ -2220,8 +2220,8 @@ test "std.zon stringify ident" {
22202220
22212221test "std.zon stringify as tuple" {
22222222 var aw: std.io.AllocatingWriter = undefined;
2223 defer aw.deinit();
22242223 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2224 defer aw.deinit();
22252225
22262226 // Tuples
22272227 try s.tuple(.{ 1, 2 }, .{});
......@@ -2241,8 +2241,8 @@ test "std.zon stringify as tuple" {
22412241
22422242test "std.zon stringify as float" {
22432243 var aw: std.io.AllocatingWriter = undefined;
2244 defer aw.deinit();
22452244 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2245 defer aw.deinit();
22462246
22472247 // Comptime float
22482248 try s.float(2.5);
......@@ -2345,8 +2345,8 @@ test "std.zon pointers" {
23452345
23462346test "std.zon tuple/struct field" {
23472347 var aw: std.io.AllocatingWriter = undefined;
2348 defer aw.deinit();
23492348 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2349 defer aw.deinit();
23502350
23512351 // Test on structs
23522352 {
src/Sema.zig+1
......@@ -37371,6 +37371,7 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,
3737137371
3737237372 var second_path_aw: std.io.AllocatingWriter = undefined;
3737337373 second_path_aw.init(arena);
37374 defer second_path_aw.deinit();
3737437375 const inter_name = try std.fmt.allocPrint(arena, "v{d}", .{intermediate_value_count});
3737537376 const deriv_start = @import("print_value.zig").printPtrDerivation(
3737637377 derivation,
src/Zcu.zig+4-4
......@@ -2857,7 +2857,7 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.F
28572857 var cache_fr = cache_file.reader();
28582858 var cache_br = cache_fr.interface().unbuffered();
28592859 cache_br.readVecAll(&vecs) catch |err| switch (err) {
2860 error.ReadFailed => if (cache_fr.err) |_| unreachable else |e| return e,
2860 error.ReadFailed => return cache_fr.err.?,
28612861 error.EndOfStream => return error.UnexpectedFileSize,
28622862 };
28632863 if (data_has_safety_tag) {
......@@ -2912,7 +2912,7 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S
29122912 var cache_fw = cache_file.writer();
29132913 var cache_bw = cache_fw.interface().unbuffered();
29142914 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {
2915 error.WriteFailed => if (cache_fw.err) |_| unreachable else |e| return e,
2915 error.WriteFailed => return cache_fw.err.?,
29162916 };
29172917}
29182918
......@@ -2943,7 +2943,7 @@ pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir
29432943 var cache_fw = cache_file.writer();
29442944 var cache_bw = cache_fw.interface().unbuffered();
29452945 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {
2946 error.WriteFailed => if (cache_fw.err) |_| unreachable else |e| return e,
2946 error.WriteFailed => return cache_fw.err.?,
29472947 };
29482948}
29492949
......@@ -2986,7 +2986,7 @@ pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs
29862986 var cache_fr = cache_file.reader();
29872987 var cache_br = cache_fr.interface().unbuffered();
29882988 cache_br.readVecAll(&vecs) catch |err| switch (err) {
2989 error.ReadFailed => if (cache_fr.err) |_| unreachable else |e| return e,
2989 error.ReadFailed => return cache_fr.err.?,
29902990 error.EndOfStream => return error.UnexpectedFileSize,
29912991 };
29922992 return zoir;
src/Zcu/PerThread.zig+2-2
......@@ -254,7 +254,7 @@ pub fn updateFile(
254254 var source_fr = source_file.reader();
255255 var source_br = source_fr.interface().unbuffered();
256256 source_br.readSlice(source) catch |err| switch (err) {
257 error.ReadFailed => if (source_fr.err) |_| unreachable else |e| return e,
257 error.ReadFailed => return source_fr.err.?,
258258 error.EndOfStream => return error.UnexpectedEndOfFile,
259259 };
260260
......@@ -2443,7 +2443,7 @@ fn updateEmbedFileInner(
24432443 var fr = file.reader();
24442444 var br = fr.interface().unbuffered();
24452445 br.readSlice(bytes[0..size]) catch |err| switch (err) {
2446 error.ReadFailed => if (fr.err) |_| unreachable else |e| return e,
2446 error.ReadFailed => return fr.err.?,
24472447 error.EndOfStream => return error.UnexpectedEof,
24482448 };
24492449 bytes[size] = 0;
src/codegen/c.zig+2006-1915
......@@ -69,6 +69,8 @@ pub const Mir = struct {
6969 }
7070};
7171
72pub const Error = std.io.Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
73
7274pub const CType = @import("c/Type.zig");
7375
7476pub const CValue = union(enum) {
......@@ -342,24 +344,23 @@ fn isReservedIdent(ident: []const u8) bool {
342344
343345fn formatIdent(
344346 ident: []const u8,
347 bw: *std.io.BufferedWriter,
345348 comptime fmt_str: []const u8,
346 _: std.fmt.FormatOptions,
347 writer: anytype,
348) @TypeOf(writer).Error!void {
349) std.io.Writer.Error!void {
349350 const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.
350351 if (solo and isReservedIdent(ident)) {
351 try writer.writeAll("zig_e_");
352 try bw.writeAll("zig_e_");
352353 }
353354 for (ident, 0..) |c, i| {
354355 switch (c) {
355 'a'...'z', 'A'...'Z', '_' => try writer.writeByte(c),
356 '.' => try writer.writeByte('_'),
356 'a'...'z', 'A'...'Z', '_' => try bw.writeByte(c),
357 '.' => try bw.writeByte('_'),
357358 '0'...'9' => if (i == 0) {
358 try writer.print("_{x:2}", .{c});
359 try bw.print("_{x:2}", .{c});
359360 } else {
360 try writer.writeByte(c);
361 try bw.writeByte(c);
361362 },
362 else => try writer.print("_{x:2}", .{c}),
363 else => try bw.print("_{x:2}", .{c}),
363364 }
364365 }
365366}
......@@ -373,14 +374,13 @@ const CTypePoolStringFormatData = struct {
373374};
374375fn formatCTypePoolString(
375376 data: CTypePoolStringFormatData,
377 bw: *std.io.BufferedWriter,
376378 comptime fmt_str: []const u8,
377 fmt_opts: std.fmt.FormatOptions,
378 writer: anytype,
379) @TypeOf(writer).Error!void {
379) std.io.Writer.Error!void {
380380 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
381 try formatIdent(slice, fmt_str, fmt_opts, writer)
381 try formatIdent(slice, bw, fmt_str)
382382 else
383 try writer.print("{}", .{data.ctype_pool_string.fmt(data.ctype_pool)});
383 try bw.print("{f}", .{data.ctype_pool_string.fmt(data.ctype_pool)});
384384}
385385pub fn fmtCTypePoolString(
386386 ctype_pool_string: CType.Pool.String,
......@@ -440,18 +440,18 @@ pub const Function = struct {
440440 const ty = f.typeOf(ref);
441441
442442 const result: CValue = if (lowersToArray(ty, pt)) result: {
443 const writer = f.object.codeHeaderWriter();
443 const ch = &f.object.code_header.buffered_writer;
444444 const decl_c_value = try f.allocLocalValue(.{
445445 .ctype = try f.ctypeFromType(ty, .complete),
446446 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)),
447447 });
448448 const gpa = f.object.dg.gpa;
449449 try f.allocs.put(gpa, decl_c_value.new_local, false);
450 try writer.writeAll("static ");
451 try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, Const, .none, .complete);
452 try writer.writeAll(" = ");
453 try f.object.dg.renderValue(writer, val, .StaticInitializer);
454 try writer.writeAll(";\n ");
450 try ch.writeAll("static ");
451 try f.object.dg.renderTypeAndName(ch, ty, decl_c_value, Const, .none, .complete);
452 try ch.writeAll(" = ");
453 try f.object.dg.renderValue(ch, val, .StaticInitializer);
454 try ch.writeAll(";\n ");
455455 break :result .{ .local = decl_c_value.new_local };
456456 } else .{ .constant = val };
457457
......@@ -504,75 +504,75 @@ pub const Function = struct {
504504 return result;
505505 }
506506
507 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {
507 fn writeCValue(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, location: ValueRenderLocation) !void {
508508 switch (c_value) {
509509 .none => unreachable,
510 .new_local, .local => |i| try w.print("t{d}", .{i}),
511 .local_ref => |i| try w.print("&t{d}", .{i}),
512 .constant => |val| try f.object.dg.renderValue(w, val, location),
513 .arg => |i| try w.print("a{d}", .{i}),
514 .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),
515 .undef => |ty| try f.object.dg.renderUndefValue(w, ty, location),
516 else => try f.object.dg.writeCValue(w, c_value),
510 .new_local, .local => |i| try bw.print("t{d}", .{i}),
511 .local_ref => |i| try bw.print("&t{d}", .{i}),
512 .constant => |val| try f.object.dg.renderValue(bw, val, location),
513 .arg => |i| try bw.print("a{d}", .{i}),
514 .arg_array => |i| try f.writeCValueMember(bw, .{ .arg = i }, .{ .identifier = "array" }),
515 .undef => |ty| try f.object.dg.renderUndefValue(bw, ty, location),
516 else => try f.object.dg.writeCValue(bw, c_value),
517517 }
518518 }
519519
520 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {
520 fn writeCValueDeref(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue) !void {
521521 switch (c_value) {
522522 .none => unreachable,
523523 .new_local, .local, .constant => {
524 try w.writeAll("(*");
525 try f.writeCValue(w, c_value, .Other);
526 try w.writeByte(')');
524 try bw.writeAll("(*");
525 try f.writeCValue(bw, c_value, .Other);
526 try bw.writeByte(')');
527527 },
528 .local_ref => |i| try w.print("t{d}", .{i}),
529 .arg => |i| try w.print("(*a{d})", .{i}),
528 .local_ref => |i| try bw.print("t{d}", .{i}),
529 .arg => |i| try bw.print("(*a{d})", .{i}),
530530 .arg_array => |i| {
531 try w.writeAll("(*");
532 try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" });
533 try w.writeByte(')');
531 try bw.writeAll("(*");
532 try f.writeCValueMember(bw, .{ .arg = i }, .{ .identifier = "array" });
533 try bw.writeByte(')');
534534 },
535 else => try f.object.dg.writeCValueDeref(w, c_value),
535 else => try f.object.dg.writeCValueDeref(bw, c_value),
536536 }
537537 }
538538
539539 fn writeCValueMember(
540540 f: *Function,
541 writer: anytype,
541 bw: *std.io.BufferedWriter,
542542 c_value: CValue,
543543 member: CValue,
544 ) error{ OutOfMemory, AnalysisFail }!void {
544 ) Error!void {
545545 switch (c_value) {
546546 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {
547 try f.writeCValue(writer, c_value, .Other);
548 try writer.writeByte('.');
549 try f.writeCValue(writer, member, .Other);
547 try f.writeCValue(bw, c_value, .Other);
548 try bw.writeByte('.');
549 try f.writeCValue(bw, member, .Other);
550550 },
551 else => return f.object.dg.writeCValueMember(writer, c_value, member),
551 else => return f.object.dg.writeCValueMember(bw, c_value, member),
552552 }
553553 }
554554
555 fn writeCValueDerefMember(f: *Function, writer: anytype, c_value: CValue, member: CValue) !void {
555 fn writeCValueDerefMember(f: *Function, bw: *std.io.BufferedWriter, c_value: CValue, member: CValue) !void {
556556 switch (c_value) {
557557 .new_local, .local, .arg, .arg_array => {
558 try f.writeCValue(writer, c_value, .Other);
559 try writer.writeAll("->");
558 try f.writeCValue(bw, c_value, .Other);
559 try bw.writeAll("->");
560560 },
561561 .constant => {
562 try writer.writeByte('(');
563 try f.writeCValue(writer, c_value, .Other);
564 try writer.writeAll(")->");
562 try bw.writeByte('(');
563 try f.writeCValue(bw, c_value, .Other);
564 try bw.writeAll(")->");
565565 },
566566 .local_ref => {
567 try f.writeCValueDeref(writer, c_value);
568 try writer.writeByte('.');
567 try f.writeCValueDeref(bw, c_value);
568 try bw.writeByte('.');
569569 },
570 else => return f.object.dg.writeCValueDerefMember(writer, c_value, member),
570 else => return f.object.dg.writeCValueDerefMember(bw, c_value, member),
571571 }
572 try f.writeCValue(writer, member, .Other);
572 try f.writeCValue(bw, member, .Other);
573573 }
574574
575 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
575 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {
576576 return f.object.dg.fail(format, args);
577577 }
578578
......@@ -584,16 +584,16 @@ pub const Function = struct {
584584 return f.object.dg.byteSize(ctype);
585585 }
586586
587 fn renderType(f: *Function, w: anytype, ctype: Type) !void {
588 return f.object.dg.renderType(w, ctype);
587 fn renderType(f: *Function, bw: *std.io.BufferedWriter, ctype: Type) !void {
588 return f.object.dg.renderType(bw, ctype);
589589 }
590590
591 fn renderCType(f: *Function, w: anytype, ctype: CType) !void {
592 return f.object.dg.renderCType(w, ctype);
591 fn renderCType(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !void {
592 return f.object.dg.renderCType(bw, ctype);
593593 }
594594
595 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
596 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
595 fn renderIntCast(f: *Function, bw: *std.io.BufferedWriter, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
596 return f.object.dg.renderIntCast(bw, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
597597 }
598598
599599 fn fmtIntLiteral(f: *Function, val: Value) !std.fmt.Formatter(formatIntLiteral) {
......@@ -614,14 +614,14 @@ pub const Function = struct {
614614 gop.value_ptr.* = .{
615615 .fn_name = switch (key) {
616616 .tag_name,
617 => |enum_ty| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
617 => |enum_ty| try ctype_pool.fmt(gpa, "zig_{s}_{f}__{d}", .{
618618 @tagName(key),
619619 fmtIdent(ip.loadEnumType(enum_ty).name.toSlice(ip)),
620620 @intFromEnum(enum_ty),
621621 }),
622622 .never_tail,
623623 .never_inline,
624 => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{
624 => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{f}__{d}", .{
625625 @tagName(key),
626626 fmtIdent(ip.getNav(owner_nav).name.toSlice(ip)),
627627 @intFromEnum(owner_nav),
......@@ -659,12 +659,12 @@ pub const Function = struct {
659659 },
660660 else => {},
661661 }
662 const writer = f.object.writer();
663 const a = try Assignment.start(f, writer, ctype);
664 try f.writeCValue(writer, dst, .Other);
665 try a.assign(f, writer);
666 try f.writeCValue(writer, src, .Other);
667 try a.end(f, writer);
662 const bw = &f.object.code.buffered_writer;
663 const a = try Assignment.start(f, bw, ctype);
664 try f.writeCValue(bw, dst, .Other);
665 try a.assign(f, bw);
666 try f.writeCValue(bw, src, .Other);
667 try a.end(f, bw);
668668 }
669669
670670 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
......@@ -699,7 +699,7 @@ pub const Object = struct {
699699
700700 const indent_width = 1;
701701
702 fn nl(o: *Object) anyerror!void {
702 fn newline(o: *Object) !void {
703703 const bw = &o.code.buffered_writer;
704704 try bw.writeByte('\n');
705705 try bw.splatByteAll(' ', o.indent_counter);
......@@ -737,7 +737,7 @@ pub const DeclGen = struct {
737737 flush,
738738 };
739739
740 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
740 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
741741 @branchHint(.cold);
742742 const zcu = dg.pt.zcu;
743743 const src_loc = zcu.navSrcLoc(dg.pass.nav);
......@@ -747,10 +747,10 @@ pub const DeclGen = struct {
747747
748748 fn renderUav(
749749 dg: *DeclGen,
750 writer: anytype,
750 bw: *std.io.BufferedWriter,
751751 uav: InternPool.Key.Ptr.BaseAddr.Uav,
752752 location: ValueRenderLocation,
753 ) error{ OutOfMemory, AnalysisFail }!void {
753 ) Error!void {
754754 const pt = dg.pt;
755755 const zcu = pt.zcu;
756756 const ip = &zcu.intern_pool;
......@@ -761,14 +761,14 @@ pub const DeclGen = struct {
761761 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
762762 const ptr_ty: Type = .fromInterned(uav.orig_ty);
763763 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {
764 return dg.writeCValue(writer, .{ .undef = ptr_ty });
764 return dg.writeCValue(bw, .{ .undef = ptr_ty });
765765 }
766766
767767 // Chase function values in order to be able to reference the original function.
768768 switch (ip.indexToKey(uav.val)) {
769769 .variable => unreachable,
770 .func => |func| return dg.renderNav(writer, func.owner_nav, location),
771 .@"extern" => |@"extern"| return dg.renderNav(writer, @"extern".owner_nav, location),
770 .func => |func| return dg.renderNav(bw, func.owner_nav, location),
771 .@"extern" => |@"extern"| return dg.renderNav(bw, @"extern".owner_nav, location),
772772 else => {},
773773 }
774774
......@@ -782,13 +782,13 @@ pub const DeclGen = struct {
782782 const need_cast = !elem_ctype.eql(uav_ctype) and
783783 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
784784 if (need_cast) {
785 try writer.writeAll("((");
786 try dg.renderCType(writer, ptr_ctype);
787 try writer.writeByte(')');
785 try bw.writeAll("((");
786 try dg.renderCType(bw, ptr_ctype);
787 try bw.writeByte(')');
788788 }
789 try writer.writeByte('&');
790 try renderUavName(writer, uav_val);
791 if (need_cast) try writer.writeByte(')');
789 try bw.writeByte('&');
790 try renderUavName(bw, uav_val);
791 if (need_cast) try bw.writeByte(')');
792792
793793 // Indicate that the anon decl should be rendered to the output so that
794794 // our reference above is not undefined.
......@@ -809,10 +809,10 @@ pub const DeclGen = struct {
809809
810810 fn renderNav(
811811 dg: *DeclGen,
812 writer: anytype,
812 bw: *std.io.BufferedWriter,
813813 nav_index: InternPool.Nav.Index,
814814 location: ValueRenderLocation,
815 ) error{ OutOfMemory, AnalysisFail }!void {
815 ) Error!void {
816816 _ = location;
817817 const pt = dg.pt;
818818 const zcu = pt.zcu;
......@@ -834,7 +834,7 @@ pub const DeclGen = struct {
834834 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));
835835 const ptr_ty = try pt.navPtrType(owner_nav);
836836 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {
837 return dg.writeCValue(writer, .{ .undef = ptr_ty });
837 return dg.writeCValue(bw, .{ .undef = ptr_ty });
838838 }
839839
840840 // We shouldn't cast C function pointers as this is UB (when you call
......@@ -847,21 +847,21 @@ pub const DeclGen = struct {
847847 const need_cast = !elem_ctype.eql(nav_ctype) and
848848 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
849849 if (need_cast) {
850 try writer.writeAll("((");
851 try dg.renderCType(writer, ctype);
852 try writer.writeByte(')');
850 try bw.writeAll("((");
851 try dg.renderCType(bw, ctype);
852 try bw.writeByte(')');
853853 }
854 try writer.writeByte('&');
855 try dg.renderNavName(writer, owner_nav);
856 if (need_cast) try writer.writeByte(')');
854 try bw.writeByte('&');
855 try dg.renderNavName(bw, owner_nav);
856 if (need_cast) try bw.writeByte(')');
857857 }
858858
859859 fn renderPointer(
860860 dg: *DeclGen,
861 writer: anytype,
861 bw: *std.io.BufferedWriter,
862862 derivation: Value.PointerDeriveStep,
863863 location: ValueRenderLocation,
864 ) error{ OutOfMemory, AnalysisFail }!void {
864 ) Error!void {
865865 const pt = dg.pt;
866866 const zcu = pt.zcu;
867867 switch (derivation) {
......@@ -869,18 +869,18 @@ pub const DeclGen = struct {
869869 .int => |int| {
870870 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
871871 const addr_val = try pt.intValue(.usize, int.addr);
872 try writer.writeByte('(');
873 try dg.renderCType(writer, ptr_ctype);
874 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});
872 try bw.writeByte('(');
873 try dg.renderCType(bw, ptr_ctype);
874 try bw.print("){fx}", .{try dg.fmtIntLiteral(addr_val, .Other)});
875875 },
876876
877 .nav_ptr => |nav| try dg.renderNav(writer, nav, location),
878 .uav_ptr => |uav| try dg.renderUav(writer, uav, location),
877 .nav_ptr => |nav| try dg.renderNav(bw, nav, location),
878 .uav_ptr => |uav| try dg.renderUav(bw, uav, location),
879879
880880 inline .eu_payload_ptr, .opt_payload_ptr => |info| {
881 try writer.writeAll("&(");
882 try dg.renderPointer(writer, info.parent.*, location);
883 try writer.writeAll(")->payload");
881 try bw.writeAll("&(");
882 try dg.renderPointer(bw, info.parent.*, location);
883 try bw.writeAll(")->payload");
884884 },
885885
886886 .field_ptr => |field| {
......@@ -892,26 +892,26 @@ pub const DeclGen = struct {
892892 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {
893893 .begin => {
894894 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
895 try writer.writeByte('(');
896 try dg.renderCType(writer, ptr_ctype);
897 try writer.writeByte(')');
898 try dg.renderPointer(writer, field.parent.*, location);
895 try bw.writeByte('(');
896 try dg.renderCType(bw, ptr_ctype);
897 try bw.writeByte(')');
898 try dg.renderPointer(bw, field.parent.*, location);
899899 },
900900 .field => |name| {
901 try writer.writeAll("&(");
902 try dg.renderPointer(writer, field.parent.*, location);
903 try writer.writeAll(")->");
904 try dg.writeCValue(writer, name);
901 try bw.writeAll("&(");
902 try dg.renderPointer(bw, field.parent.*, location);
903 try bw.writeAll(")->");
904 try dg.writeCValue(bw, name);
905905 },
906906 .byte_offset => |byte_offset| {
907907 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
908 try writer.writeByte('(');
909 try dg.renderCType(writer, ptr_ctype);
910 try writer.writeByte(')');
908 try bw.writeByte('(');
909 try dg.renderCType(bw, ptr_ctype);
910 try bw.writeByte(')');
911911 const offset_val = try pt.intValue(.usize, byte_offset);
912 try writer.writeAll("((char *)");
913 try dg.renderPointer(writer, field.parent.*, location);
914 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});
912 try bw.writeAll("((char *)");
913 try dg.renderPointer(bw, field.parent.*, location);
914 try bw.print(" + {f})", .{try dg.fmtIntLiteral(offset_val, .Other)});
915915 },
916916 }
917917 },
......@@ -919,10 +919,10 @@ pub const DeclGen = struct {
919919 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {
920920 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.
921921 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
922 try writer.writeByte('(');
923 try dg.renderCType(writer, ptr_ctype);
924 try writer.writeByte(')');
925 try dg.renderPointer(writer, elem.parent.*, location);
922 try bw.writeByte('(');
923 try dg.renderCType(bw, ptr_ctype);
924 try bw.writeByte(')');
925 try dg.renderPointer(bw, elem.parent.*, location);
926926 } else {
927927 const index_val = try pt.intValue(.usize, elem.elem_idx);
928928 // We want to do pointer arithmetic on a pointer to the element type.
......@@ -931,48 +931,47 @@ pub const DeclGen = struct {
931931 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);
932932 if (result_ctype.eql(parent_ctype)) {
933933 // The pointer already has an appropriate type - just do the arithmetic.
934 try writer.writeByte('(');
935 try dg.renderPointer(writer, elem.parent.*, location);
936 try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)});
934 try bw.writeByte('(');
935 try dg.renderPointer(bw, elem.parent.*, location);
936 try bw.print(" + {f})", .{try dg.fmtIntLiteral(index_val, .Other)});
937937 } else {
938938 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,
939939 // and *then* apply the index.
940 try writer.writeAll("((");
941 try dg.renderCType(writer, result_ctype);
942 try writer.writeByte(')');
943 try dg.renderPointer(writer, elem.parent.*, location);
944 try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)});
940 try bw.writeAll("((");
941 try dg.renderCType(bw, result_ctype);
942 try bw.writeByte(')');
943 try dg.renderPointer(bw, elem.parent.*, location);
944 try bw.print(" + {f})", .{try dg.fmtIntLiteral(index_val, .Other)});
945945 }
946946 },
947947
948948 .offset_and_cast => |oac| {
949949 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);
950 try writer.writeByte('(');
951 try dg.renderCType(writer, ptr_ctype);
952 try writer.writeByte(')');
950 try bw.writeByte('(');
951 try dg.renderCType(bw, ptr_ctype);
952 try bw.writeByte(')');
953953 if (oac.byte_offset == 0) {
954 try dg.renderPointer(writer, oac.parent.*, location);
954 try dg.renderPointer(bw, oac.parent.*, location);
955955 } else {
956956 const offset_val = try pt.intValue(.usize, oac.byte_offset);
957 try writer.writeAll("((char *)");
958 try dg.renderPointer(writer, oac.parent.*, location);
959 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});
957 try bw.writeAll("((char *)");
958 try dg.renderPointer(bw, oac.parent.*, location);
959 try bw.print(" + {f})", .{try dg.fmtIntLiteral(offset_val, .Other)});
960960 }
961961 },
962962 }
963963 }
964964
965 fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {
966 const ip = &dg.pt.zcu.intern_pool;
967 try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))});
965 fn renderErrorName(dg: *DeclGen, bw: *std.io.BufferedWriter, err_name: InternPool.NullTerminatedString) !void {
966 try bw.print("zig_error_{f}", .{fmtIdent(err_name.toSlice(&dg.pt.zcu.intern_pool))});
968967 }
969968
970969 fn renderValue(
971970 dg: *DeclGen,
972 writer: anytype,
971 writer: *std.io.BufferedWriter,
973972 val: Value,
974973 location: ValueRenderLocation,
975 ) error{ OutOfMemory, AnalysisFail }!void {
974 ) Error!void {
976975 const pt = dg.pt;
977976 const zcu = pt.zcu;
978977 const ip = &zcu.intern_pool;
......@@ -1028,11 +1027,11 @@ pub const DeclGen = struct {
10281027 .empty_enum_value,
10291028 => unreachable, // non-runtime values
10301029 .int => |int| switch (int.storage) {
1031 .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(val, location)}),
1030 .u64, .i64, .big_int => try writer.print("{f}", .{try dg.fmtIntLiteral(val, location)}),
10321031 .lazy_align, .lazy_size => {
10331032 try writer.writeAll("((");
10341033 try dg.renderCType(writer, ctype);
1035 try writer.print("){x})", .{try dg.fmtIntLiteral(
1034 try writer.print("){fx})", .{try dg.fmtIntLiteral(
10361035 try pt.intValue(.usize, val.toUnsignedInt(zcu)),
10371036 .Other,
10381037 )});
......@@ -1161,7 +1160,7 @@ pub const DeclGen = struct {
11611160 try writer.writeAll(", ");
11621161 empty = false;
11631162 }
1164 try writer.print("{x}", .{try dg.fmtIntLiteral(
1163 try writer.print("{fx}", .{try dg.fmtIntLiteral(
11651164 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
11661165 location,
11671166 )});
......@@ -1550,7 +1549,7 @@ pub const DeclGen = struct {
15501549 .payload => {
15511550 try writer.writeByte('{');
15521551 if (field_ty.hasRuntimeBits(zcu)) {
1553 try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});
1552 try writer.print(" .{f } = ", .{fmtIdent(field_name.toSlice(ip))});
15541553 try dg.renderValue(
15551554 writer,
15561555 Value.fromInterned(un.val),
......@@ -1578,10 +1577,10 @@ pub const DeclGen = struct {
15781577
15791578 fn renderUndefValue(
15801579 dg: *DeclGen,
1581 writer: anytype,
1580 bw: *std.io.BufferedWriter,
15821581 ty: Type,
15831582 location: ValueRenderLocation,
1584 ) error{ OutOfMemory, AnalysisFail }!void {
1583 ) Error!void {
15851584 const pt = dg.pt;
15861585 const zcu = pt.zcu;
15871586 const ip = &zcu.intern_pool;
......@@ -1611,57 +1610,57 @@ pub const DeclGen = struct {
16111610 // All unsigned ints matching float types are pre-allocated.
16121611 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
16131612
1614 try writer.writeAll("zig_make_");
1615 try dg.renderTypeForBuiltinFnName(writer, ty);
1616 try writer.writeByte('(');
1613 try bw.writeAll("zig_make_");
1614 try dg.renderTypeForBuiltinFnName(bw, ty);
1615 try bw.writeByte('(');
16171616 switch (bits) {
1618 16 => try writer.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1619 32 => try writer.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1620 64 => try writer.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1621 80 => try writer.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1622 128 => try writer.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
1617 16 => try bw.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1618 32 => try bw.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1619 64 => try bw.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1620 80 => try bw.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1621 128 => try bw.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
16231622 else => unreachable,
16241623 }
1625 try writer.writeAll(", ");
1626 try dg.renderUndefValue(writer, repr_ty, .FunctionArgument);
1627 return writer.writeByte(')');
1624 try bw.writeAll(", ");
1625 try dg.renderUndefValue(bw, repr_ty, .FunctionArgument);
1626 return bw.writeByte(')');
16281627 },
1629 .bool_type => try writer.writeAll(if (safety_on) "0xaa" else "false"),
1628 .bool_type => try bw.writeAll(if (safety_on) "0xaa" else "false"),
16301629 else => switch (ip.indexToKey(ty.toIntern())) {
16311630 .simple_type,
16321631 .int_type,
16331632 .enum_type,
16341633 .error_set_type,
16351634 .inferred_error_set_type,
1636 => return writer.print("{x}", .{
1635 => return bw.print("{fx}", .{
16371636 try dg.fmtIntLiteral(try pt.undefValue(ty), location),
16381637 }),
16391638 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
16401639 .one, .many, .c => {
1641 try writer.writeAll("((");
1642 try dg.renderCType(writer, ctype);
1643 return writer.print("){x})", .{
1640 try bw.writeAll("((");
1641 try dg.renderCType(bw, ctype);
1642 return bw.print("){fx})", .{
16441643 try dg.fmtIntLiteral(.undef_usize, .Other),
16451644 });
16461645 },
16471646 .slice => {
16481647 if (!location.isInitializer()) {
1649 try writer.writeByte('(');
1650 try dg.renderCType(writer, ctype);
1651 try writer.writeByte(')');
1648 try bw.writeByte('(');
1649 try dg.renderCType(bw, ctype);
1650 try bw.writeByte(')');
16521651 }
16531652
1654 try writer.writeAll("{(");
1653 try bw.writeAll("{(");
16551654 const ptr_ty = ty.slicePtrFieldType(zcu);
1656 try dg.renderType(writer, ptr_ty);
1657 return writer.print("){x}, {0x}}}", .{
1655 try dg.renderType(bw, ptr_ty);
1656 return bw.print("){fx}, {0fx}}}", .{
16581657 try dg.fmtIntLiteral(.undef_usize, .Other),
16591658 });
16601659 },
16611660 },
16621661 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {
16631662 .basic, .pointer => try dg.renderUndefValue(
1664 writer,
1663 bw,
16651664 .fromInterned(if (ctype.isBool()) .bool_type else child_type),
16661665 location,
16671666 ),
......@@ -1670,21 +1669,21 @@ pub const DeclGen = struct {
16701669 switch (aggregate.fields.at(0, ctype_pool).name.index) {
16711670 .is_null, .payload => {},
16721671 .ptr, .len => return dg.renderUndefValue(
1673 writer,
1672 bw,
16741673 .fromInterned(child_type),
16751674 location,
16761675 ),
16771676 else => unreachable,
16781677 }
16791678 if (!location.isInitializer()) {
1680 try writer.writeByte('(');
1681 try dg.renderCType(writer, ctype);
1682 try writer.writeByte(')');
1679 try bw.writeByte('(');
1680 try dg.renderCType(bw, ctype);
1681 try bw.writeByte(')');
16831682 }
1684 try writer.writeByte('{');
1683 try bw.writeByte('{');
16851684 for (0..aggregate.fields.len) |field_index| {
1686 if (field_index > 0) try writer.writeByte(',');
1687 try dg.renderUndefValue(writer, .fromInterned(
1685 if (field_index > 0) try bw.writeByte(',');
1686 try dg.renderUndefValue(bw, .fromInterned(
16881687 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
16891688 .is_null => .bool_type,
16901689 .payload => child_type,
......@@ -1692,7 +1691,7 @@ pub const DeclGen = struct {
16921691 },
16931692 ), initializer_type);
16941693 }
1695 try writer.writeByte('}');
1694 try bw.writeByte('}');
16961695 },
16971696 },
16981697 .struct_type => {
......@@ -1700,117 +1699,117 @@ pub const DeclGen = struct {
17001699 switch (loaded_struct.layout) {
17011700 .auto, .@"extern" => {
17021701 if (!location.isInitializer()) {
1703 try writer.writeByte('(');
1704 try dg.renderCType(writer, ctype);
1705 try writer.writeByte(')');
1702 try bw.writeByte('(');
1703 try dg.renderCType(bw, ctype);
1704 try bw.writeByte(')');
17061705 }
17071706
1708 try writer.writeByte('{');
1707 try bw.writeByte('{');
17091708 var field_it = loaded_struct.iterateRuntimeOrder(ip);
17101709 var need_comma = false;
17111710 while (field_it.next()) |field_index| {
17121711 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
17131712 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17141713
1715 if (need_comma) try writer.writeByte(',');
1714 if (need_comma) try bw.writeByte(',');
17161715 need_comma = true;
1717 try dg.renderUndefValue(writer, field_ty, initializer_type);
1716 try dg.renderUndefValue(bw, field_ty, initializer_type);
17181717 }
1719 return writer.writeByte('}');
1718 return bw.writeByte('}');
17201719 },
1721 .@"packed" => return writer.print("{x}", .{
1720 .@"packed" => return bw.print("{fx}", .{
17221721 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
17231722 }),
17241723 }
17251724 },
17261725 .tuple_type => |tuple_info| {
17271726 if (!location.isInitializer()) {
1728 try writer.writeByte('(');
1729 try dg.renderCType(writer, ctype);
1730 try writer.writeByte(')');
1727 try bw.writeByte('(');
1728 try dg.renderCType(bw, ctype);
1729 try bw.writeByte(')');
17311730 }
17321731
1733 try writer.writeByte('{');
1732 try bw.writeByte('{');
17341733 var need_comma = false;
17351734 for (0..tuple_info.types.len) |field_index| {
17361735 if (tuple_info.values.get(ip)[field_index] != .none) continue;
17371736 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
17381737 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17391738
1740 if (need_comma) try writer.writeByte(',');
1739 if (need_comma) try bw.writeByte(',');
17411740 need_comma = true;
1742 try dg.renderUndefValue(writer, field_ty, initializer_type);
1741 try dg.renderUndefValue(bw, field_ty, initializer_type);
17431742 }
1744 return writer.writeByte('}');
1743 return bw.writeByte('}');
17451744 },
17461745 .union_type => {
17471746 const loaded_union = ip.loadUnionType(ty.toIntern());
17481747 switch (loaded_union.flagsUnordered(ip).layout) {
17491748 .auto, .@"extern" => {
17501749 if (!location.isInitializer()) {
1751 try writer.writeByte('(');
1752 try dg.renderCType(writer, ctype);
1753 try writer.writeByte(')');
1750 try bw.writeByte('(');
1751 try dg.renderCType(bw, ctype);
1752 try bw.writeByte(')');
17541753 }
17551754
17561755 const has_tag = loaded_union.hasTag(ip);
1757 if (has_tag) try writer.writeByte('{');
1756 if (has_tag) try bw.writeByte('{');
17581757 const aggregate = ctype.info(ctype_pool).aggregate;
17591758 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
1760 if (outer_field_index > 0) try writer.writeByte(',');
1759 if (outer_field_index > 0) try bw.writeByte(',');
17611760 switch (if (has_tag)
17621761 aggregate.fields.at(outer_field_index, ctype_pool).name.index
17631762 else
17641763 .payload) {
17651764 .tag => try dg.renderUndefValue(
1766 writer,
1765 bw,
17671766 .fromInterned(loaded_union.enum_tag_ty),
17681767 initializer_type,
17691768 ),
17701769 .payload => {
1771 try writer.writeByte('{');
1770 try bw.writeByte('{');
17721771 for (0..loaded_union.field_types.len) |inner_field_index| {
17731772 const inner_field_ty: Type = .fromInterned(
17741773 loaded_union.field_types.get(ip)[inner_field_index],
17751774 );
17761775 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;
17771776 try dg.renderUndefValue(
1778 writer,
1777 bw,
17791778 inner_field_ty,
17801779 initializer_type,
17811780 );
17821781 break;
17831782 }
1784 try writer.writeByte('}');
1783 try bw.writeByte('}');
17851784 },
17861785 else => unreachable,
17871786 }
17881787 }
1789 if (has_tag) try writer.writeByte('}');
1788 if (has_tag) try bw.writeByte('}');
17901789 },
1791 .@"packed" => return writer.print("{x}", .{
1790 .@"packed" => return bw.print("{fx}", .{
17921791 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
17931792 }),
17941793 }
17951794 },
17961795 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {
17971796 .basic => try dg.renderUndefValue(
1798 writer,
1797 bw,
17991798 .fromInterned(error_union_type.error_set_type),
18001799 location,
18011800 ),
18021801 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
18031802 .aggregate => |aggregate| {
18041803 if (!location.isInitializer()) {
1805 try writer.writeByte('(');
1806 try dg.renderCType(writer, ctype);
1807 try writer.writeByte(')');
1804 try bw.writeByte('(');
1805 try dg.renderCType(bw, ctype);
1806 try bw.writeByte(')');
18081807 }
1809 try writer.writeByte('{');
1808 try bw.writeByte('{');
18101809 for (0..aggregate.fields.len) |field_index| {
1811 if (field_index > 0) try writer.writeByte(',');
1810 if (field_index > 0) try bw.writeByte(',');
18121811 try dg.renderUndefValue(
1813 writer,
1812 bw,
18141813 .fromInterned(
18151814 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
18161815 .@"error" => error_union_type.error_set_type,
......@@ -1821,14 +1820,14 @@ pub const DeclGen = struct {
18211820 initializer_type,
18221821 );
18231822 }
1824 try writer.writeByte('}');
1823 try bw.writeByte('}');
18251824 },
18261825 },
18271826 .array_type, .vector_type => {
18281827 const ai = ty.arrayInfo(zcu);
18291828 if (ai.elem_type.eql(.u8, zcu)) {
18301829 const c_len = ty.arrayLenIncludingSentinel(zcu);
1831 var literal: StringLiteral = .init(writer, c_len);
1830 var literal: StringLiteral = .init(bw, c_len);
18321831 try literal.start();
18331832 var index: u64 = 0;
18341833 while (index < c_len) : (index += 1)
......@@ -1836,19 +1835,19 @@ pub const DeclGen = struct {
18361835 return literal.end();
18371836 } else {
18381837 if (!location.isInitializer()) {
1839 try writer.writeByte('(');
1840 try dg.renderCType(writer, ctype);
1841 try writer.writeByte(')');
1838 try bw.writeByte('(');
1839 try dg.renderCType(bw, ctype);
1840 try bw.writeByte(')');
18421841 }
18431842
1844 try writer.writeByte('{');
1843 try bw.writeByte('{');
18451844 const c_len = ty.arrayLenIncludingSentinel(zcu);
18461845 var index: u64 = 0;
18471846 while (index < c_len) : (index += 1) {
1848 if (index > 0) try writer.writeAll(", ");
1849 try dg.renderUndefValue(writer, ty.childType(zcu), initializer_type);
1847 if (index > 0) try bw.writeAll(", ");
1848 try dg.renderUndefValue(bw, ty.childType(zcu), initializer_type);
18501849 }
1851 return writer.writeByte('}');
1850 return bw.writeByte('}');
18521851 }
18531852 },
18541853 .anyframe_type,
......@@ -1881,7 +1880,7 @@ pub const DeclGen = struct {
18811880
18821881 fn renderFunctionSignature(
18831882 dg: *DeclGen,
1884 w: anytype,
1883 bw: *std.io.BufferedWriter,
18851884 fn_val: Value,
18861885 fn_align: InternPool.Alignment,
18871886 kind: CType.Kind,
......@@ -1903,8 +1902,8 @@ pub const DeclGen = struct {
19031902 const fn_info = zcu.typeToFunc(fn_ty).?;
19041903 if (fn_info.cc == .naked) {
19051904 switch (kind) {
1906 .forward => try w.writeAll("zig_naked_decl "),
1907 .complete => try w.writeAll("zig_naked "),
1905 .forward => try bw.writeAll("zig_naked_decl "),
1906 .complete => try bw.writeAll("zig_naked "),
19081907 else => unreachable,
19091908 }
19101909 }
......@@ -1913,33 +1912,33 @@ pub const DeclGen = struct {
19131912 const func_analysis = func.analysisUnordered(ip);
19141913
19151914 if (func_analysis.branch_hint == .cold)
1916 try w.writeAll("zig_cold ");
1915 try bw.writeAll("zig_cold ");
19171916
19181917 if (kind == .complete and func_analysis.disable_intrinsics or dg.mod.no_builtin)
1919 try w.writeAll("zig_no_builtin ");
1918 try bw.writeAll("zig_no_builtin ");
19201919 }
19211920
1922 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
1921 if (fn_info.return_type == .noreturn_type) try bw.writeAll("zig_noreturn ");
19231922
1924 var trailing = try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, fn_ctype, .suffix, .{});
1923 var trailing = try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, bw, fn_ctype, .suffix, .{});
19251924
19261925 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {
1927 try w.print("{}zig_callconv({s})", .{ trailing, call_conv });
1926 try bw.print("{f}zig_callconv({s})", .{ trailing, call_conv });
19281927 trailing = .maybe_space;
19291928 }
19301929
1931 try w.print("{}", .{trailing});
1930 try bw.print("{f}", .{trailing});
19321931 switch (name) {
1933 .nav => |nav| try dg.renderNavName(w, nav),
1934 .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}),
1935 .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),
1932 .nav => |nav| try dg.renderNavName(bw, nav),
1933 .fmt_ctype_pool_string => |fmt| try bw.print("{f }", .{fmt}),
1934 .@"export" => |@"export"| try bw.print("{f }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),
19361935 }
19371936
19381937 try renderTypeSuffix(
19391938 dg.pass,
19401939 &dg.ctype_pool,
19411940 zcu,
1942 w,
1941 bw,
19431942 fn_ctype,
19441943 .suffix,
19451944 CQualifiers.init(.{ .@"const" = switch (kind) {
......@@ -1951,7 +1950,7 @@ pub const DeclGen = struct {
19511950
19521951 switch (kind) {
19531952 .forward => {
1954 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});
1953 if (fn_align.toByteUnits()) |a| try bw.print(" zig_align_fn({})", .{a});
19551954 switch (name) {
19561955 .nav, .fmt_ctype_pool_string => {},
19571956 .@"export" => |@"export"| {
......@@ -1959,17 +1958,17 @@ pub const DeclGen = struct {
19591958 const is_mangled = isMangledIdent(extern_name, true);
19601959 const is_export = @"export".extern_name != @"export".main_name;
19611960 if (is_mangled and is_export) {
1962 try w.print(" zig_mangled_export({ }, {s}, {s})", .{
1961 try bw.print(" zig_mangled_export({f }, {fs}, {fs})", .{
19631962 fmtIdent(extern_name),
19641963 fmtStringLiteral(extern_name, null),
19651964 fmtStringLiteral(@"export".main_name.toSlice(ip), null),
19661965 });
19671966 } else if (is_mangled) {
1968 try w.print(" zig_mangled({ }, {s})", .{
1967 try bw.print(" zig_mangled({f }, {fs})", .{
19691968 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),
19701969 });
19711970 } else if (is_export) {
1972 try w.print(" zig_export({s}, {s})", .{
1971 try bw.print(" zig_export({fs}, {fs})", .{
19731972 fmtStringLiteral(@"export".main_name.toSlice(ip), null),
19741973 fmtStringLiteral(extern_name, null),
19751974 });
......@@ -2002,13 +2001,13 @@ pub const DeclGen = struct {
20022001 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
20032002 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
20042003 ///
2005 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{OutOfMemory}!void {
2006 try dg.renderCType(w, try dg.ctypeFromType(t, .complete));
2004 fn renderType(dg: *DeclGen, bw: *std.io.BufferedWriter, t: Type) Error!void {
2005 try dg.renderCType(bw, try dg.ctypeFromType(t, .complete));
20072006 }
20082007
2009 fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {
2010 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
2011 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
2008 fn renderCType(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) Error!void {
2009 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
2010 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
20122011 }
20132012
20142013 const IntCastContext = union(enum) {
......@@ -2021,13 +2020,13 @@ pub const DeclGen = struct {
20212020 value: Value,
20222021 },
20232022
2024 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: anytype, location: ValueRenderLocation) !void {
2023 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, bw: *std.io.BufferedWriter, location: ValueRenderLocation) !void {
20252024 switch (self.*) {
20262025 .c_value => |v| {
2027 try v.f.writeCValue(w, v.value, location);
2028 try v.v.elem(v.f, w);
2026 try v.f.writeCValue(bw, v.value, location);
2027 try v.v.elem(v.f, bw);
20292028 },
2030 .value => |v| try dg.renderValue(w, v.value, location),
2029 .value => |v| try dg.renderValue(bw, v.value, location),
20312030 }
20322031 }
20332032 };
......@@ -2067,7 +2066,7 @@ pub const DeclGen = struct {
20672066 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
20682067 fn renderIntCast(
20692068 dg: *DeclGen,
2070 w: anytype,
2069 bw: *std.io.BufferedWriter,
20712070 dest_ty: Type,
20722071 context: IntCastContext,
20732072 src_ty: Type,
......@@ -2092,52 +2091,52 @@ pub const DeclGen = struct {
20922091 dest_int_info.signedness != src_int_info.?.signedness);
20932092
20942093 if (needs_cast) {
2095 try w.writeByte('(');
2096 try dg.renderType(w, dest_ty);
2097 try w.writeByte(')');
2094 try bw.writeByte('(');
2095 try dg.renderType(bw, dest_ty);
2096 try bw.writeByte(')');
20982097 }
20992098 if (src_is_ptr) {
2100 try w.writeByte('(');
2101 try dg.renderType(w, src_eff_ty);
2102 try w.writeByte(')');
2099 try bw.writeByte('(');
2100 try dg.renderType(bw, src_eff_ty);
2101 try bw.writeByte(')');
21032102 }
2104 try context.writeValue(dg, w, location);
2103 try context.writeValue(dg, bw, location);
21052104 } else if (dest_bits <= 64 and src_bits > 64) {
21062105 assert(!src_is_ptr);
21072106 if (dest_bits < 64) {
2108 try w.writeByte('(');
2109 try dg.renderType(w, dest_ty);
2110 try w.writeByte(')');
2107 try bw.writeByte('(');
2108 try dg.renderType(bw, dest_ty);
2109 try bw.writeByte(')');
21112110 }
2112 try w.writeAll("zig_lo_");
2113 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2114 try w.writeByte('(');
2115 try context.writeValue(dg, w, .FunctionArgument);
2116 try w.writeByte(')');
2111 try bw.writeAll("zig_lo_");
2112 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2113 try bw.writeByte('(');
2114 try context.writeValue(dg, bw, .FunctionArgument);
2115 try bw.writeByte(')');
21172116 } else if (dest_bits > 64 and src_bits <= 64) {
2118 try w.writeAll("zig_make_");
2119 try dg.renderTypeForBuiltinFnName(w, dest_ty);
2120 try w.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral?
2117 try bw.writeAll("zig_make_");
2118 try dg.renderTypeForBuiltinFnName(bw, dest_ty);
2119 try bw.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral?
21212120 if (src_is_ptr) {
2122 try w.writeByte('(');
2123 try dg.renderType(w, src_eff_ty);
2124 try w.writeByte(')');
2121 try bw.writeByte('(');
2122 try dg.renderType(bw, src_eff_ty);
2123 try bw.writeByte(')');
21252124 }
2126 try context.writeValue(dg, w, .FunctionArgument);
2127 try w.writeByte(')');
2125 try context.writeValue(dg, bw, .FunctionArgument);
2126 try bw.writeByte(')');
21282127 } else {
21292128 assert(!src_is_ptr);
2130 try w.writeAll("zig_make_");
2131 try dg.renderTypeForBuiltinFnName(w, dest_ty);
2132 try w.writeAll("(zig_hi_");
2133 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2134 try w.writeByte('(');
2135 try context.writeValue(dg, w, .FunctionArgument);
2136 try w.writeAll("), zig_lo_");
2137 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
2138 try w.writeByte('(');
2139 try context.writeValue(dg, w, .FunctionArgument);
2140 try w.writeAll("))");
2129 try bw.writeAll("zig_make_");
2130 try dg.renderTypeForBuiltinFnName(bw, dest_ty);
2131 try bw.writeAll("(zig_hi_");
2132 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2133 try bw.writeByte('(');
2134 try context.writeValue(dg, bw, .FunctionArgument);
2135 try bw.writeAll("), zig_lo_");
2136 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2137 try bw.writeByte('(');
2138 try context.writeValue(dg, bw, .FunctionArgument);
2139 try bw.writeAll("))");
21412140 }
21422141 }
21432142
......@@ -2151,15 +2150,15 @@ pub const DeclGen = struct {
21512150 ///
21522151 fn renderTypeAndName(
21532152 dg: *DeclGen,
2154 w: anytype,
2153 bw: *std.io.BufferedWriter,
21552154 ty: Type,
21562155 name: CValue,
21572156 qualifiers: CQualifiers,
21582157 alignment: Alignment,
21592158 kind: CType.Kind,
2160 ) error{ OutOfMemory, AnalysisFail }!void {
2159 ) !void {
21612160 try dg.renderCTypeAndName(
2162 w,
2161 bw,
21632162 try dg.ctypeFromType(ty, kind),
21642163 name,
21652164 qualifiers,
......@@ -2172,60 +2171,60 @@ pub const DeclGen = struct {
21722171
21732172 fn renderCTypeAndName(
21742173 dg: *DeclGen,
2175 w: anytype,
2174 bw: *std.io.BufferedWriter,
21762175 ctype: CType,
21772176 name: CValue,
21782177 qualifiers: CQualifiers,
21792178 alignas: CType.AlignAs,
2180 ) error{ OutOfMemory, AnalysisFail }!void {
2179 ) !void {
21812180 const zcu = dg.pt.zcu;
21822181 switch (alignas.abiOrder()) {
2183 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
2182 .lt => try bw.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
21842183 .eq => {},
2185 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
2184 .gt => try bw.print("zig_align({}) ", .{alignas.toByteUnits()}),
21862185 }
21872186
2188 try w.print("{}", .{
2189 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers),
2187 try bw.print("{f}", .{
2188 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, qualifiers),
21902189 });
2191 try dg.writeName(w, name);
2192 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});
2190 try dg.writeName(bw, name);
2191 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, .{});
21932192 }
21942193
2195 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {
2194 fn writeName(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
21962195 switch (c_value) {
2197 .new_local, .local => |i| try w.print("t{d}", .{i}),
2198 .constant => |uav| try renderUavName(w, uav),
2199 .nav => |nav| try dg.renderNavName(w, nav),
2200 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
2196 .new_local, .local => |i| try bw.print("t{d}", .{i}),
2197 .constant => |uav| try renderUavName(bw, uav),
2198 .nav => |nav| try dg.renderNavName(bw, nav),
2199 .identifier => |ident| try bw.print("{f }", .{fmtIdent(ident)}),
22012200 else => unreachable,
22022201 }
22032202 }
22042203
2205 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {
2204 fn writeCValue(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) Error!void {
22062205 switch (c_value) {
22072206 .none, .new_local, .local, .local_ref => unreachable,
2208 .constant => |uav| try renderUavName(w, uav),
2207 .constant => |uav| try renderUavName(bw, uav),
22092208 .arg, .arg_array => unreachable,
2210 .field => |i| try w.print("f{d}", .{i}),
2211 .nav => |nav| try dg.renderNavName(w, nav),
2209 .field => |i| try bw.print("f{d}", .{i}),
2210 .nav => |nav| try dg.renderNavName(bw, nav),
22122211 .nav_ref => |nav| {
2213 try w.writeByte('&');
2214 try dg.renderNavName(w, nav);
2212 try bw.writeByte('&');
2213 try dg.renderNavName(bw, nav);
22152214 },
2216 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),
2217 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),
2218 .payload_identifier => |ident| try w.print("{ }.{ }", .{
2215 .undef => |ty| try dg.renderUndefValue(bw, ty, .Other),
2216 .identifier => |ident| try bw.print("{f }", .{fmtIdent(ident)}),
2217 .payload_identifier => |ident| try bw.print("{f }.{f }", .{
22192218 fmtIdent("payload"),
22202219 fmtIdent(ident),
22212220 }),
2222 .ctype_pool_string => |string| try w.print("{ }", .{
2221 .ctype_pool_string => |string| try bw.print("{f }", .{
22232222 fmtCTypePoolString(string, &dg.ctype_pool),
22242223 }),
22252224 }
22262225 }
22272226
2228 fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {
2227 fn writeCValueDeref(dg: *DeclGen, bw: *std.io.BufferedWriter, c_value: CValue) !void {
22292228 switch (c_value) {
22302229 .none,
22312230 .new_local,
......@@ -2236,16 +2235,16 @@ pub const DeclGen = struct {
22362235 .arg_array,
22372236 .ctype_pool_string,
22382237 => unreachable,
2239 .field => |i| try w.print("f{d}", .{i}),
2238 .field => |i| try bw.print("f{d}", .{i}),
22402239 .nav => |nav| {
2241 try w.writeAll("(*");
2242 try dg.renderNavName(w, nav);
2243 try w.writeByte(')');
2240 try bw.writeAll("(*");
2241 try dg.renderNavName(bw, nav);
2242 try bw.writeByte(')');
22442243 },
2245 .nav_ref => |nav| try dg.renderNavName(w, nav),
2244 .nav_ref => |nav| try dg.renderNavName(bw, nav),
22462245 .undef => unreachable,
2247 .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),
2248 .payload_identifier => |ident| try w.print("(*{ }.{ })", .{
2246 .identifier => |ident| try bw.print("(*{f })", .{fmtIdent(ident)}),
2247 .payload_identifier => |ident| try bw.print("(*{f }.{f })", .{
22492248 fmtIdent("payload"),
22502249 fmtIdent(ident),
22512250 }),
......@@ -2254,16 +2253,21 @@ pub const DeclGen = struct {
22542253
22552254 fn writeCValueMember(
22562255 dg: *DeclGen,
2257 writer: anytype,
2256 bw: *std.io.BufferedWriter,
22582257 c_value: CValue,
22592258 member: CValue,
2260 ) error{ OutOfMemory, AnalysisFail }!void {
2261 try dg.writeCValue(writer, c_value);
2262 try writer.writeByte('.');
2263 try dg.writeCValue(writer, member);
2259 ) Error!void {
2260 try dg.writeCValue(bw, c_value);
2261 try bw.writeByte('.');
2262 try dg.writeCValue(bw, member);
22642263 }
22652264
2266 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {
2265 fn writeCValueDerefMember(
2266 dg: *DeclGen,
2267 bw: *std.io.BufferedWriter,
2268 c_value: CValue,
2269 member: CValue,
2270 ) !void {
22672271 switch (c_value) {
22682272 .none,
22692273 .new_local,
......@@ -2277,15 +2281,15 @@ pub const DeclGen = struct {
22772281 .ctype_pool_string,
22782282 => unreachable,
22792283 .nav, .identifier, .payload_identifier => {
2280 try dg.writeCValue(writer, c_value);
2281 try writer.writeAll("->");
2284 try dg.writeCValue(bw, c_value);
2285 try bw.writeAll("->");
22822286 },
22832287 .nav_ref => {
2284 try dg.writeCValueDeref(writer, c_value);
2285 try writer.writeByte('.');
2288 try dg.writeCValueDeref(bw, c_value);
2289 try bw.writeByte('.');
22862290 },
22872291 }
2288 try dg.writeCValue(writer, member);
2292 try dg.writeCValue(bw, member);
22892293 }
22902294
22912295 fn renderFwdDecl(
......@@ -2301,7 +2305,7 @@ pub const DeclGen = struct {
23012305 const zcu = dg.pt.zcu;
23022306 const ip = &zcu.intern_pool;
23032307 const nav = ip.getNav(nav_index);
2304 const fwd = dg.fwdDeclWriter();
2308 const fwd = &dg.fwd_decl.buffered_writer;
23052309 try fwd.writeAll(switch (flags.linkage) {
23062310 .internal => "static ",
23072311 .strong, .weak, .link_once => "zig_extern ",
......@@ -2327,36 +2331,36 @@ pub const DeclGen = struct {
23272331 try fwd.writeAll(";\n");
23282332 }
23292333
2330 fn renderNavName(dg: *DeclGen, writer: anytype, nav_index: InternPool.Nav.Index) !void {
2334 fn renderNavName(dg: *DeclGen, bw: *std.io.BufferedWriter, nav_index: InternPool.Nav.Index) !void {
23312335 const zcu = dg.pt.zcu;
23322336 const ip = &zcu.intern_pool;
23332337 const nav = ip.getNav(nav_index);
23342338 if (nav.getExtern(ip)) |@"extern"| {
2335 try writer.print("{ }", .{
2339 try bw.print("{f }", .{
23362340 fmtIdent(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
23372341 });
23382342 } else {
23392343 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
23402344 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
23412345 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2342 try writer.print("{}__{d}", .{
2346 try bw.print("{f}__{d}", .{
23432347 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
23442348 @intFromEnum(nav_index),
23452349 });
23462350 }
23472351 }
23482352
2349 fn renderUavName(writer: anytype, uav: Value) !void {
2350 try writer.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
2353 fn renderUavName(bw: *std.io.BufferedWriter, uav: Value) !void {
2354 try bw.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
23512355 }
23522356
2353 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {
2354 try dg.renderCTypeForBuiltinFnName(writer, try dg.ctypeFromType(ty, .complete));
2357 fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type) !void {
2358 try dg.renderCTypeForBuiltinFnName(bw, try dg.ctypeFromType(ty, .complete));
23552359 }
23562360
2357 fn renderCTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ctype: CType) !void {
2361 fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) !void {
23582362 switch (ctype.info(&dg.ctype_pool)) {
2359 else => |ctype_info| try writer.print("{c}{d}", .{
2363 else => |ctype_info| try bw.print("{c}{d}", .{
23602364 if (ctype.isBool())
23612365 signAbbrev(.unsigned)
23622366 else if (ctype.isInteger())
......@@ -2369,11 +2373,11 @@ pub const DeclGen = struct {
23692373 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),
23702374 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,
23712375 }),
2372 .array => try writer.writeAll("big"),
2376 .array => try bw.writeAll("big"),
23732377 }
23742378 }
23752379
2376 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {
2380 fn renderBuiltinInfo(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type, info: BuiltinInfo) !void {
23772381 const ctype = try dg.ctypeFromType(ty, .complete);
23782382 const is_big = ctype.info(&dg.ctype_pool) == .array;
23792383 switch (info) {
......@@ -2388,8 +2392,8 @@ pub const DeclGen = struct {
23882392 .bits = @intCast(ty.bitSize(zcu)),
23892393 };
23902394
2391 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});
2392 try writer.print(", {}", .{try dg.fmtIntLiteral(
2395 if (is_big) try bw.print(", {}", .{int_info.signedness == .signed});
2396 try bw.print(", {f}", .{try dg.fmtIntLiteral(
23932397 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),
23942398 .FunctionArgument,
23952399 )});
......@@ -2422,35 +2426,32 @@ const RenderCTypeTrailing = enum {
24222426
24232427 pub fn format(
24242428 self: @This(),
2429 bw: *std.io.BufferedWriter,
24252430 comptime fmt: []const u8,
2426 _: std.fmt.FormatOptions,
2427 w: anytype,
2428 ) @TypeOf(w).Error!void {
2429 if (fmt.len != 0)
2430 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++
2431 @typeName(@This()) ++ "'");
2432 comptime assert(fmt.len == 0);
2431 ) std.io.Writer.Error!void {
2432 if (fmt.len != 0) @compileError("invalid format string '" ++
2433 fmt ++ "' for type '" ++ @typeName(@This()) ++ "'");
24332434 switch (self) {
24342435 .no_space => {},
2435 .maybe_space => try w.writeByte(' '),
2436 .maybe_space => try bw.writeByte(' '),
24362437 }
24372438 }
24382439};
2439fn renderAlignedTypeName(w: anytype, ctype: CType) !void {
2440 try w.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
2440fn renderAlignedTypeName(bw: *std.io.BufferedWriter, ctype: CType) !void {
2441 try bw.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
24412442}
24422443fn renderFwdDeclTypeName(
24432444 zcu: *Zcu,
2444 w: anytype,
2445 bw: *std.io.BufferedWriter,
24452446 ctype: CType,
24462447 fwd_decl: CType.Info.FwdDecl,
24472448 attributes: []const u8,
24482449) !void {
24492450 const ip = &zcu.intern_pool;
2450 try w.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });
2451 try bw.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });
24512452 switch (fwd_decl.name) {
2452 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2453 .index => |index| try w.print("{}__{d}", .{
2453 .anon => try bw.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2454 .index => |index| try bw.print("{f}__{d}", .{
24542455 fmtIdent(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),
24552456 @intFromEnum(index),
24562457 }),
......@@ -2460,21 +2461,21 @@ fn renderTypePrefix(
24602461 pass: DeclGen.Pass,
24612462 ctype_pool: *const CType.Pool,
24622463 zcu: *Zcu,
2463 w: anytype,
2464 bw: *std.io.BufferedWriter,
24642465 ctype: CType,
24652466 parent_fix: CTypeFix,
24662467 qualifiers: CQualifiers,
2467) @TypeOf(w).Error!RenderCTypeTrailing {
2468) std.io.Writer.Error!RenderCTypeTrailing {
24682469 var trailing = RenderCTypeTrailing.maybe_space;
24692470 switch (ctype.info(ctype_pool)) {
2470 .basic => |basic_info| try w.writeAll(@tagName(basic_info)),
2471 .basic => |basic_info| try bw.writeAll(@tagName(basic_info)),
24712472
24722473 .pointer => |pointer_info| {
2473 try w.print("{}*", .{try renderTypePrefix(
2474 try bw.print("{f}*", .{try renderTypePrefix(
24742475 pass,
24752476 ctype_pool,
24762477 zcu,
2477 w,
2478 bw,
24782479 pointer_info.elem_ctype,
24792480 .prefix,
24802481 CQualifiers.init(.{
......@@ -2486,13 +2487,13 @@ fn renderTypePrefix(
24862487 },
24872488
24882489 .aligned => switch (pass) {
2489 .nav => |nav| try w.print("nav__{d}_{d}", .{
2490 .nav => |nav| try bw.print("nav__{d}_{d}", .{
24902491 @intFromEnum(nav), @intFromEnum(ctype.index),
24912492 }),
2492 .uav => |uav| try w.print("uav__{d}_{d}", .{
2493 .uav => |uav| try bw.print("uav__{d}_{d}", .{
24932494 @intFromEnum(uav), @intFromEnum(ctype.index),
24942495 }),
2495 .flush => try renderAlignedTypeName(w, ctype),
2496 .flush => try renderAlignedTypeName(bw, ctype),
24962497 },
24972498
24982499 .array, .vector => |sequence_info| {
......@@ -2500,14 +2501,14 @@ fn renderTypePrefix(
25002501 pass,
25012502 ctype_pool,
25022503 zcu,
2503 w,
2504 bw,
25042505 sequence_info.elem_ctype,
25052506 .suffix,
25062507 qualifiers,
25072508 );
25082509 switch (parent_fix) {
25092510 .prefix => {
2510 try w.print("{}(", .{child_trailing});
2511 try bw.print("{f}(", .{child_trailing});
25112512 return .no_space;
25122513 },
25132514 .suffix => return child_trailing,
......@@ -2516,31 +2517,31 @@ fn renderTypePrefix(
25162517
25172518 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
25182519 .anon => switch (pass) {
2519 .nav => |nav| try w.print("nav__{d}_{d}", .{
2520 .nav => |nav| try bw.print("nav__{d}_{d}", .{
25202521 @intFromEnum(nav), @intFromEnum(ctype.index),
25212522 }),
2522 .uav => |uav| try w.print("uav__{d}_{d}", .{
2523 .uav => |uav| try bw.print("uav__{d}_{d}", .{
25232524 @intFromEnum(uav), @intFromEnum(ctype.index),
25242525 }),
2525 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2526 .flush => try renderFwdDeclTypeName(zcu, bw, ctype, fwd_decl_info, ""),
25262527 },
2527 .index => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2528 .index => try renderFwdDeclTypeName(zcu, bw, ctype, fwd_decl_info, ""),
25282529 },
25292530
25302531 .aggregate => |aggregate_info| switch (aggregate_info.name) {
25312532 .anon => {
2532 try w.print("{s} {s}", .{
2533 try bw.print("{s} {s}", .{
25332534 @tagName(aggregate_info.tag),
25342535 if (aggregate_info.@"packed") "zig_packed(" else "",
25352536 });
2536 try renderFields(zcu, w, ctype_pool, aggregate_info, 1);
2537 if (aggregate_info.@"packed") try w.writeByte(')');
2537 try renderFields(zcu, bw, ctype_pool, aggregate_info, 1);
2538 if (aggregate_info.@"packed") try bw.writeByte(')');
25382539 },
25392540 .fwd_decl => |fwd_decl| return renderTypePrefix(
25402541 pass,
25412542 ctype_pool,
25422543 zcu,
2543 w,
2544 bw,
25442545 fwd_decl,
25452546 parent_fix,
25462547 qualifiers,
......@@ -2552,14 +2553,14 @@ fn renderTypePrefix(
25522553 pass,
25532554 ctype_pool,
25542555 zcu,
2555 w,
2556 bw,
25562557 function_info.return_ctype,
25572558 .suffix,
25582559 .{},
25592560 );
25602561 switch (parent_fix) {
25612562 .prefix => {
2562 try w.print("{}(", .{child_trailing});
2563 try bw.print("{f}(", .{child_trailing});
25632564 return .no_space;
25642565 },
25652566 .suffix => return child_trailing,
......@@ -2568,7 +2569,7 @@ fn renderTypePrefix(
25682569 }
25692570 var qualifier_it = qualifiers.iterator();
25702571 while (qualifier_it.next()) |qualifier| {
2571 try w.print("{}{s}", .{ trailing, @tagName(qualifier) });
2572 try bw.print("{f}{s}", .{ trailing, @tagName(qualifier) });
25722573 trailing = .maybe_space;
25732574 }
25742575 return trailing;
......@@ -2577,105 +2578,105 @@ fn renderTypeSuffix(
25772578 pass: DeclGen.Pass,
25782579 ctype_pool: *const CType.Pool,
25792580 zcu: *Zcu,
2580 w: anytype,
2581 bw: *std.io.BufferedWriter,
25812582 ctype: CType,
25822583 parent_fix: CTypeFix,
25832584 qualifiers: CQualifiers,
2584) @TypeOf(w).Error!void {
2585) std.io.Writer.Error!void {
25852586 switch (ctype.info(ctype_pool)) {
25862587 .basic, .aligned, .fwd_decl, .aggregate => {},
25872588 .pointer => |pointer_info| try renderTypeSuffix(
25882589 pass,
25892590 ctype_pool,
25902591 zcu,
2591 w,
2592 bw,
25922593 pointer_info.elem_ctype,
25932594 .prefix,
25942595 .{},
25952596 ),
25962597 .array, .vector => |sequence_info| {
25972598 switch (parent_fix) {
2598 .prefix => try w.writeByte(')'),
2599 .prefix => try bw.writeByte(')'),
25992600 .suffix => {},
26002601 }
26012602
2602 try w.print("[{}]", .{sequence_info.len});
2603 try renderTypeSuffix(pass, ctype_pool, zcu, w, sequence_info.elem_ctype, .suffix, .{});
2603 try bw.print("[{}]", .{sequence_info.len});
2604 try renderTypeSuffix(pass, ctype_pool, zcu, bw, sequence_info.elem_ctype, .suffix, .{});
26042605 },
26052606 .function => |function_info| {
26062607 switch (parent_fix) {
2607 .prefix => try w.writeByte(')'),
2608 .prefix => try bw.writeByte(')'),
26082609 .suffix => {},
26092610 }
26102611
2611 try w.writeByte('(');
2612 try bw.writeByte('(');
26122613 var need_comma = false;
26132614 for (0..function_info.param_ctypes.len) |param_index| {
26142615 const param_type = function_info.param_ctypes.at(param_index, ctype_pool);
2615 if (need_comma) try w.writeAll(", ");
2616 if (need_comma) try bw.writeAll(", ");
26162617 need_comma = true;
26172618 const trailing =
2618 try renderTypePrefix(pass, ctype_pool, zcu, w, param_type, .suffix, qualifiers);
2619 if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_index });
2620 try renderTypeSuffix(pass, ctype_pool, zcu, w, param_type, .suffix, .{});
2619 try renderTypePrefix(pass, ctype_pool, zcu, bw, param_type, .suffix, qualifiers);
2620 if (qualifiers.contains(.@"const")) try bw.print("{f}a{d}", .{ trailing, param_index });
2621 try renderTypeSuffix(pass, ctype_pool, zcu, bw, param_type, .suffix, .{});
26212622 }
26222623 if (function_info.varargs) {
2623 if (need_comma) try w.writeAll(", ");
2624 if (need_comma) try bw.writeAll(", ");
26242625 need_comma = true;
2625 try w.writeAll("...");
2626 try bw.writeAll("...");
26262627 }
2627 if (!need_comma) try w.writeAll("void");
2628 try w.writeByte(')');
2628 if (!need_comma) try bw.writeAll("void");
2629 try bw.writeByte(')');
26292630
2630 try renderTypeSuffix(pass, ctype_pool, zcu, w, function_info.return_ctype, .suffix, .{});
2631 try renderTypeSuffix(pass, ctype_pool, zcu, bw, function_info.return_ctype, .suffix, .{});
26312632 },
26322633 }
26332634}
26342635fn renderFields(
26352636 zcu: *Zcu,
2636 writer: anytype,
2637 bw: *std.io.BufferedWriter,
26372638 ctype_pool: *const CType.Pool,
26382639 aggregate_info: CType.Info.Aggregate,
26392640 indent: usize,
26402641) !void {
2641 try writer.writeAll("{\n");
2642 try bw.writeAll("{\n");
26422643 for (0..aggregate_info.fields.len) |field_index| {
26432644 const field_info = aggregate_info.fields.at(field_index, ctype_pool);
2644 try writer.writeByteNTimes(' ', indent + 1);
2645 try bw.splatByteAll(' ', indent + 1);
26452646 switch (field_info.alignas.abiOrder()) {
26462647 .lt => {
26472648 std.debug.assert(aggregate_info.@"packed");
2648 if (field_info.alignas.@"align" != .@"1") try writer.print("zig_under_align({}) ", .{
2649 if (field_info.alignas.@"align" != .@"1") try bw.print("zig_under_align({}) ", .{
26492650 field_info.alignas.toByteUnits(),
26502651 });
26512652 },
26522653 .eq => if (aggregate_info.@"packed" and field_info.alignas.@"align" != .@"1")
2653 try writer.print("zig_align({}) ", .{field_info.alignas.toByteUnits()}),
2654 try bw.print("zig_align({}) ", .{field_info.alignas.toByteUnits()}),
26542655 .gt => {
26552656 std.debug.assert(field_info.alignas.@"align" != .@"1");
2656 try writer.print("zig_align({}) ", .{field_info.alignas.toByteUnits()});
2657 try bw.print("zig_align({}) ", .{field_info.alignas.toByteUnits()});
26572658 },
26582659 }
26592660 const trailing = try renderTypePrefix(
26602661 .flush,
26612662 ctype_pool,
26622663 zcu,
2663 writer,
2664 bw,
26642665 field_info.ctype,
26652666 .suffix,
26662667 .{},
26672668 );
2668 try writer.print("{}{ }", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool) });
2669 try renderTypeSuffix(.flush, ctype_pool, zcu, writer, field_info.ctype, .suffix, .{});
2670 try writer.writeAll(";\n");
2669 try bw.print("{f}{f }", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool) });
2670 try renderTypeSuffix(.flush, ctype_pool, zcu, bw, field_info.ctype, .suffix, .{});
2671 try bw.writeAll(";\n");
26712672 }
2672 try writer.writeByteNTimes(' ', indent);
2673 try writer.writeByte('}');
2673 try bw.splatByteAll(' ', indent);
2674 try bw.writeByte('}');
26742675}
26752676
26762677pub fn genTypeDecl(
26772678 zcu: *Zcu,
2678 writer: anytype,
2679 bw: *std.io.BufferedWriter,
26792680 global_ctype_pool: *const CType.Pool,
26802681 global_ctype: CType,
26812682 pass: DeclGen.Pass,
......@@ -2688,27 +2689,27 @@ pub fn genTypeDecl(
26882689 .aligned => |aligned_info| {
26892690 if (!found_existing) {
26902691 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));
2691 try writer.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2692 try writer.print("{}", .{try renderTypePrefix(
2692 try bw.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2693 try bw.print("{f}", .{try renderTypePrefix(
26932694 .flush,
26942695 global_ctype_pool,
26952696 zcu,
2696 writer,
2697 bw,
26972698 aligned_info.ctype,
26982699 .suffix,
26992700 .{},
27002701 )});
2701 try renderAlignedTypeName(writer, global_ctype);
2702 try renderTypeSuffix(.flush, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{});
2703 try writer.writeAll(";\n");
2702 try renderAlignedTypeName(bw, global_ctype);
2703 try renderTypeSuffix(.flush, global_ctype_pool, zcu, bw, aligned_info.ctype, .suffix, .{});
2704 try bw.writeAll(";\n");
27042705 }
27052706 switch (pass) {
27062707 .nav, .uav => {
2707 try writer.writeAll("typedef ");
2708 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2709 try writer.writeByte(' ');
2710 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});
2711 try writer.writeAll(";\n");
2708 try bw.writeAll("typedef ");
2709 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2710 try bw.writeByte(' ');
2711 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, bw, decl_ctype, .suffix, .{});
2712 try bw.writeAll(";\n");
27122713 },
27132714 .flush => {},
27142715 }
......@@ -2716,24 +2717,24 @@ pub fn genTypeDecl(
27162717 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
27172718 .anon => switch (pass) {
27182719 .nav, .uav => {
2719 try writer.writeAll("typedef ");
2720 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2721 try writer.writeByte(' ');
2722 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});
2723 try writer.writeAll(";\n");
2720 try bw.writeAll("typedef ");
2721 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2722 try bw.writeByte(' ');
2723 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, bw, decl_ctype, .suffix, .{});
2724 try bw.writeAll(";\n");
27242725 },
27252726 .flush => {},
27262727 },
27272728 .index => |index| if (!found_existing) {
27282729 const ip = &zcu.intern_pool;
27292730 const ty: Type = .fromInterned(index);
2730 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});
2731 try writer.writeByte(';');
2731 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2732 try bw.writeByte(';');
27322733 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);
2733 if (!zcu.fileByIndex(file_scope).mod.?.strip) try writer.print(" /* {} */", .{
2734 if (!zcu.fileByIndex(file_scope).mod.?.strip) try bw.print(" /* {f} */", .{
27342735 ty.containerTypeName(ip).fmt(ip),
27352736 });
2736 try writer.writeByte('\n');
2737 try bw.writeByte('\n');
27372738 },
27382739 },
27392740 .aggregate => |aggregate_info| switch (aggregate_info.name) {
......@@ -2741,38 +2742,39 @@ pub fn genTypeDecl(
27412742 .fwd_decl => |fwd_decl| if (!found_existing) {
27422743 try renderFwdDeclTypeName(
27432744 zcu,
2744 writer,
2745 bw,
27452746 fwd_decl,
27462747 fwd_decl.info(global_ctype_pool).fwd_decl,
27472748 if (aggregate_info.@"packed") "zig_packed(" else "",
27482749 );
2749 try writer.writeByte(' ');
2750 try renderFields(zcu, writer, global_ctype_pool, aggregate_info, 0);
2751 if (aggregate_info.@"packed") try writer.writeByte(')');
2752 try writer.writeAll(";\n");
2750 try bw.writeByte(' ');
2751 try renderFields(zcu, bw, global_ctype_pool, aggregate_info, 0);
2752 if (aggregate_info.@"packed") try bw.writeByte(')');
2753 try bw.writeAll(";\n");
27532754 },
27542755 },
27552756 }
27562757}
27572758
2758pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {
2759pub fn genGlobalAsm(zcu: *Zcu, bw: *std.io.BufferedWriter) !void {
27592760 for (zcu.global_assembly.values()) |asm_source| {
2760 try writer.print("__asm({s});\n", .{fmtStringLiteral(asm_source, null)});
2761 try bw.print("__asm({fs});\n", .{fmtStringLiteral(asm_source, null)});
27612762 }
27622763}
27632764
2764pub fn genErrDecls(o: *Object) !void {
2765pub fn genErrDecls(o: *Object) Error!void {
27652766 const pt = o.dg.pt;
27662767 const zcu = pt.zcu;
27672768 const ip = &zcu.intern_pool;
2768 const writer = o.writer();
2769 const bw = &o.code.buffered_writer;
27692770
27702771 var max_name_len: usize = 0;
27712772 // do not generate an invalid empty enum when the global error set is empty
27722773 const names = ip.global_error_set.getNamesFromMainThread();
27732774 if (names.len > 0) {
2774 try writer.writeAll("enum {\n");
2775 o.indent_writer.pushIndent();
2775 try bw.writeAll("enum {");
2776 o.indent();
2777 try o.newline();
27762778 for (names, 1..) |name_nts, value| {
27772779 const name = name_nts.toSlice(ip);
27782780 max_name_len = @max(name.len, max_name_len);
......@@ -2780,11 +2782,13 @@ pub fn genErrDecls(o: *Object) !void {
27802782 .ty = .anyerror_type,
27812783 .name = name_nts,
27822784 } });
2783 try o.dg.renderValue(writer, Value.fromInterned(err_val), .Other);
2784 try writer.print(" = {d}u,\n", .{value});
2785 try o.dg.renderValue(bw, Value.fromInterned(err_val), .Other);
2786 try bw.print(" = {d}u,", .{value});
2787 try o.newline();
27852788 }
2786 o.indent_writer.popIndent();
2787 try writer.writeAll("};\n");
2789 o.outdent();
2790 try bw.writeAll("};");
2791 try o.newline();
27882792 }
27892793 const array_identifier = "zig_errorName";
27902794 const name_prefix = array_identifier ++ "_";
......@@ -2807,18 +2811,19 @@ pub fn genErrDecls(o: *Object) !void {
28072811 .storage = .{ .bytes = name.toString() },
28082812 } });
28092813
2810 try writer.writeAll("static ");
2814 try bw.writeAll("static ");
28112815 try o.dg.renderTypeAndName(
2812 writer,
2816 bw,
28132817 name_ty,
28142818 .{ .identifier = identifier },
28152819 Const,
28162820 .none,
28172821 .complete,
28182822 );
2819 try writer.writeAll(" = ");
2820 try o.dg.renderValue(writer, Value.fromInterned(name_val), .StaticInitializer);
2821 try writer.writeAll(";\n");
2823 try bw.writeAll(" = ");
2824 try o.dg.renderValue(bw, Value.fromInterned(name_val), .StaticInitializer);
2825 try bw.writeByte(';');
2826 try o.newline();
28222827 }
28232828
28242829 const name_array_ty = try pt.arrayType(.{
......@@ -2826,33 +2831,34 @@ pub fn genErrDecls(o: *Object) !void {
28262831 .child = .slice_const_u8_sentinel_0_type,
28272832 });
28282833
2829 try writer.writeAll("static ");
2834 try bw.writeAll("static ");
28302835 try o.dg.renderTypeAndName(
2831 writer,
2836 bw,
28322837 name_array_ty,
28332838 .{ .identifier = array_identifier },
28342839 Const,
28352840 .none,
28362841 .complete,
28372842 );
2838 try writer.writeAll(" = {");
2843 try bw.writeAll(" = {");
28392844 for (names, 1..) |name_nts, val| {
28402845 const name = name_nts.toSlice(ip);
2841 if (val > 1) try writer.writeAll(", ");
2842 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2846 if (val > 1) try bw.writeAll(", ");
2847 try bw.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{
28432848 fmtIdent(name),
28442849 try o.dg.fmtIntLiteral(try pt.intValue(.usize, name.len), .StaticInitializer),
28452850 });
28462851 }
2847 try writer.writeAll("};\n");
2852 try bw.writeAll("};");
2853 try o.newline();
28482854}
28492855
2850pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void {
2856pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) Error!void {
28512857 const pt = o.dg.pt;
28522858 const zcu = pt.zcu;
28532859 const ip = &zcu.intern_pool;
28542860 const ctype_pool = &o.dg.ctype_pool;
2855 const w = o.writer();
2861 const bw = &o.code.buffered_writer;
28562862 const key = lazy_fn.key_ptr.*;
28572863 const val = lazy_fn.value_ptr;
28582864 switch (key) {
......@@ -2860,11 +2866,16 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
28602866 const enum_ty: Type = .fromInterned(enum_ty_ip);
28612867 const name_slice_ty: Type = .slice_const_u8_sentinel_0;
28622868
2863 try w.writeAll("static ");
2864 try o.dg.renderType(w, name_slice_ty);
2865 try w.print(" {}(", .{val.fn_name.fmt(lazy_ctype_pool)});
2866 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
2867 try w.writeAll(") {\n switch (tag) {\n");
2869 try bw.writeAll("static ");
2870 try o.dg.renderType(bw, name_slice_ty);
2871 try bw.print(" {f}(", .{val.fn_name.fmt(lazy_ctype_pool)});
2872 try o.dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
2873 try bw.writeAll(") {");
2874 o.indent();
2875 try o.newline();
2876 try bw.writeAll("switch (tag) {");
2877 o.indent();
2878 try o.newline();
28682879 const tag_names = enum_ty.enumFields(zcu);
28692880 for (0..tag_names.len) |tag_index| {
28702881 const tag_name = tag_names.get(ip)[tag_index];
......@@ -2881,26 +2892,35 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
28812892 .storage = .{ .bytes = tag_name.toString() },
28822893 } });
28832894
2884 try w.print(" case {}: {{\n static ", .{
2895 try bw.print("case {f}: {{", .{
28852896 try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other),
28862897 });
2887 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
2888 try w.writeAll(" = ");
2889 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);
2890 try w.writeAll(";\n return (");
2891 try o.dg.renderType(w, name_slice_ty);
2892 try w.print("){{{}, {}}};\n", .{
2898 try o.newline();
2899 try bw.writeAll("static ");
2900 try o.dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
2901 try bw.writeAll(" = ");
2902 try o.dg.renderValue(bw, Value.fromInterned(name_val), .StaticInitializer);
2903 try bw.writeByte(';');
2904 try o.newline();
2905 try bw.writeAll("return (");
2906 try o.dg.renderType(bw, name_slice_ty);
2907 try bw.print("){{{f}, {f}}};", .{
28932908 fmtIdent("name"),
28942909 try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other),
28952910 });
2911 try o.newline();
28962912
2897 try w.writeAll(" }\n");
2913 try bw.writeByte('}');
2914 try o.newline();
28982915 }
2899 try w.writeAll(" }\n while (");
2900 try o.dg.renderValue(w, Value.true, .Other);
2901 try w.writeAll(") ");
2902 _ = try airBreakpoint(w);
2903 try w.writeAll("}\n");
2916 try bw.writeByte('}');
2917 try o.newline();
2918 try bw.writeAll("while (");
2919 try o.dg.renderValue(bw, Value.true, .Other);
2920 try bw.writeAll(") ");
2921 _ = try airBreakpoint(o, bw);
2922 try bw.writeByte('}');
2923 try o.newline();
29042924 },
29052925 .never_tail, .never_inline => |fn_nav_index| {
29062926 const fn_val = zcu.navValue(fn_nav_index);
......@@ -2908,25 +2928,30 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
29082928 const fn_info = fn_ctype.info(ctype_pool).function;
29092929 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);
29102930
2911 const fwd = o.dg.fwdDeclWriter();
2931 const fwd = &o.dg.fwd_decl.buffered_writer;
29122932 try fwd.print("static zig_{s} ", .{@tagName(key)});
29132933 try o.dg.renderFunctionSignature(fwd, fn_val, ip.getNav(fn_nav_index).getAlignment(), .forward, .{
29142934 .fmt_ctype_pool_string = fn_name,
29152935 });
29162936 try fwd.writeAll(";\n");
29172937
2918 try w.print("zig_{s} ", .{@tagName(key)});
2919 try o.dg.renderFunctionSignature(w, fn_val, .none, .complete, .{
2938 try bw.print("zig_{s} ", .{@tagName(key)});
2939 try o.dg.renderFunctionSignature(bw, fn_val, .none, .complete, .{
29202940 .fmt_ctype_pool_string = fn_name,
29212941 });
2922 try w.writeAll(" {\n return ");
2923 try o.dg.renderNavName(w, fn_nav_index);
2924 try w.writeByte('(');
2942 try bw.writeAll(" {");
2943 try o.newline();
2944 try bw.writeAll("return ");
2945 try o.dg.renderNavName(bw, fn_nav_index);
2946 try bw.writeByte('(');
29252947 for (0..fn_info.param_ctypes.len) |arg| {
2926 if (arg > 0) try w.writeAll(", ");
2927 try w.print("a{d}", .{arg});
2948 if (arg > 0) try bw.writeAll(", ");
2949 try bw.print("a{d}", .{arg});
29282950 }
2929 try w.writeAll(");\n}\n");
2951 try bw.writeAll(");");
2952 try o.newline();
2953 try bw.writeByte('}');
2954 try o.newline();
29302955 },
29312956 }
29322957}
......@@ -3015,10 +3040,7 @@ fn genFunc(f: *Function) !void {
30153040 const nav_val = zcu.navValue(nav_index);
30163041 const nav = ip.getNav(nav_index);
30173042
3018 o.code_header = std.ArrayList(u8).init(gpa);
3019 defer o.code_header.deinit();
3020
3021 const fwd = o.dg.fwdDeclWriter();
3043 const fwd = &o.dg.fwd_decl.buffered_writer;
30223044 try fwd.writeAll("static ");
30233045 try o.dg.renderFunctionSignature(
30243046 fwd,
......@@ -3029,29 +3051,23 @@ fn genFunc(f: *Function) !void {
30293051 );
30303052 try fwd.writeAll(";\n");
30313053
3054 const ch = &o.code_header.buffered_writer;
30323055 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s|
3033 try o.writer().print("zig_linksection_fn({s}) ", .{fmtStringLiteral(s, null)});
3056 try ch.print("zig_linksection_fn({fs}) ", .{fmtStringLiteral(s, null)});
30343057 try o.dg.renderFunctionSignature(
3035 o.writer(),
3058 ch,
30363059 nav_val,
30373060 .none,
30383061 .complete,
30393062 .{ .nav = nav_index },
30403063 );
3041 try o.writer().writeByte(' ');
3042
3043 // In case we need to use the header, populate it with a copy of the function
3044 // signature here. We anticipate a brace, newline, and space.
3045 try o.code_header.ensureUnusedCapacity(o.code.items.len + 3);
3046 o.code_header.appendSliceAssumeCapacity(o.code.items);
3047 o.code_header.appendSliceAssumeCapacity("{\n ");
3048 const empty_header_len = o.code_header.items.len;
3064 try ch.writeAll(" {\n ");
30493065
30503066 f.free_locals_map.clearRetainingCapacity();
30513067
30523068 const main_body = f.air.getMainBody();
30533069 try genBodyResolveState(f, undefined, &.{}, main_body, false);
3054 try o.indent_writer.insertNewline();
3070 try o.newline();
30553071 if (o.dg.expected_block) |_|
30563072 return f.fail("runtime code not allowed in naked function", .{});
30573073
......@@ -3082,24 +3098,16 @@ fn genFunc(f: *Function) !void {
30823098 };
30833099 free_locals.sort(SortContext{ .keys = free_locals.keys() });
30843100
3085 const w = o.codeHeaderWriter();
30863101 for (free_locals.values()) |list| {
30873102 for (list.keys()) |local_index| {
30883103 const local = f.locals.items[local_index];
3089 try o.dg.renderCTypeAndName(w, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);
3090 try w.writeAll(";\n ");
3104 try o.dg.renderCTypeAndName(ch, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);
3105 try ch.writeAll(";\n ");
30913106 }
30923107 }
3093
3094 // If we have a header to insert, append the body to the header
3095 // and then return the result, freeing the body.
3096 if (o.code_header.items.len > empty_header_len) {
3097 try o.code_header.appendSlice(o.code.items[empty_header_len..]);
3098 mem.swap(std.ArrayList(u8), &o.code, &o.code_header);
3099 }
31003108}
31013109
3102pub fn genDecl(o: *Object) !void {
3110pub fn genDecl(o: *Object) Error!void {
31033111 const tracy = trace(@src());
31043112 defer tracy.end();
31053113
......@@ -3119,7 +3127,7 @@ pub fn genDecl(o: *Object) !void {
31193127 .visibility = @"extern".visibility,
31203128 });
31213129
3122 const fwd = o.dg.fwdDeclWriter();
3130 const fwd = &o.dg.fwd_decl.buffered_writer;
31233131 try fwd.writeAll("zig_extern ");
31243132 try o.dg.renderFunctionSignature(
31253133 fwd,
......@@ -3140,22 +3148,22 @@ pub fn genDecl(o: *Object) !void {
31403148 .linkage = .internal,
31413149 .visibility = .default,
31423150 });
3143 const w = o.writer();
3144 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");
3151 const bw = &o.code.buffered_writer;
3152 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try bw.writeAll("zig_threadlocal ");
31453153 if (nav.status.fully_resolved.@"linksection".toSlice(&zcu.intern_pool)) |s|
3146 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
3154 try bw.print("zig_linksection({fs}) ", .{fmtStringLiteral(s, null)});
31473155 try o.dg.renderTypeAndName(
3148 w,
3156 bw,
31493157 nav_ty,
31503158 .{ .nav = o.dg.pass.nav },
31513159 .{},
31523160 nav.status.fully_resolved.alignment,
31533161 .complete,
31543162 );
3155 try w.writeAll(" = ");
3156 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);
3157 try w.writeByte(';');
3158 try o.indent_writer.insertNewline();
3163 try bw.writeAll(" = ");
3164 try o.dg.renderValue(bw, Value.fromInterned(variable.init), .StaticInitializer);
3165 try bw.writeByte(';');
3166 try o.newline();
31593167 },
31603168 else => try genDeclValue(
31613169 o,
......@@ -3173,28 +3181,29 @@ pub fn genDeclValue(
31733181 decl_c_value: CValue,
31743182 alignment: Alignment,
31753183 @"linksection": InternPool.OptionalNullTerminatedString,
3176) !void {
3184) Error!void {
31773185 const zcu = o.dg.pt.zcu;
31783186 const ty = val.typeOf(zcu);
31793187
3180 const fwd = o.dg.fwdDeclWriter();
3188 const fwd = &o.dg.fwd_decl.buffered_writer;
31813189 try fwd.writeAll("static ");
31823190 try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete);
31833191 try fwd.writeAll(";\n");
31843192
3185 const w = o.writer();
3193 const bw = &o.code.buffered_writer;
31863194 if (@"linksection".toSlice(&zcu.intern_pool)) |s|
3187 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});
3188 try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);
3189 try w.writeAll(" = ");
3190 try o.dg.renderValue(w, val, .StaticInitializer);
3191 try w.writeAll(";\n");
3195 try bw.print("zig_linksection({fs}) ", .{fmtStringLiteral(s, null)});
3196 try o.dg.renderTypeAndName(bw, ty, decl_c_value, Const, alignment, .complete);
3197 try bw.writeAll(" = ");
3198 try o.dg.renderValue(bw, val, .StaticInitializer);
3199 try bw.writeByte(';');
3200 try o.newline();
31923201}
31933202
31943203pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {
31953204 const zcu = dg.pt.zcu;
31963205 const ip = &zcu.intern_pool;
3197 const fwd = dg.fwdDeclWriter();
3206 const fwd = &dg.fwd_decl.buffered_writer;
31983207
31993208 const main_name = export_indices[0].ptr(zcu).opts.name;
32003209 try fwd.writeAll("#define ");
......@@ -3203,7 +3212,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32033212 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),
32043213 }
32053214 try fwd.writeByte(' ');
3206 try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))});
3215 try fwd.print("{f }", .{fmtIdent(main_name.toSlice(ip))});
32073216 try fwd.writeByte('\n');
32083217
32093218 const exported_val = exported.getValue(zcu);
......@@ -3233,7 +3242,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32333242 const @"export" = export_index.ptr(zcu);
32343243 try fwd.writeAll("zig_extern ");
32353244 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage ");
3236 if (@"export".opts.section.toSlice(ip)) |s| try fwd.print("zig_linksection({s}) ", .{
3245 if (@"export".opts.section.toSlice(ip)) |s| try fwd.print("zig_linksection({fs}) ", .{
32373246 fmtStringLiteral(s, null),
32383247 });
32393248 const extern_name = @"export".opts.name.toSlice(ip);
......@@ -3248,17 +3257,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32483257 .complete,
32493258 );
32503259 if (is_mangled and is_export) {
3251 try fwd.print(" zig_mangled_export({ }, {s}, {s})", .{
3260 try fwd.print(" zig_mangled_export({f }, {fs}, {fs})", .{
32523261 fmtIdent(extern_name),
32533262 fmtStringLiteral(extern_name, null),
32543263 fmtStringLiteral(main_name.toSlice(ip), null),
32553264 });
32563265 } else if (is_mangled) {
3257 try fwd.print(" zig_mangled({ }, {s})", .{
3266 try fwd.print(" zig_mangled({f }, {fs})", .{
32583267 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),
32593268 });
32603269 } else if (is_export) {
3261 try fwd.print(" zig_export({s}, {s})", .{
3270 try fwd.print(" zig_export({fs}, {fs})", .{
32623271 fmtStringLiteral(main_name.toSlice(ip), null),
32633272 fmtStringLiteral(extern_name, null),
32643273 });
......@@ -3271,16 +3280,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32713280/// `value_map` and `free_locals_map` are undefined after the generation, and new locals may not
32723281/// have been added to `free_locals_map`. For a version of this function that restores this state,
32733282/// see `genBodyResolveState`.
3274fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
3275 const writer = f.object.writer();
3283fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
3284 const bw = &f.object.code.buffered_writer;
32763285 if (body.len == 0) {
3277 try writer.writeAll("{}");
3286 try bw.writeAll("{}");
32783287 } else {
3279 try writer.writeAll("{\n");
3280 f.object.indent_writer.pushIndent();
3288 try bw.writeAll("{");
3289 f.object.indent();
3290 try f.object.newline();
32813291 try genBodyInner(f, body);
3282 f.object.indent_writer.popIndent();
3283 try writer.writeByte('}');
3292 f.object.outdent();
3293 try bw.writeByte('}');
32843294 }
32853295}
32863296
......@@ -3290,10 +3300,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
32903300/// `leading_deaths` have their deaths processed before the body is generated.
32913301/// A scope is introduced (using braces) only if `inner` is `false`.
32923302/// If `leading_deaths` is empty, `inst` may be `undefined`.
3293fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []const Air.Inst.Index, body: []const Air.Inst.Index, inner: bool) error{ AnalysisFail, OutOfMemory }!void {
3303fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []const Air.Inst.Index, body: []const Air.Inst.Index, inner: bool) Error!void {
32943304 if (body.len == 0) {
32953305 // Don't go to the expense of cloning everything!
3296 if (!inner) try f.object.writer().writeAll("{}");
3306 if (!inner) try f.object.code.buffered_writer.writeAll("{}");
32973307 return;
32983308 }
32993309
......@@ -3339,7 +3349,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
33393349 }
33403350}
33413351
3342fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
3352fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
33433353 const zcu = f.object.dg.pt.zcu;
33443354 const ip = &zcu.intern_pool;
33453355 const air_tags = f.air.instructions.items(.tag);
......@@ -3357,7 +3367,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
33573367
33583368 .arg => try airArg(f, inst),
33593369
3360 .breakpoint => try airBreakpoint(f.object.writer()),
3370 .breakpoint => try airBreakpoint(&f.object, &f.object.code.buffered_writer),
33613371 .ret_addr => try airRetAddr(f, inst),
33623372 .frame_addr => try airFrameAddress(f, inst),
33633373
......@@ -3610,7 +3620,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
36103620 .ret => return airRet(f, inst, false),
36113621 .ret_safe => return airRet(f, inst, false), // TODO
36123622 .ret_load => return airRet(f, inst, true),
3613 .trap => return airTrap(f, f.object.writer()),
3623 .trap => return airTrap(f, &f.object.code.buffered_writer),
36143624 .unreach => return airUnreach(f),
36153625
36163626 // Instructions which may be `noreturn`.
......@@ -3654,16 +3664,16 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
36543664 const operand = try f.resolveInst(ty_op.operand);
36553665 try reap(f, inst, &.{ty_op.operand});
36563666
3657 const writer = f.object.writer();
3667 const bw = &f.object.code.buffered_writer;
36583668 const local = try f.allocLocal(inst, inst_ty);
3659 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3660 try f.writeCValue(writer, local, .Other);
3661 try a.assign(f, writer);
3669 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3670 try f.writeCValue(bw, local, .Other);
3671 try a.assign(f, bw);
36623672 if (is_ptr) {
3663 try writer.writeByte('&');
3664 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });
3665 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });
3666 try a.end(f, writer);
3673 try bw.writeByte('&');
3674 try f.writeCValueDerefMember(bw, operand, .{ .identifier = field_name });
3675 } else try f.writeCValueMember(bw, operand, .{ .identifier = field_name });
3676 try a.end(f, bw);
36673677 return local;
36683678}
36693679
......@@ -3680,16 +3690,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
36803690 const index = try f.resolveInst(bin_op.rhs);
36813691 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36823692
3683 const writer = f.object.writer();
3693 const bw = &f.object.code.buffered_writer;
36843694 const local = try f.allocLocal(inst, inst_ty);
3685 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3686 try f.writeCValue(writer, local, .Other);
3687 try a.assign(f, writer);
3688 try f.writeCValue(writer, ptr, .Other);
3689 try writer.writeByte('[');
3690 try f.writeCValue(writer, index, .Other);
3691 try writer.writeByte(']');
3692 try a.end(f, writer);
3695 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3696 try f.writeCValue(bw, local, .Other);
3697 try a.assign(f, bw);
3698 try f.writeCValue(bw, ptr, .Other);
3699 try bw.writeByte('[');
3700 try f.writeCValue(bw, index, .Other);
3701 try bw.writeByte(']');
3702 try a.end(f, bw);
36933703 return local;
36943704}
36953705
......@@ -3707,25 +3717,25 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
37073717 const index = try f.resolveInst(bin_op.rhs);
37083718 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37093719
3710 const writer = f.object.writer();
3720 const bw = &f.object.code.buffered_writer;
37113721 const local = try f.allocLocal(inst, inst_ty);
3712 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3713 try f.writeCValue(writer, local, .Other);
3714 try a.assign(f, writer);
3715 try writer.writeByte('(');
3716 try f.renderType(writer, inst_ty);
3717 try writer.writeByte(')');
3718 if (elem_has_bits) try writer.writeByte('&');
3722 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3723 try f.writeCValue(bw, local, .Other);
3724 try a.assign(f, bw);
3725 try bw.writeByte('(');
3726 try f.renderType(bw, inst_ty);
3727 try bw.writeByte(')');
3728 if (elem_has_bits) try bw.writeByte('&');
37193729 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {
37203730 // It's a pointer to an array, so we need to de-reference.
3721 try f.writeCValueDeref(writer, ptr);
3722 } else try f.writeCValue(writer, ptr, .Other);
3731 try f.writeCValueDeref(bw, ptr);
3732 } else try f.writeCValue(bw, ptr, .Other);
37233733 if (elem_has_bits) {
3724 try writer.writeByte('[');
3725 try f.writeCValue(writer, index, .Other);
3726 try writer.writeByte(']');
3734 try bw.writeByte('[');
3735 try f.writeCValue(bw, index, .Other);
3736 try bw.writeByte(']');
37273737 }
3728 try a.end(f, writer);
3738 try a.end(f, bw);
37293739 return local;
37303740}
37313741
......@@ -3742,16 +3752,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
37423752 const index = try f.resolveInst(bin_op.rhs);
37433753 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37443754
3745 const writer = f.object.writer();
3755 const bw = &f.object.code.buffered_writer;
37463756 const local = try f.allocLocal(inst, inst_ty);
3747 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3748 try f.writeCValue(writer, local, .Other);
3749 try a.assign(f, writer);
3750 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3751 try writer.writeByte('[');
3752 try f.writeCValue(writer, index, .Other);
3753 try writer.writeByte(']');
3754 try a.end(f, writer);
3757 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3758 try f.writeCValue(bw, local, .Other);
3759 try a.assign(f, bw);
3760 try f.writeCValueMember(bw, slice, .{ .identifier = "ptr" });
3761 try bw.writeByte('[');
3762 try f.writeCValue(bw, index, .Other);
3763 try bw.writeByte(']');
3764 try a.end(f, bw);
37553765 return local;
37563766}
37573767
......@@ -3770,19 +3780,19 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
37703780 const index = try f.resolveInst(bin_op.rhs);
37713781 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37723782
3773 const writer = f.object.writer();
3783 const bw = &f.object.code.buffered_writer;
37743784 const local = try f.allocLocal(inst, inst_ty);
3775 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3776 try f.writeCValue(writer, local, .Other);
3777 try a.assign(f, writer);
3778 if (elem_has_bits) try writer.writeByte('&');
3779 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });
3785 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3786 try f.writeCValue(bw, local, .Other);
3787 try a.assign(f, bw);
3788 if (elem_has_bits) try bw.writeByte('&');
3789 try f.writeCValueMember(bw, slice, .{ .identifier = "ptr" });
37803790 if (elem_has_bits) {
3781 try writer.writeByte('[');
3782 try f.writeCValue(writer, index, .Other);
3783 try writer.writeByte(']');
3791 try bw.writeByte('[');
3792 try f.writeCValue(bw, index, .Other);
3793 try bw.writeByte(']');
37843794 }
3785 try a.end(f, writer);
3795 try a.end(f, bw);
37863796 return local;
37873797}
37883798
......@@ -3799,16 +3809,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
37993809 const index = try f.resolveInst(bin_op.rhs);
38003810 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
38013811
3802 const writer = f.object.writer();
3812 const bw = &f.object.code.buffered_writer;
38033813 const local = try f.allocLocal(inst, inst_ty);
3804 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
3805 try f.writeCValue(writer, local, .Other);
3806 try a.assign(f, writer);
3807 try f.writeCValue(writer, array, .Other);
3808 try writer.writeByte('[');
3809 try f.writeCValue(writer, index, .Other);
3810 try writer.writeByte(']');
3811 try a.end(f, writer);
3814 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3815 try f.writeCValue(bw, local, .Other);
3816 try a.assign(f, bw);
3817 try f.writeCValue(bw, array, .Other);
3818 try bw.writeByte('[');
3819 try f.writeCValue(bw, index, .Other);
3820 try bw.writeByte(']');
3821 try a.end(f, bw);
38123822 return local;
38133823}
38143824
......@@ -3862,12 +3872,13 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
38623872 .{ .arg_array = i };
38633873
38643874 if (f.liveness.isUnused(inst)) {
3865 const writer = f.object.writer();
3866 try writer.writeByte('(');
3867 try f.renderType(writer, .void);
3868 try writer.writeByte(')');
3869 try f.writeCValue(writer, result, .Other);
3870 try writer.writeAll(";\n");
3875 const bw = &f.object.code.buffered_writer;
3876 try bw.writeByte('(');
3877 try f.renderType(bw, .void);
3878 try bw.writeByte(')');
3879 try f.writeCValue(bw, result, .Other);
3880 try bw.writeByte(';');
3881 try f.object.newline();
38713882 return .none;
38723883 }
38733884
......@@ -3900,21 +3911,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39003911 const is_array = lowersToArray(src_ty, pt);
39013912 const need_memcpy = !is_aligned or is_array;
39023913
3903 const writer = f.object.writer();
3914 const bw = &f.object.code.buffered_writer;
39043915 const local = try f.allocLocal(inst, src_ty);
3905 const v = try Vectorize.start(f, inst, writer, ptr_ty);
3916 const v = try Vectorize.start(f, inst, bw, ptr_ty);
39063917
39073918 if (need_memcpy) {
3908 try writer.writeAll("memcpy(");
3909 if (!is_array) try writer.writeByte('&');
3910 try f.writeCValue(writer, local, .Other);
3911 try v.elem(f, writer);
3912 try writer.writeAll(", (const char *)");
3913 try f.writeCValue(writer, operand, .Other);
3914 try v.elem(f, writer);
3915 try writer.writeAll(", sizeof(");
3916 try f.renderType(writer, src_ty);
3917 try writer.writeAll("))");
3919 try bw.writeAll("memcpy(");
3920 if (!is_array) try bw.writeByte('&');
3921 try f.writeCValue(bw, local, .Other);
3922 try v.elem(f, bw);
3923 try bw.writeAll(", (const char *)");
3924 try f.writeCValue(bw, operand, .Other);
3925 try v.elem(f, bw);
3926 try bw.writeAll(", sizeof(");
3927 try f.renderType(bw, src_ty);
3928 try bw.writeAll("))");
39183929 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
39193930 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
39203931 const host_ty = try pt.intType(.unsigned, host_bits);
......@@ -3924,40 +3935,41 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39243935
39253936 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));
39263937
3927 try f.writeCValue(writer, local, .Other);
3928 try v.elem(f, writer);
3929 try writer.writeAll(" = (");
3930 try f.renderType(writer, src_ty);
3931 try writer.writeAll(")zig_wrap_");
3932 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);
3933 try writer.writeAll("((");
3934 try f.renderType(writer, field_ty);
3935 try writer.writeByte(')');
3938 try f.writeCValue(bw, local, .Other);
3939 try v.elem(f, bw);
3940 try bw.writeAll(" = (");
3941 try f.renderType(bw, src_ty);
3942 try bw.writeAll(")zig_wrap_");
3943 try f.object.dg.renderTypeForBuiltinFnName(bw, field_ty);
3944 try bw.writeAll("((");
3945 try f.renderType(bw, field_ty);
3946 try bw.writeByte(')');
39363947 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
39373948 if (cant_cast) {
39383949 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3939 try writer.writeAll("zig_lo_");
3940 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3941 try writer.writeByte('(');
3950 try bw.writeAll("zig_lo_");
3951 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
3952 try bw.writeByte('(');
39423953 }
3943 try writer.writeAll("zig_shr_");
3944 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
3945 try writer.writeByte('(');
3946 try f.writeCValueDeref(writer, operand);
3947 try v.elem(f, writer);
3948 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_val)});
3949 if (cant_cast) try writer.writeByte(')');
3950 try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits);
3951 try writer.writeByte(')');
3954 try bw.writeAll("zig_shr_");
3955 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
3956 try bw.writeByte('(');
3957 try f.writeCValueDeref(bw, operand);
3958 try v.elem(f, bw);
3959 try bw.print(", {f})", .{try f.fmtIntLiteral(bit_offset_val)});
3960 if (cant_cast) try bw.writeByte(')');
3961 try f.object.dg.renderBuiltinInfo(bw, field_ty, .bits);
3962 try bw.writeByte(')');
39523963 } else {
3953 try f.writeCValue(writer, local, .Other);
3954 try v.elem(f, writer);
3955 try writer.writeAll(" = ");
3956 try f.writeCValueDeref(writer, operand);
3957 try v.elem(f, writer);
3964 try f.writeCValue(bw, local, .Other);
3965 try v.elem(f, bw);
3966 try bw.writeAll(" = ");
3967 try f.writeCValueDeref(bw, operand);
3968 try v.elem(f, bw);
39583969 }
3959 try writer.writeAll(";\n");
3960 try v.end(f, inst, writer);
3970 try bw.writeByte(';');
3971 try f.object.newline();
3972 try v.end(f, inst, bw);
39613973
39623974 return local;
39633975}
......@@ -3966,7 +3978,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
39663978 const pt = f.object.dg.pt;
39673979 const zcu = pt.zcu;
39683980 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3969 const writer = f.object.writer();
3981 const bw = &f.object.code.buffered_writer;
39703982 const op_inst = un_op.toIndex();
39713983 const op_ty = f.typeOf(un_op);
39723984 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;
......@@ -3985,33 +3997,38 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
39853997 .ctype = ret_ctype,
39863998 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
39873999 });
3988 try writer.writeAll("memcpy(");
3989 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
3990 try writer.writeAll(", ");
4000 try bw.writeAll("memcpy(");
4001 try f.writeCValueMember(bw, array_local, .{ .identifier = "array" });
4002 try bw.writeAll(", ");
39914003 if (deref)
3992 try f.writeCValueDeref(writer, operand)
4004 try f.writeCValueDeref(bw, operand)
39934005 else
3994 try f.writeCValue(writer, operand, .FunctionArgument);
4006 try f.writeCValue(bw, operand, .FunctionArgument);
39954007 deref = false;
3996 try writer.writeAll(", sizeof(");
3997 try f.renderType(writer, ret_ty);
3998 try writer.writeAll("));\n");
4008 try bw.writeAll(", sizeof(");
4009 try f.renderType(bw, ret_ty);
4010 try bw.writeAll("));");
4011 try f.object.newline();
39994012 break :ret_val array_local;
40004013 } else operand;
40014014
4002 try writer.writeAll("return ");
4015 try bw.writeAll("return ");
40034016 if (deref)
4004 try f.writeCValueDeref(writer, ret_val)
4017 try f.writeCValueDeref(bw, ret_val)
40054018 else
4006 try f.writeCValue(writer, ret_val, .Other);
4007 try writer.writeAll(";\n");
4019 try f.writeCValue(bw, ret_val, .Other);
4020 try bw.writeByte(';');
4021 try f.object.newline();
40084022 if (is_array) {
40094023 try freeLocal(f, inst, ret_val.new_local, null);
40104024 }
40114025 } else {
40124026 try reap(f, inst, &.{un_op});
40134027 // Not even allowed to return void in a naked function.
4014 if (!f.object.dg.is_naked_fn) try writer.writeAll("return;\n");
4028 if (!f.object.dg.is_naked_fn) {
4029 try bw.writeAll("return;");
4030 try f.object.newline();
4031 }
40154032 }
40164033}
40174034
......@@ -4030,16 +4047,16 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
40304047
40314048 if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);
40324049
4033 const writer = f.object.writer();
4050 const bw = &f.object.code.buffered_writer;
40344051 const local = try f.allocLocal(inst, inst_ty);
4035 const v = try Vectorize.start(f, inst, writer, operand_ty);
4036 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
4037 try f.writeCValue(writer, local, .Other);
4038 try v.elem(f, writer);
4039 try a.assign(f, writer);
4040 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);
4041 try a.end(f, writer);
4042 try v.end(f, inst, writer);
4052 const v = try Vectorize.start(f, inst, bw, operand_ty);
4053 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
4054 try f.writeCValue(bw, local, .Other);
4055 try v.elem(f, bw);
4056 try a.assign(f, bw);
4057 try f.renderIntCast(bw, inst_scalar_ty, operand, v, scalar_ty, .Other);
4058 try a.end(f, bw);
4059 try v.end(f, inst, bw);
40434060 return local;
40444061}
40454062
......@@ -4066,34 +4083,34 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
40664083 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
40674084 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
40684085
4069 const writer = f.object.writer();
4086 const bw = &f.object.code.buffered_writer;
40704087 const local = try f.allocLocal(inst, inst_ty);
4071 const v = try Vectorize.start(f, inst, writer, operand_ty);
4072 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));
4073 try f.writeCValue(writer, local, .Other);
4074 try v.elem(f, writer);
4075 try a.assign(f, writer);
4088 const v = try Vectorize.start(f, inst, bw, operand_ty);
4089 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_scalar_ty, .complete));
4090 try f.writeCValue(bw, local, .Other);
4091 try v.elem(f, bw);
4092 try a.assign(f, bw);
40764093 if (need_cast) {
4077 try writer.writeByte('(');
4078 try f.renderType(writer, inst_scalar_ty);
4079 try writer.writeByte(')');
4094 try bw.writeByte('(');
4095 try f.renderType(bw, inst_scalar_ty);
4096 try bw.writeByte(')');
40804097 }
40814098 if (need_lo) {
4082 try writer.writeAll("zig_lo_");
4083 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
4084 try writer.writeByte('(');
4099 try bw.writeAll("zig_lo_");
4100 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4101 try bw.writeByte('(');
40854102 }
40864103 if (!need_mask) {
4087 try f.writeCValue(writer, operand, .Other);
4088 try v.elem(f, writer);
4104 try f.writeCValue(bw, operand, .Other);
4105 try v.elem(f, bw);
40894106 } else switch (dest_int_info.signedness) {
40904107 .unsigned => {
4091 try writer.writeAll("zig_and_");
4092 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
4093 try writer.writeByte('(');
4094 try f.writeCValue(writer, operand, .FunctionArgument);
4095 try v.elem(f, writer);
4096 try writer.print(", {x})", .{
4108 try bw.writeAll("zig_and_");
4109 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4110 try bw.writeByte('(');
4111 try f.writeCValue(bw, operand, .FunctionArgument);
4112 try v.elem(f, bw);
4113 try bw.print(", {fx})", .{
40974114 try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
40984115 });
40994116 },
......@@ -4102,30 +4119,30 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
41024119 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
41034120 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
41044121
4105 try writer.writeAll("zig_shr_");
4106 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
4122 try bw.writeAll("zig_shr_");
4123 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
41074124 if (c_bits == 128) {
4108 try writer.print("(zig_bitCast_i{d}(", .{c_bits});
4125 try bw.print("(zig_bitCast_i{d}(", .{c_bits});
41094126 } else {
4110 try writer.print("((int{d}_t)", .{c_bits});
4127 try bw.print("((int{d}_t)", .{c_bits});
41114128 }
4112 try writer.print("zig_shl_u{d}(", .{c_bits});
4129 try bw.print("zig_shl_u{d}(", .{c_bits});
41134130 if (c_bits == 128) {
4114 try writer.print("zig_bitCast_u{d}(", .{c_bits});
4131 try bw.print("zig_bitCast_u{d}(", .{c_bits});
41154132 } else {
4116 try writer.print("(uint{d}_t)", .{c_bits});
4133 try bw.print("(uint{d}_t)", .{c_bits});
41174134 }
4118 try f.writeCValue(writer, operand, .FunctionArgument);
4119 try v.elem(f, writer);
4120 if (c_bits == 128) try writer.writeByte(')');
4121 try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});
4122 if (c_bits == 128) try writer.writeByte(')');
4123 try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});
4135 try f.writeCValue(bw, operand, .FunctionArgument);
4136 try v.elem(f, bw);
4137 if (c_bits == 128) try bw.writeByte(')');
4138 try bw.print(", {f})", .{try f.fmtIntLiteral(shift_val)});
4139 if (c_bits == 128) try bw.writeByte(')');
4140 try bw.print(", {f})", .{try f.fmtIntLiteral(shift_val)});
41244141 },
41254142 }
4126 if (need_lo) try writer.writeByte(')');
4127 try a.end(f, writer);
4128 try v.end(f, inst, writer);
4143 if (need_lo) try bw.writeByte(')');
4144 try a.end(f, bw);
4145 try v.end(f, inst, bw);
41294146 return local;
41304147}
41314148
......@@ -4144,15 +4161,16 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41444161
41454162 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndefDeep(zcu) else false;
41464163
4164 const bw = &f.object.code.buffered_writer;
41474165 if (val_is_undef) {
41484166 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41494167 if (safety and ptr_info.packed_offset.host_size == 0) {
4150 const writer = f.object.writer();
4151 try writer.writeAll("memset(");
4152 try f.writeCValue(writer, ptr_val, .FunctionArgument);
4153 try writer.writeAll(", 0xaa, sizeof(");
4154 try f.renderType(writer, .fromInterned(ptr_info.child));
4155 try writer.writeAll("));\n");
4168 try bw.writeAll("memset(");
4169 try f.writeCValue(bw, ptr_val, .FunctionArgument);
4170 try bw.writeAll(", 0xaa, sizeof(");
4171 try f.renderType(bw, .fromInterned(ptr_info.child));
4172 try bw.writeAll("));");
4173 try f.object.newline();
41564174 }
41574175 return .none;
41584176 }
......@@ -4168,7 +4186,6 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41684186 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41694187
41704188 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);
4171 const writer = f.object.writer();
41724189 if (need_memcpy) {
41734190 // For this memcpy to safely work we need the rhs to have the same
41744191 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
......@@ -4179,28 +4196,30 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41794196 // TODO this should be done by manually initializing elements of the dest array
41804197 const array_src = if (src_val == .constant) blk: {
41814198 const new_local = try f.allocLocal(inst, src_ty);
4182 try f.writeCValue(writer, new_local, .Other);
4183 try writer.writeAll(" = ");
4184 try f.writeCValue(writer, src_val, .Other);
4185 try writer.writeAll(";\n");
4199 try f.writeCValue(bw, new_local, .Other);
4200 try bw.writeAll(" = ");
4201 try f.writeCValue(bw, src_val, .Other);
4202 try bw.writeByte(';');
4203 try f.object.newline();
41864204
41874205 break :blk new_local;
41884206 } else src_val;
41894207
4190 const v = try Vectorize.start(f, inst, writer, ptr_ty);
4191 try writer.writeAll("memcpy((char *)");
4192 try f.writeCValue(writer, ptr_val, .FunctionArgument);
4193 try v.elem(f, writer);
4194 try writer.writeAll(", ");
4195 if (!is_array) try writer.writeByte('&');
4196 try f.writeCValue(writer, array_src, .FunctionArgument);
4197 try v.elem(f, writer);
4198 try writer.writeAll(", sizeof(");
4199 try f.renderType(writer, src_ty);
4200 try writer.writeAll("))");
4208 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4209 try bw.writeAll("memcpy((char *)");
4210 try f.writeCValue(bw, ptr_val, .FunctionArgument);
4211 try v.elem(f, bw);
4212 try bw.writeAll(", ");
4213 if (!is_array) try bw.writeByte('&');
4214 try f.writeCValue(bw, array_src, .FunctionArgument);
4215 try v.elem(f, bw);
4216 try bw.writeAll(", sizeof(");
4217 try f.renderType(bw, src_ty);
4218 try bw.writeAll("))");
42014219 try f.freeCValue(inst, array_src);
4202 try writer.writeAll(";\n");
4203 try v.end(f, inst, writer);
4220 try bw.writeByte(';');
4221 try f.object.newline();
4222 try v.end(f, inst, bw);
42044223 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
42054224 const host_bits = ptr_info.packed_offset.host_size * 8;
42064225 const host_ty = try pt.intType(.unsigned, host_bits);
......@@ -4223,44 +4242,44 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
42234242
42244243 const mask_val = try pt.intValue_big(host_ty, mask.toConst());
42254244
4226 const v = try Vectorize.start(f, inst, writer, ptr_ty);
4227 const a = try Assignment.start(f, writer, src_scalar_ctype);
4228 try f.writeCValueDeref(writer, ptr_val);
4229 try v.elem(f, writer);
4230 try a.assign(f, writer);
4231 try writer.writeAll("zig_or_");
4232 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
4233 try writer.writeAll("(zig_and_");
4234 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
4235 try writer.writeByte('(');
4236 try f.writeCValueDeref(writer, ptr_val);
4237 try v.elem(f, writer);
4238 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});
4239 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
4240 try writer.writeByte('(');
4245 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4246 const a = try Assignment.start(f, bw, src_scalar_ctype);
4247 try f.writeCValueDeref(bw, ptr_val);
4248 try v.elem(f, bw);
4249 try a.assign(f, bw);
4250 try bw.writeAll("zig_or_");
4251 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4252 try bw.writeAll("(zig_and_");
4253 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4254 try bw.writeByte('(');
4255 try f.writeCValueDeref(bw, ptr_val);
4256 try v.elem(f, bw);
4257 try bw.print(", {fx}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});
4258 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4259 try bw.writeByte('(');
42414260 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
42424261 if (cant_cast) {
42434262 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
4244 try writer.writeAll("zig_make_");
4245 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);
4246 try writer.writeAll("(0, ");
4263 try bw.writeAll("zig_make_");
4264 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4265 try bw.writeAll("(0, ");
42474266 } else {
4248 try writer.writeByte('(');
4249 try f.renderType(writer, host_ty);
4250 try writer.writeByte(')');
4267 try bw.writeByte('(');
4268 try f.renderType(bw, host_ty);
4269 try bw.writeByte(')');
42514270 }
42524271
42534272 if (src_ty.isPtrAtRuntime(zcu)) {
4254 try writer.writeByte('(');
4255 try f.renderType(writer, .usize);
4256 try writer.writeByte(')');
4273 try bw.writeByte('(');
4274 try f.renderType(bw, .usize);
4275 try bw.writeByte(')');
42574276 }
4258 try f.writeCValue(writer, src_val, .Other);
4259 try v.elem(f, writer);
4260 if (cant_cast) try writer.writeByte(')');
4261 try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_val)});
4262 try a.end(f, writer);
4263 try v.end(f, inst, writer);
4277 try f.writeCValue(bw, src_val, .Other);
4278 try v.elem(f, bw);
4279 if (cant_cast) try bw.writeByte(')');
4280 try bw.print(", {f}))", .{try f.fmtIntLiteral(bit_offset_val)});
4281 try a.end(f, bw);
4282 try v.end(f, inst, bw);
42644283 } else {
42654284 switch (ptr_val) {
42664285 .local_ref => |ptr_local_index| switch (src_val) {
......@@ -4270,15 +4289,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
42704289 },
42714290 else => {},
42724291 }
4273 const v = try Vectorize.start(f, inst, writer, ptr_ty);
4274 const a = try Assignment.start(f, writer, src_scalar_ctype);
4275 try f.writeCValueDeref(writer, ptr_val);
4276 try v.elem(f, writer);
4277 try a.assign(f, writer);
4278 try f.writeCValue(writer, src_val, .Other);
4279 try v.elem(f, writer);
4280 try a.end(f, writer);
4281 try v.end(f, inst, writer);
4292 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4293 const a = try Assignment.start(f, bw, src_scalar_ctype);
4294 try f.writeCValueDeref(bw, ptr_val);
4295 try v.elem(f, bw);
4296 try a.assign(f, bw);
4297 try f.writeCValue(bw, src_val, .Other);
4298 try v.elem(f, bw);
4299 try a.end(f, bw);
4300 try v.end(f, inst, bw);
42824301 }
42834302 return .none;
42844303}
......@@ -4297,27 +4316,27 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
42974316 const operand_ty = f.typeOf(bin_op.lhs);
42984317 const scalar_ty = operand_ty.scalarType(zcu);
42994318
4300 const w = f.object.writer();
4319 const bw = &f.object.code.buffered_writer;
43014320 const local = try f.allocLocal(inst, inst_ty);
4302 const v = try Vectorize.start(f, inst, w, operand_ty);
4303 try f.writeCValueMember(w, local, .{ .field = 1 });
4304 try v.elem(f, w);
4305 try w.writeAll(" = zig_");
4306 try w.writeAll(operation);
4307 try w.writeAll("o_");
4308 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4309 try w.writeAll("(&");
4310 try f.writeCValueMember(w, local, .{ .field = 0 });
4311 try v.elem(f, w);
4312 try w.writeAll(", ");
4313 try f.writeCValue(w, lhs, .FunctionArgument);
4314 try v.elem(f, w);
4315 try w.writeAll(", ");
4316 try f.writeCValue(w, rhs, .FunctionArgument);
4317 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
4318 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
4319 try w.writeAll(");\n");
4320 try v.end(f, inst, w);
4321 const v = try Vectorize.start(f, inst, bw, operand_ty);
4322 try f.writeCValueMember(bw, local, .{ .field = 1 });
4323 try v.elem(f, bw);
4324 try bw.writeAll(" = zig_");
4325 try bw.writeAll(operation);
4326 try bw.writeAll("o_");
4327 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4328 try bw.writeAll("(&");
4329 try f.writeCValueMember(bw, local, .{ .field = 0 });
4330 try v.elem(f, bw);
4331 try bw.writeAll(", ");
4332 try f.writeCValue(bw, lhs, .FunctionArgument);
4333 try v.elem(f, bw);
4334 try bw.writeAll(", ");
4335 try f.writeCValue(bw, rhs, .FunctionArgument);
4336 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, bw);
4337 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
4338 try bw.writeAll(");\n");
4339 try v.end(f, inst, bw);
43214340
43224341 return local;
43234342}
......@@ -4335,17 +4354,18 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
43354354
43364355 const inst_ty = f.typeOfIndex(inst);
43374356
4338 const writer = f.object.writer();
4357 const bw = &f.object.code.buffered_writer;
43394358 const local = try f.allocLocal(inst, inst_ty);
4340 const v = try Vectorize.start(f, inst, writer, operand_ty);
4341 try f.writeCValue(writer, local, .Other);
4342 try v.elem(f, writer);
4343 try writer.writeAll(" = ");
4344 try writer.writeByte('!');
4345 try f.writeCValue(writer, op, .Other);
4346 try v.elem(f, writer);
4347 try writer.writeAll(";\n");
4348 try v.end(f, inst, writer);
4359 const v = try Vectorize.start(f, inst, bw, operand_ty);
4360 try f.writeCValue(bw, local, .Other);
4361 try v.elem(f, bw);
4362 try bw.writeAll(" = ");
4363 try bw.writeByte('!');
4364 try f.writeCValue(bw, op, .Other);
4365 try v.elem(f, bw);
4366 try bw.writeByte(';');
4367 try f.object.newline();
4368 try v.end(f, inst, bw);
43494369
43504370 return local;
43514371}
......@@ -4371,21 +4391,22 @@ fn airBinOp(
43714391
43724392 const inst_ty = f.typeOfIndex(inst);
43734393
4374 const writer = f.object.writer();
4394 const bw = &f.object.code.buffered_writer;
43754395 const local = try f.allocLocal(inst, inst_ty);
4376 const v = try Vectorize.start(f, inst, writer, operand_ty);
4377 try f.writeCValue(writer, local, .Other);
4378 try v.elem(f, writer);
4379 try writer.writeAll(" = ");
4380 try f.writeCValue(writer, lhs, .Other);
4381 try v.elem(f, writer);
4382 try writer.writeByte(' ');
4383 try writer.writeAll(operator);
4384 try writer.writeByte(' ');
4385 try f.writeCValue(writer, rhs, .Other);
4386 try v.elem(f, writer);
4387 try writer.writeAll(";\n");
4388 try v.end(f, inst, writer);
4396 const v = try Vectorize.start(f, inst, bw, operand_ty);
4397 try f.writeCValue(bw, local, .Other);
4398 try v.elem(f, bw);
4399 try bw.writeAll(" = ");
4400 try f.writeCValue(bw, lhs, .Other);
4401 try v.elem(f, bw);
4402 try bw.writeByte(' ');
4403 try bw.writeAll(operator);
4404 try bw.writeByte(' ');
4405 try f.writeCValue(bw, rhs, .Other);
4406 try v.elem(f, bw);
4407 try bw.writeByte(';');
4408 try f.object.newline();
4409 try v.end(f, inst, bw);
43894410
43904411 return local;
43914412}
......@@ -4421,27 +4442,27 @@ fn airCmpOp(
44214442
44224443 const rhs_ty = f.typeOf(data.rhs);
44234444 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);
4424 const writer = f.object.writer();
4445 const bw = &f.object.code.buffered_writer;
44254446 const local = try f.allocLocal(inst, inst_ty);
4426 const v = try Vectorize.start(f, inst, writer, lhs_ty);
4427 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
4428 try f.writeCValue(writer, local, .Other);
4429 try v.elem(f, writer);
4430 try a.assign(f, writer);
4431 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
4447 const v = try Vectorize.start(f, inst, bw, lhs_ty);
4448 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
4449 try f.writeCValue(bw, local, .Other);
4450 try v.elem(f, bw);
4451 try a.assign(f, bw);
4452 if (lhs != .undef and lhs.eql(rhs)) try bw.writeAll(switch (operator) {
44324453 .lt, .neq, .gt => "false",
44334454 .lte, .eq, .gte => "true",
44344455 }) else {
4435 if (need_cast) try writer.writeAll("(void*)");
4436 try f.writeCValue(writer, lhs, .Other);
4437 try v.elem(f, writer);
4438 try writer.writeAll(compareOperatorC(operator));
4439 if (need_cast) try writer.writeAll("(void*)");
4440 try f.writeCValue(writer, rhs, .Other);
4441 try v.elem(f, writer);
4456 if (need_cast) try bw.writeAll("(void*)");
4457 try f.writeCValue(bw, lhs, .Other);
4458 try v.elem(f, bw);
4459 try bw.writeAll(compareOperatorC(operator));
4460 if (need_cast) try bw.writeAll("(void*)");
4461 try f.writeCValue(bw, rhs, .Other);
4462 try v.elem(f, bw);
44424463 }
4443 try a.end(f, writer);
4444 try v.end(f, inst, writer);
4464 try a.end(f, bw);
4465 try v.end(f, inst, bw);
44454466
44464467 return local;
44474468}
......@@ -4474,41 +4495,41 @@ fn airEquality(
44744495 const rhs = try f.resolveInst(bin_op.rhs);
44754496 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
44764497
4477 const writer = f.object.writer();
4498 const bw = &f.object.code.buffered_writer;
44784499 const local = try f.allocLocal(inst, .bool);
4479 const a = try Assignment.start(f, writer, .bool);
4480 try f.writeCValue(writer, local, .Other);
4481 try a.assign(f, writer);
4500 const a = try Assignment.start(f, bw, .bool);
4501 try f.writeCValue(bw, local, .Other);
4502 try a.assign(f, bw);
44824503
44834504 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
4484 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {
4505 if (lhs != .undef and lhs.eql(rhs)) try bw.writeAll(switch (operator) {
44854506 .lt, .lte, .gte, .gt => unreachable,
44864507 .neq => "false",
44874508 .eq => "true",
44884509 }) else switch (operand_ctype.info(ctype_pool)) {
44894510 .basic, .pointer => {
4490 try f.writeCValue(writer, lhs, .Other);
4491 try writer.writeAll(compareOperatorC(operator));
4492 try f.writeCValue(writer, rhs, .Other);
4511 try f.writeCValue(bw, lhs, .Other);
4512 try bw.writeAll(compareOperatorC(operator));
4513 try f.writeCValue(bw, rhs, .Other);
44934514 },
44944515 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
44954516 .aggregate => |aggregate| if (aggregate.fields.len == 2 and
44964517 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
44974518 aggregate.fields.at(1, ctype_pool).name.index == .is_null))
44984519 {
4499 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
4500 try writer.writeAll(" || ");
4501 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
4502 try writer.writeAll(" ? ");
4503 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
4504 try writer.writeAll(compareOperatorC(operator));
4505 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });
4506 try writer.writeAll(" : ");
4507 try f.writeCValueMember(writer, lhs, .{ .identifier = "payload" });
4508 try writer.writeAll(compareOperatorC(operator));
4509 try f.writeCValueMember(writer, rhs, .{ .identifier = "payload" });
4520 try f.writeCValueMember(bw, lhs, .{ .identifier = "is_null" });
4521 try bw.writeAll(" || ");
4522 try f.writeCValueMember(bw, rhs, .{ .identifier = "is_null" });
4523 try bw.writeAll(" ? ");
4524 try f.writeCValueMember(bw, lhs, .{ .identifier = "is_null" });
4525 try bw.writeAll(compareOperatorC(operator));
4526 try f.writeCValueMember(bw, rhs, .{ .identifier = "is_null" });
4527 try bw.writeAll(" : ");
4528 try f.writeCValueMember(bw, lhs, .{ .identifier = "payload" });
4529 try bw.writeAll(compareOperatorC(operator));
4530 try f.writeCValueMember(bw, rhs, .{ .identifier = "payload" });
45104531 } else for (0..aggregate.fields.len) |field_index| {
4511 if (field_index > 0) try writer.writeAll(switch (operator) {
4532 if (field_index > 0) try bw.writeAll(switch (operator) {
45124533 .lt, .lte, .gte, .gt => unreachable,
45134534 .eq => " && ",
45144535 .neq => " || ",
......@@ -4516,12 +4537,12 @@ fn airEquality(
45164537 const field_name: CValue = .{
45174538 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,
45184539 };
4519 try f.writeCValueMember(writer, lhs, field_name);
4520 try writer.writeAll(compareOperatorC(operator));
4521 try f.writeCValueMember(writer, rhs, field_name);
4540 try f.writeCValueMember(bw, lhs, field_name);
4541 try bw.writeAll(compareOperatorC(operator));
4542 try f.writeCValueMember(bw, rhs, field_name);
45224543 },
45234544 }
4524 try a.end(f, writer);
4545 try a.end(f, bw);
45254546
45264547 return local;
45274548}
......@@ -4532,12 +4553,13 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
45324553 const operand = try f.resolveInst(un_op);
45334554 try reap(f, inst, &.{un_op});
45344555
4535 const writer = f.object.writer();
4556 const bw = &f.object.code.buffered_writer;
45364557 const local = try f.allocLocal(inst, .bool);
4537 try f.writeCValue(writer, local, .Other);
4538 try writer.writeAll(" = ");
4539 try f.writeCValue(writer, operand, .Other);
4540 try writer.print(" < sizeof({ }) / sizeof(*{0 });\n", .{fmtIdent("zig_errorName")});
4558 try f.writeCValue(bw, local, .Other);
4559 try bw.writeAll(" = ");
4560 try f.writeCValue(bw, operand, .Other);
4561 try bw.print(" < sizeof({f }) / sizeof(*{0f });", .{fmtIdent("zig_errorName")});
4562 try f.object.newline();
45414563 return local;
45424564}
45434565
......@@ -4558,30 +4580,30 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
45584580 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
45594581
45604582 const local = try f.allocLocal(inst, inst_ty);
4561 const writer = f.object.writer();
4562 const v = try Vectorize.start(f, inst, writer, inst_ty);
4563 const a = try Assignment.start(f, writer, inst_scalar_ctype);
4564 try f.writeCValue(writer, local, .Other);
4565 try v.elem(f, writer);
4566 try a.assign(f, writer);
4583 const bw = &f.object.code.buffered_writer;
4584 const v = try Vectorize.start(f, inst, bw, inst_ty);
4585 const a = try Assignment.start(f, bw, inst_scalar_ctype);
4586 try f.writeCValue(bw, local, .Other);
4587 try v.elem(f, bw);
4588 try a.assign(f, bw);
45674589 // We must convert to and from integer types to prevent UB if the operation
45684590 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
45694591 // if the result is NULL and then dereferenced.
4570 try writer.writeByte('(');
4571 try f.renderCType(writer, inst_scalar_ctype);
4572 try writer.writeAll(")(((uintptr_t)");
4573 try f.writeCValue(writer, lhs, .Other);
4574 try v.elem(f, writer);
4575 try writer.writeAll(") ");
4576 try writer.writeByte(operator);
4577 try writer.writeAll(" (");
4578 try f.writeCValue(writer, rhs, .Other);
4579 try v.elem(f, writer);
4580 try writer.writeAll("*sizeof(");
4581 try f.renderType(writer, elem_ty);
4582 try writer.writeAll(")))");
4583 try a.end(f, writer);
4584 try v.end(f, inst, writer);
4592 try bw.writeByte('(');
4593 try f.renderCType(bw, inst_scalar_ctype);
4594 try bw.writeAll(")(((uintptr_t)");
4595 try f.writeCValue(bw, lhs, .Other);
4596 try v.elem(f, bw);
4597 try bw.writeAll(") ");
4598 try bw.writeByte(operator);
4599 try bw.writeAll(" (");
4600 try f.writeCValue(bw, rhs, .Other);
4601 try v.elem(f, bw);
4602 try bw.writeAll("*sizeof(");
4603 try f.renderType(bw, elem_ty);
4604 try bw.writeAll(")))");
4605 try a.end(f, bw);
4606 try v.end(f, inst, bw);
45854607 return local;
45864608}
45874609
......@@ -4600,28 +4622,29 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
46004622 const rhs = try f.resolveInst(bin_op.rhs);
46014623 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
46024624
4603 const writer = f.object.writer();
4625 const bw = &f.object.code.buffered_writer;
46044626 const local = try f.allocLocal(inst, inst_ty);
4605 const v = try Vectorize.start(f, inst, writer, inst_ty);
4606 try f.writeCValue(writer, local, .Other);
4607 try v.elem(f, writer);
4627 const v = try Vectorize.start(f, inst, bw, inst_ty);
4628 try f.writeCValue(bw, local, .Other);
4629 try v.elem(f, bw);
46084630 // (lhs <> rhs) ? lhs : rhs
4609 try writer.writeAll(" = (");
4610 try f.writeCValue(writer, lhs, .Other);
4611 try v.elem(f, writer);
4612 try writer.writeByte(' ');
4613 try writer.writeByte(operator);
4614 try writer.writeByte(' ');
4615 try f.writeCValue(writer, rhs, .Other);
4616 try v.elem(f, writer);
4617 try writer.writeAll(") ? ");
4618 try f.writeCValue(writer, lhs, .Other);
4619 try v.elem(f, writer);
4620 try writer.writeAll(" : ");
4621 try f.writeCValue(writer, rhs, .Other);
4622 try v.elem(f, writer);
4623 try writer.writeAll(";\n");
4624 try v.end(f, inst, writer);
4631 try bw.writeAll(" = (");
4632 try f.writeCValue(bw, lhs, .Other);
4633 try v.elem(f, bw);
4634 try bw.writeByte(' ');
4635 try bw.writeByte(operator);
4636 try bw.writeByte(' ');
4637 try f.writeCValue(bw, rhs, .Other);
4638 try v.elem(f, bw);
4639 try bw.writeAll(") ? ");
4640 try f.writeCValue(bw, lhs, .Other);
4641 try v.elem(f, bw);
4642 try bw.writeAll(" : ");
4643 try f.writeCValue(bw, rhs, .Other);
4644 try v.elem(f, bw);
4645 try bw.writeByte(';');
4646 try f.object.newline();
4647 try v.end(f, inst, bw);
46254648
46264649 return local;
46274650}
......@@ -4639,21 +4662,21 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
46394662 const inst_ty = f.typeOfIndex(inst);
46404663 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
46414664
4642 const writer = f.object.writer();
4665 const bw = &f.object.code.buffered_writer;
46434666 const local = try f.allocLocal(inst, inst_ty);
46444667 {
4645 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));
4646 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
4647 try a.assign(f, writer);
4648 try f.writeCValue(writer, ptr, .Other);
4649 try a.end(f, writer);
4668 const a = try Assignment.start(f, bw, try f.ctypeFromType(ptr_ty, .complete));
4669 try f.writeCValueMember(bw, local, .{ .identifier = "ptr" });
4670 try a.assign(f, bw);
4671 try f.writeCValue(bw, ptr, .Other);
4672 try a.end(f, bw);
46504673 }
46514674 {
4652 const a = try Assignment.start(f, writer, .usize);
4653 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
4654 try a.assign(f, writer);
4655 try f.writeCValue(writer, len, .Other);
4656 try a.end(f, writer);
4675 const a = try Assignment.start(f, bw, .usize);
4676 try f.writeCValueMember(bw, local, .{ .identifier = "len" });
4677 try a.assign(f, bw);
4678 try f.writeCValue(bw, len, .Other);
4679 try a.end(f, bw);
46574680 }
46584681 return local;
46594682}
......@@ -4670,7 +4693,7 @@ fn airCall(
46704693 if (f.object.dg.is_naked_fn) return .none;
46714694
46724695 const gpa = f.object.dg.gpa;
4673 const writer = f.object.writer();
4696 const bw = &f.object.code.buffered_writer;
46744697
46754698 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
46764699 const extra = f.air.extraData(Air.Call, pl_op.payload);
......@@ -4691,13 +4714,14 @@ fn airCall(
46914714 .ctype = arg_ctype,
46924715 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),
46934716 });
4694 try writer.writeAll("memcpy(");
4695 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });
4696 try writer.writeAll(", ");
4697 try f.writeCValue(writer, resolved_arg.*, .FunctionArgument);
4698 try writer.writeAll(", sizeof(");
4699 try f.renderCType(writer, arg_ctype);
4700 try writer.writeAll("));\n");
4717 try bw.writeAll("memcpy(");
4718 try f.writeCValueMember(bw, array_local, .{ .identifier = "array" });
4719 try bw.writeAll(", ");
4720 try f.writeCValue(bw, resolved_arg.*, .FunctionArgument);
4721 try bw.writeAll(", sizeof(");
4722 try f.renderCType(bw, arg_ctype);
4723 try bw.writeAll("));");
4724 try f.object.newline();
47014725 resolved_arg.* = array_local;
47024726 }
47034727 }
......@@ -4725,22 +4749,22 @@ fn airCall(
47254749
47264750 const result_local = result: {
47274751 if (modifier == .always_tail) {
4728 try writer.writeAll("zig_always_tail return ");
4752 try bw.writeAll("zig_always_tail return ");
47294753 break :result .none;
47304754 } else if (ret_ctype.index == .void) {
47314755 break :result .none;
47324756 } else if (f.liveness.isUnused(inst)) {
4733 try writer.writeByte('(');
4734 try f.renderCType(writer, .void);
4735 try writer.writeByte(')');
4757 try bw.writeByte('(');
4758 try f.renderCType(bw, .void);
4759 try bw.writeByte(')');
47364760 break :result .none;
47374761 } else {
47384762 const local = try f.allocAlignedLocal(inst, .{
47394763 .ctype = ret_ctype,
47404764 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
47414765 });
4742 try f.writeCValue(writer, local, .Other);
4743 try writer.writeAll(" = ");
4766 try f.writeCValue(bw, local, .Other);
4767 try bw.writeAll(" = ");
47444768 break :result local;
47454769 }
47464770 };
......@@ -4760,17 +4784,17 @@ fn airCall(
47604784 else => break :known,
47614785 };
47624786 if (need_cast) {
4763 try writer.writeAll("((");
4764 try f.renderType(writer, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));
4765 try writer.writeByte(')');
4766 if (!callee_is_ptr) try writer.writeByte('&');
4787 try bw.writeAll("((");
4788 try f.renderType(bw, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));
4789 try bw.writeByte(')');
4790 if (!callee_is_ptr) try bw.writeByte('&');
47674791 }
47684792 switch (modifier) {
4769 .auto, .always_tail => try f.object.dg.renderNavName(writer, fn_nav),
4770 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
4793 .auto, .always_tail => try f.object.dg.renderNavName(bw, fn_nav),
4794 inline .never_tail, .never_inline => |m| try bw.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
47714795 else => unreachable,
47724796 }
4773 if (need_cast) try writer.writeByte(')');
4797 if (need_cast) try bw.writeByte(')');
47744798 break :callee;
47754799 }
47764800 switch (modifier) {
......@@ -4780,32 +4804,34 @@ fn airCall(
47804804 else => unreachable,
47814805 }
47824806 // Fall back to function pointer call.
4783 try f.writeCValue(writer, callee, .Other);
4807 try f.writeCValue(bw, callee, .Other);
47844808 }
47854809
4786 try writer.writeByte('(');
4810 try bw.writeByte('(');
47874811 var need_comma = false;
47884812 for (resolved_args) |resolved_arg| {
47894813 if (resolved_arg == .none) continue;
4790 if (need_comma) try writer.writeAll(", ");
4814 if (need_comma) try bw.writeAll(", ");
47914815 need_comma = true;
4792 try f.writeCValue(writer, resolved_arg, .FunctionArgument);
4816 try f.writeCValue(bw, resolved_arg, .FunctionArgument);
47934817 try f.freeCValue(inst, resolved_arg);
47944818 }
4795 try writer.writeAll(");\n");
4819 try bw.writeAll(");");
4820 try f.object.newline();
47964821
47974822 const result = result: {
47984823 if (result_local == .none or !lowersToArray(ret_ty, pt))
47994824 break :result result_local;
48004825
48014826 const array_local = try f.allocLocal(inst, ret_ty);
4802 try writer.writeAll("memcpy(");
4803 try f.writeCValue(writer, array_local, .FunctionArgument);
4804 try writer.writeAll(", ");
4805 try f.writeCValueMember(writer, result_local, .{ .identifier = "array" });
4806 try writer.writeAll(", sizeof(");
4807 try f.renderType(writer, ret_ty);
4808 try writer.writeAll("));\n");
4827 try bw.writeAll("memcpy(");
4828 try f.writeCValue(bw, array_local, .FunctionArgument);
4829 try bw.writeAll(", ");
4830 try f.writeCValueMember(bw, result_local, .{ .identifier = "array" });
4831 try bw.writeAll(", sizeof(");
4832 try f.renderType(bw, ret_ty);
4833 try bw.writeAll("));");
4834 try f.object.newline();
48094835 try freeLocal(f, inst, result_local.new_local, null);
48104836 break :result array_local;
48114837 };
......@@ -4815,7 +4841,7 @@ fn airCall(
48154841
48164842fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
48174843 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
4818 const writer = f.object.writer();
4844 const bw = &f.object.code.buffered_writer;
48194845 // TODO re-evaluate whether to emit these or not. If we naively emit
48204846 // these directives, the output file will report bogus line numbers because
48214847 // every newline after the #line directive adds one to the line.
......@@ -4823,13 +4849,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
48234849 // If we wanted to go this route, we would need to go all the way and not output
48244850 // newlines until the next dbg_stmt occurs.
48254851 // Perhaps an additional compilation option is in order?
4826 //try writer.print("#line {d}\n", .{dbg_stmt.line + 1});
4827 try writer.print("/* file:{d}:{d} */\n", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4852 //try bw.print("#line {d}", .{dbg_stmt.line + 1});
4853 //try f.object.newline();
4854 try bw.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4855 try f.object.newline();
48284856 return .none;
48294857}
48304858
48314859fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {
4832 try f.object.writer().writeAll("(void)0;\n");
4860 try f.object.code.buffered_writer.writeAll("(void)0;");
4861 try f.object.newline();
48334862 return .none;
48344863}
48354864
......@@ -4841,7 +4870,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
48414870 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
48424871 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);
48434872 const writer = f.object.writer();
4844 try writer.print("/* inline:{} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
4873 try writer.print("/* inline:{f} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
48454874 return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]));
48464875}
48474876
......@@ -4855,8 +4884,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
48554884 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
48564885
48574886 try reap(f, inst, &.{pl_op.operand});
4858 const writer = f.object.writer();
4859 try writer.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) });
4887 const bw = &f.object.code.buffered_writer;
4888 try bw.print("/* {s}:{s} */", .{ @tagName(tag), name.toSlice(f.air) });
4889 try f.object.newline();
48604890 return .none;
48614891}
48624892
......@@ -4873,7 +4903,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
48734903
48744904 const block_id = f.next_block_index;
48754905 f.next_block_index += 1;
4876 const writer = f.object.writer();
4906 const bw = &f.object.code.buffered_writer;
48774907
48784908 const inst_ty = f.typeOfIndex(inst);
48794909 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))
......@@ -4895,7 +4925,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
48954925 try die(f, inst, death.toRef());
48964926 }
48974927
4898 try f.object.indent_writer.insertNewline();
4928 try f.object.newline();
48994929
49004930 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
49014931 if (f.object.dg.is_naked_fn) {
......@@ -4906,7 +4936,8 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
49064936 }
49074937 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
49084938 // label must be followed by an expression, include an empty one.
4909 try writer.print("zig_block_{d}:;\n", .{block_id});
4939 try bw.print("zig_block_{d}:;", .{block_id});
4940 try f.object.newline();
49104941 }
49114942
49124943 return result;
......@@ -4943,31 +4974,31 @@ fn lowerTry(
49434974 const err_union = try f.resolveInst(operand);
49444975 const inst_ty = f.typeOfIndex(inst);
49454976 const liveness_condbr = f.liveness.getCondBr(inst);
4946 const writer = f.object.writer();
4977 const bw = &f.object.code.buffered_writer;
49474978 const payload_ty = err_union_ty.errorUnionPayload(zcu);
49484979 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
49494980
49504981 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4951 try writer.writeAll("if (");
4982 try bw.writeAll("if (");
49524983 if (!payload_has_bits) {
49534984 if (is_ptr)
4954 try f.writeCValueDeref(writer, err_union)
4985 try f.writeCValueDeref(bw, err_union)
49554986 else
4956 try f.writeCValue(writer, err_union, .Other);
4987 try f.writeCValue(bw, err_union, .Other);
49574988 } else {
49584989 // Reap the operand so that it can be reused inside genBody.
49594990 // Remember we must avoid calling reap() twice for the same operand
49604991 // in this function.
49614992 try reap(f, inst, &.{operand});
49624993 if (is_ptr)
4963 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })
4994 try f.writeCValueDerefMember(bw, err_union, .{ .identifier = "error" })
49644995 else
4965 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });
4996 try f.writeCValueMember(bw, err_union, .{ .identifier = "error" });
49664997 }
4967 try writer.writeAll(") ");
4998 try bw.writeAll(") ");
49684999
49695000 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);
4970 try f.object.indent_writer.insertNewline();
5001 try f.object.newline();
49715002 if (f.object.dg.expected_block) |_|
49725003 return f.fail("runtime code not allowed in naked function", .{});
49735004 }
......@@ -4990,14 +5021,14 @@ fn lowerTry(
49905021 if (f.liveness.isUnused(inst)) return .none;
49915022
49925023 const local = try f.allocLocal(inst, inst_ty);
4993 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
4994 try f.writeCValue(writer, local, .Other);
4995 try a.assign(f, writer);
5024 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
5025 try f.writeCValue(bw, local, .Other);
5026 try a.assign(f, bw);
49965027 if (is_ptr) {
4997 try writer.writeByte('&');
4998 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });
4999 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });
5000 try a.end(f, writer);
5028 try bw.writeByte('&');
5029 try f.writeCValueDerefMember(bw, err_union, .{ .identifier = "payload" });
5030 } else try f.writeCValueMember(bw, err_union, .{ .identifier = "payload" });
5031 try a.end(f, bw);
50015032 return local;
50025033}
50035034
......@@ -5005,7 +5036,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
50055036 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
50065037 const block = f.blocks.get(branch.block_inst).?;
50075038 const result = block.result;
5008 const writer = f.object.writer();
5039 const bw = &f.object.code.buffered_writer;
50095040
50105041 if (f.object.dg.is_naked_fn) {
50115042 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});
......@@ -5019,27 +5050,28 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
50195050 const operand = try f.resolveInst(branch.operand);
50205051 try reap(f, inst, &.{branch.operand});
50215052
5022 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));
5023 try f.writeCValue(writer, result, .Other);
5024 try a.assign(f, writer);
5025 try f.writeCValue(writer, operand, .Other);
5026 try a.end(f, writer);
5053 const a = try Assignment.start(f, bw, try f.ctypeFromType(operand_ty, .complete));
5054 try f.writeCValue(bw, result, .Other);
5055 try a.assign(f, bw);
5056 try f.writeCValue(bw, operand, .Other);
5057 try a.end(f, bw);
50275058 }
50285059
5029 try writer.print("goto zig_block_{d};\n", .{block.block_id});
5060 try bw.print("goto zig_block_{d};", .{block.block_id});
5061 try f.object.newline();
50305062}
50315063
50325064fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {
50335065 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
5034 const writer = f.object.writer();
5035 try writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});
5066 try f.object.code.buffered_writer.print("goto zig_loop_{d};", .{@intFromEnum(repeat.loop_inst)});
5067 try f.object.newline();
50365068}
50375069
50385070fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
50395071 const pt = f.object.dg.pt;
50405072 const zcu = pt.zcu;
50415073 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
5042 const writer = f.object.writer();
5074 const bw = &f.object.code.buffered_writer;
50435075
50445076 if (try f.air.value(br.operand, pt)) |cond_val| {
50455077 // Comptime-known dispatch. Iterate the cases to find the correct
......@@ -5061,18 +5093,20 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
50615093 }
50625094 }
50635095 } else switch_br.cases_len;
5064 try writer.print("goto zig_switch_{d}_dispatch_{d};\n", .{ @intFromEnum(br.block_inst), target_case_idx });
5096 try bw.print("goto zig_switch_{d}_dispatch_{d};", .{ @intFromEnum(br.block_inst), target_case_idx });
5097 try f.object.newline();
50655098 return;
50665099 }
50675100
50685101 // Runtime-known dispatch. Set the switch condition, and branch back.
50695102 const cond = try f.resolveInst(br.operand);
50705103 const cond_local = f.loop_switch_conds.get(br.block_inst).?;
5071 try f.writeCValue(writer, .{ .local = cond_local }, .Other);
5072 try writer.writeAll(" = ");
5073 try f.writeCValue(writer, cond, .Other);
5074 try writer.writeAll(";\n");
5075 try writer.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});
5104 try f.writeCValue(bw, .{ .local = cond_local }, .Other);
5105 try bw.writeAll(" = ");
5106 try f.writeCValue(bw, cond, .Other);
5107 try bw.writeByte(';');
5108 try f.object.newline();
5109 try bw.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});
50765110}
50775111
50785112fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
......@@ -5092,7 +5126,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
50925126 const zcu = pt.zcu;
50935127 const target = &f.object.dg.mod.resolved_target.result;
50945128 const ctype_pool = &f.object.dg.ctype_pool;
5095 const writer = f.object.writer();
5129 const bw = &f.object.code.buffered_writer;
50965130
50975131 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
50985132 const src_info = dest_ty.intInfo(zcu);
......@@ -5103,35 +5137,44 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
51035137
51045138 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {
51055139 const local = try f.allocLocal(null, dest_ty);
5106 try f.writeCValue(writer, local, .Other);
5107 try writer.writeAll(" = (");
5108 try f.renderType(writer, dest_ty);
5109 try writer.writeByte(')');
5110 try f.writeCValue(writer, operand, .Other);
5111 try writer.writeAll(";\n");
5140 try f.writeCValue(bw, local, .Other);
5141 try bw.writeAll(" = (");
5142 try f.renderType(bw, dest_ty);
5143 try bw.writeByte(')');
5144 try f.writeCValue(bw, operand, .Other);
5145 try bw.writeByte(';');
5146 try f.object.newline();
51125147 return local;
51135148 }
51145149
51155150 const operand_lval = if (operand == .constant) blk: {
51165151 const operand_local = try f.allocLocal(null, operand_ty);
5117 try f.writeCValue(writer, operand_local, .Other);
5118 try writer.writeAll(" = ");
5119 try f.writeCValue(writer, operand, .Other);
5120 try writer.writeAll(";\n");
5152 try f.writeCValue(bw, operand_local, .Other);
5153 if (operand_ty.isAbiInt(zcu)) {
5154 try bw.writeAll(" = ");
5155 } else {
5156 try bw.writeAll(" = (");
5157 try f.renderType(bw, operand_ty);
5158 try bw.writeByte(')');
5159 }
5160 try f.writeCValue(bw, operand, .Other);
5161 try bw.writeByte(';');
5162 try f.object.newline();
51215163 break :blk operand_local;
51225164 } else operand;
51235165
51245166 const local = try f.allocLocal(null, dest_ty);
5125 try writer.writeAll("memcpy(&");
5126 try f.writeCValue(writer, local, .Other);
5127 try writer.writeAll(", &");
5128 try f.writeCValue(writer, operand_lval, .Other);
5129 try writer.writeAll(", sizeof(");
5167 try bw.writeAll("memcpy(&");
5168 try f.writeCValue(bw, local, .Other);
5169 try bw.writeAll(", &");
5170 try f.writeCValue(bw, operand_lval, .Other);
5171 try bw.writeAll(", sizeof(");
51305172 try f.renderType(
5131 writer,
5173 bw,
51325174 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,
51335175 );
5134 try writer.writeAll("));\n");
5176 try bw.writeAll("));");
5177 try f.object.newline();
51355178
51365179 // Ensure padding bits have the expected value.
51375180 if (dest_ty.isAbiInt(zcu)) {
......@@ -5141,11 +5184,11 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
51415184 var wrap_ctype: ?CType = null;
51425185 var need_bitcasts = false;
51435186
5144 try f.writeCValue(writer, local, .Other);
5187 try f.writeCValue(bw, local, .Other);
51455188 switch (dest_ctype.info(ctype_pool)) {
51465189 else => {},
51475190 .array => |array_info| {
5148 try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) {
5191 try bw.print("[{d}]", .{switch (target.cpu.arch.endian()) {
51495192 .little => array_info.len - 1,
51505193 .big => 0,
51515194 }});
......@@ -5156,92 +5199,99 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
51565199 bits += 1;
51575200 },
51585201 }
5159 try writer.writeAll(" = ");
5202 try bw.writeAll(" = ");
51605203 if (need_bitcasts) {
5161 try writer.writeAll("zig_bitCast_");
5162 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?.toUnsigned());
5163 try writer.writeByte('(');
5204 try bw.writeAll("zig_bitCast_");
5205 try f.object.dg.renderCTypeForBuiltinFnName(bw, wrap_ctype.?.toUnsigned());
5206 try bw.writeByte('(');
51645207 }
5165 try writer.writeAll("zig_wrap_");
5208 try bw.writeAll("zig_wrap_");
51665209 const info_ty = try pt.intType(dest_info.signedness, bits);
51675210 if (wrap_ctype) |ctype|
5168 try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype)
5211 try f.object.dg.renderCTypeForBuiltinFnName(bw, ctype)
51695212 else
5170 try f.object.dg.renderTypeForBuiltinFnName(writer, info_ty);
5171 try writer.writeByte('(');
5213 try f.object.dg.renderTypeForBuiltinFnName(bw, info_ty);
5214 try bw.writeByte('(');
51725215 if (need_bitcasts) {
5173 try writer.writeAll("zig_bitCast_");
5174 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?);
5175 try writer.writeByte('(');
5216 try bw.writeAll("zig_bitCast_");
5217 try f.object.dg.renderCTypeForBuiltinFnName(bw, wrap_ctype.?);
5218 try bw.writeByte('(');
51765219 }
5177 try f.writeCValue(writer, local, .Other);
5220 try f.writeCValue(bw, local, .Other);
51785221 switch (dest_ctype.info(ctype_pool)) {
51795222 else => {},
5180 .array => |array_info| try writer.print("[{d}]", .{
5223 .array => |array_info| try bw.print("[{d}]", .{
51815224 switch (target.cpu.arch.endian()) {
51825225 .little => array_info.len - 1,
51835226 .big => 0,
51845227 },
51855228 }),
51865229 }
5187 if (need_bitcasts) try writer.writeByte(')');
5188 try f.object.dg.renderBuiltinInfo(writer, info_ty, .bits);
5189 if (need_bitcasts) try writer.writeByte(')');
5190 try writer.writeAll(");\n");
5230 if (need_bitcasts) try bw.writeByte(')');
5231 try f.object.dg.renderBuiltinInfo(bw, info_ty, .bits);
5232 if (need_bitcasts) try bw.writeByte(')');
5233 try bw.writeAll(");");
5234 try f.object.newline();
51915235 }
51925236
51935237 try f.freeCValue(null, operand_lval);
51945238 return local;
51955239}
51965240
5197fn airTrap(f: *Function, writer: anytype) !void {
5241fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void {
51985242 // Not even allowed to call trap in a naked function.
51995243 if (f.object.dg.is_naked_fn) return;
5200 try writer.writeAll("zig_trap();\n");
5244 try bw.writeAll("zig_trap();");
5245 try f.object.newline();
52015246}
52025247
5203fn airBreakpoint(writer: anytype) !CValue {
5204 try writer.writeAll("zig_breakpoint();\n");
5248fn airBreakpoint(o: *Object, bw: *std.io.BufferedWriter) !CValue {
5249 try bw.writeAll("zig_breakpoint();");
5250 try o.newline();
52055251 return .none;
52065252}
52075253
52085254fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
5209 const writer = f.object.writer();
5255 const bw = &f.object.code.buffered_writer;
52105256 const local = try f.allocLocal(inst, .usize);
5211 try f.writeCValue(writer, local, .Other);
5212 try writer.writeAll(" = (");
5213 try f.renderType(writer, .usize);
5214 try writer.writeAll(")zig_return_address();\n");
5257 try f.writeCValue(bw, local, .Other);
5258 try bw.writeAll(" = (");
5259 try f.renderType(bw, .usize);
5260 try bw.writeAll(")zig_return_address();");
5261 try f.object.newline();
52155262 return local;
52165263}
52175264
52185265fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
5219 const writer = f.object.writer();
5266 const bw = &f.object.code.buffered_writer;
52205267 const local = try f.allocLocal(inst, .usize);
5221 try f.writeCValue(writer, local, .Other);
5222 try writer.writeAll(" = (");
5223 try f.renderType(writer, .usize);
5224 try writer.writeAll(")zig_frame_address();\n");
5268 try f.writeCValue(bw, local, .Other);
5269 try bw.writeAll(" = (");
5270 try f.renderType(bw, .usize);
5271 try bw.writeAll(")zig_frame_address();");
5272 try f.object.newline();
52255273 return local;
52265274}
52275275
52285276fn airUnreach(f: *Function) !void {
52295277 // Not even allowed to call unreachable in a naked function.
52305278 if (f.object.dg.is_naked_fn) return;
5231 try f.object.writer().writeAll("zig_unreachable();\n");
5279 try f.object.code.buffered_writer.writeAll("zig_unreachable();");
5280 try f.object.newline();
52325281}
52335282
52345283fn airLoop(f: *Function, inst: Air.Inst.Index) !void {
52355284 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
52365285 const loop = f.air.extraData(Air.Block, ty_pl.payload);
52375286 const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[loop.end..][0..loop.data.body_len]);
5238 const writer = f.object.writer();
5287 const bw = &f.object.code.buffered_writer;
52395288
52405289 // `repeat` instructions matching this loop will branch to
52415290 // this label. Since we need a label for arbitrary `repeat`
52425291 // anyway, there's actually no need to use a "real" looping
52435292 // construct at all!
5244 try writer.print("zig_loop_{d}:\n", .{@intFromEnum(inst)});
5293 try bw.print("zig_loop_{d}:", .{@intFromEnum(inst)});
5294 try f.object.newline();
52455295 try genBodyInner(f, body); // no need to restore state, we're noreturn
52465296}
52475297
......@@ -5253,14 +5303,14 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
52535303 const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]);
52545304 const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);
52555305 const liveness_condbr = f.liveness.getCondBr(inst);
5256 const writer = f.object.writer();
5306 const bw = &f.object.code.buffered_writer;
52575307
5258 try writer.writeAll("if (");
5259 try f.writeCValue(writer, cond, .Other);
5260 try writer.writeAll(") ");
5308 try bw.writeAll("if (");
5309 try f.writeCValue(bw, cond, .Other);
5310 try bw.writeAll(") ");
52615311
52625312 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
5263 try writer.writeByte('\n');
5313 try f.object.newline();
52645314 if (else_body.len > 0) if (f.object.dg.expected_block) |_|
52655315 return f.fail("runtime code not allowed in naked function", .{});
52665316
......@@ -5286,7 +5336,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
52865336 const init_condition = try f.resolveInst(switch_br.operand);
52875337 try reap(f, inst, &.{switch_br.operand});
52885338 const condition_ty = f.typeOf(switch_br.operand);
5289 const writer = f.object.writer();
5339 const bw = &f.object.code.buffered_writer;
52905340
52915341 // For dispatches, we will create a local alloc to contain the condition value.
52925342 // This may not result in optimal codegen for switch loops, but it minimizes the
......@@ -5294,7 +5344,8 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
52945344 const condition = if (is_dispatch_loop) cond: {
52955345 const new_local = try f.allocLocal(inst, condition_ty);
52965346 try f.copyCValue(try f.ctypeFromType(condition_ty, .complete), new_local, init_condition);
5297 try writer.print("zig_switch_{d}_loop:\n", .{@intFromEnum(inst)});
5347 try bw.print("zig_switch_{d}_loop:", .{@intFromEnum(inst)});
5348 try f.object.newline();
52985349 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);
52995350 break :cond new_local;
53005351 } else init_condition;
......@@ -5303,7 +5354,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53035354 assert(f.loop_switch_conds.remove(inst));
53045355 };
53055356
5306 try writer.writeAll("switch (");
5357 try bw.writeAll("switch (");
53075358
53085359 const lowered_condition_ty: Type = if (condition_ty.toIntern() == .bool_type)
53095360 .u1
......@@ -5312,13 +5363,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53125363 else
53135364 condition_ty;
53145365 if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {
5315 try writer.writeByte('(');
5316 try f.renderType(writer, lowered_condition_ty);
5317 try writer.writeByte(')');
5366 try bw.writeByte('(');
5367 try f.renderType(bw, lowered_condition_ty);
5368 try bw.writeByte(')');
53185369 }
5319 try f.writeCValue(writer, condition, .Other);
5320 try writer.writeAll(") {");
5321 f.object.indent_writer.pushIndent();
5370 try f.writeCValue(bw, condition, .Other);
5371 try bw.writeAll(") {");
5372 f.object.indent();
53225373
53235374 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);
53245375 defer gpa.free(liveness.deaths);
......@@ -5331,35 +5382,36 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53315382 continue;
53325383 }
53335384 for (case.items) |item| {
5334 try f.object.indent_writer.insertNewline();
5335 try writer.writeAll("case ");
5385 try f.object.newline();
5386 try bw.writeAll("case ");
53365387 const item_value = try f.air.value(item, pt);
53375388 // If `item_value` is a pointer with a known integer address, print the address
53385389 // with no cast to avoid a warning.
53395390 write_val: {
53405391 if (condition_ty.isPtrAtRuntime(zcu)) {
53415392 if (item_value.?.getUnsignedInt(zcu)) |item_int| {
5342 try writer.print("{}", .{try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int))});
5393 try bw.print("{f}", .{try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int))});
53435394 break :write_val;
53445395 }
53455396 }
53465397 if (condition_ty.isPtrAtRuntime(zcu)) {
5347 try writer.writeByte('(');
5348 try f.renderType(writer, .usize);
5349 try writer.writeByte(')');
5398 try bw.writeByte('(');
5399 try f.renderType(bw, .usize);
5400 try bw.writeByte(')');
53505401 }
5351 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);
5402 try f.object.dg.renderValue(bw, (try f.air.value(item, pt)).?, .Other);
53525403 }
5353 try writer.writeByte(':');
5404 try bw.writeByte(':');
53545405 }
5355 try writer.writeAll(" {\n");
5356 f.object.indent_writer.pushIndent();
5406 try bw.writeAll(" {");
5407 f.object.indent();
5408 try f.object.newline();
53575409 if (is_dispatch_loop) {
5358 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
5410 try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
53595411 }
53605412 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5361 f.object.indent_writer.popIndent();
5362 try writer.writeByte('}');
5413 f.object.outdent();
5414 try bw.writeByte('}');
53635415 if (f.object.dg.expected_block) |_|
53645416 return f.fail("runtime code not allowed in naked function", .{});
53655417
......@@ -5367,9 +5419,9 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53675419 }
53685420
53695421 const else_body = it.elseBody();
5370 try f.object.indent_writer.insertNewline();
5422 try f.object.newline();
53715423
5372 try writer.writeAll("default: ");
5424 try bw.writeAll("default: ");
53735425 if (any_range_cases) {
53745426 // We will iterate the cases again to handle those with ranges, and generate
53755427 // code using conditions rather than switch cases for such cases.
......@@ -5377,40 +5429,41 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53775429 while (it.next()) |case| {
53785430 if (case.ranges.len == 0) continue; // handled above
53795431
5380 try writer.writeAll("if (");
5432 try bw.writeAll("if (");
53815433 for (case.items, 0..) |item, item_i| {
5382 if (item_i != 0) try writer.writeAll(" || ");
5383 try f.writeCValue(writer, condition, .Other);
5384 try writer.writeAll(" == ");
5385 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);
5434 if (item_i != 0) try bw.writeAll(" || ");
5435 try f.writeCValue(bw, condition, .Other);
5436 try bw.writeAll(" == ");
5437 try f.object.dg.renderValue(bw, (try f.air.value(item, pt)).?, .Other);
53865438 }
53875439 for (case.ranges, 0..) |range, range_i| {
5388 if (case.items.len != 0 or range_i != 0) try writer.writeAll(" || ");
5440 if (case.items.len != 0 or range_i != 0) try bw.writeAll(" || ");
53895441 // "(x >= lower && x <= upper)"
5390 try writer.writeByte('(');
5391 try f.writeCValue(writer, condition, .Other);
5392 try writer.writeAll(" >= ");
5393 try f.object.dg.renderValue(writer, (try f.air.value(range[0], pt)).?, .Other);
5394 try writer.writeAll(" && ");
5395 try f.writeCValue(writer, condition, .Other);
5396 try writer.writeAll(" <= ");
5397 try f.object.dg.renderValue(writer, (try f.air.value(range[1], pt)).?, .Other);
5398 try writer.writeByte(')');
5442 try bw.writeByte('(');
5443 try f.writeCValue(bw, condition, .Other);
5444 try bw.writeAll(" >= ");
5445 try f.object.dg.renderValue(bw, (try f.air.value(range[0], pt)).?, .Other);
5446 try bw.writeAll(" && ");
5447 try f.writeCValue(bw, condition, .Other);
5448 try bw.writeAll(" <= ");
5449 try f.object.dg.renderValue(bw, (try f.air.value(range[1], pt)).?, .Other);
5450 try bw.writeByte(')');
53995451 }
5400 try writer.writeAll(") {\n");
5401 f.object.indent_writer.pushIndent();
5452 try bw.writeAll(") {");
5453 f.object.indent();
5454 try f.object.newline();
54025455 if (is_dispatch_loop) {
5403 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
5456 try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
54045457 }
54055458 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5406 f.object.indent_writer.popIndent();
5407 try writer.writeByte('}');
5459 f.object.outdent();
5460 try bw.writeByte('}');
54085461 if (f.object.dg.expected_block) |_|
54095462 return f.fail("runtime code not allowed in naked function", .{});
54105463 }
54115464 }
54125465 if (is_dispatch_loop) {
5413 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), switch_br.cases_len });
5466 try bw.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), switch_br.cases_len });
54145467 }
54155468 if (else_body.len > 0) {
54165469 // Note that this must be the last case, so we do not need to use `genBodyResolveState` since
......@@ -5422,12 +5475,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
54225475 if (f.object.dg.expected_block) |_|
54235476 return f.fail("runtime code not allowed in naked function", .{});
54245477 } else {
5425 try writer.writeAll("zig_unreachable();");
5478 try bw.writeAll("zig_unreachable();");
54265479 }
5427 try f.object.indent_writer.insertNewline();
5480 try f.object.newline();
54285481
5429 f.object.indent_writer.popIndent();
5430 try writer.writeAll("}\n");
5482 f.object.outdent();
5483 try bw.writeByte('}');
5484 try f.object.newline();
54315485}
54325486
54335487fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
......@@ -5465,7 +5519,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
54655519 extra_i += inputs.len;
54665520
54675521 const result = result: {
5468 const writer = f.object.writer();
5522 const bw = &f.object.code.buffered_writer;
54695523 const inst_ty = f.typeOfIndex(inst);
54705524 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
54715525 const inst_local = try f.allocLocalValue(.{
......@@ -5473,10 +5527,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
54735527 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
54745528 });
54755529 if (f.wantSafety()) {
5476 try f.writeCValue(writer, inst_local, .Other);
5477 try writer.writeAll(" = ");
5478 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
5479 try writer.writeAll(";\n");
5530 try f.writeCValue(bw, inst_local, .Other);
5531 try bw.writeAll(" = ");
5532 try f.writeCValue(bw, .{ .undef = inst_ty }, .Other);
5533 try bw.writeByte(';');
5534 try f.object.newline();
54805535 }
54815536 break :local inst_local;
54825537 } else .none;
......@@ -5500,21 +5555,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
55005555 const is_reg = constraint[1] == '{';
55015556 if (is_reg) {
55025557 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
5503 try writer.writeAll("register ");
5558 try bw.writeAll("register ");
55045559 const output_local = try f.allocLocalValue(.{
55055560 .ctype = try f.ctypeFromType(output_ty, .complete),
55065561 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
55075562 });
55085563 try f.allocs.put(gpa, output_local.new_local, false);
5509 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);
5510 try writer.writeAll(" __asm(\"");
5511 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
5512 try writer.writeAll("\")");
5564 try f.object.dg.renderTypeAndName(bw, output_ty, output_local, .{}, .none, .complete);
5565 try bw.writeAll(" __asm(\"");
5566 try bw.writeAll(constraint["={".len .. constraint.len - "}".len]);
5567 try bw.writeAll("\")");
55135568 if (f.wantSafety()) {
5514 try writer.writeAll(" = ");
5515 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);
5569 try bw.writeAll(" = ");
5570 try f.writeCValue(bw, .{ .undef = output_ty }, .Other);
55165571 }
5517 try writer.writeAll(";\n");
5572 try bw.writeByte(';');
5573 try f.object.newline();
55185574 }
55195575 }
55205576 for (inputs) |input| {
......@@ -5535,21 +5591,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
55355591 const input_val = try f.resolveInst(input);
55365592 if (asmInputNeedsLocal(f, constraint, input_val)) {
55375593 const input_ty = f.typeOf(input);
5538 if (is_reg) try writer.writeAll("register ");
5594 if (is_reg) try bw.writeAll("register ");
55395595 const input_local = try f.allocLocalValue(.{
55405596 .ctype = try f.ctypeFromType(input_ty, .complete),
55415597 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
55425598 });
55435599 try f.allocs.put(gpa, input_local.new_local, false);
5544 try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);
5600 try f.object.dg.renderTypeAndName(bw, input_ty, input_local, Const, .none, .complete);
55455601 if (is_reg) {
5546 try writer.writeAll(" __asm(\"");
5547 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
5548 try writer.writeAll("\")");
5602 try bw.writeAll(" __asm(\"");
5603 try bw.writeAll(constraint["{".len .. constraint.len - "}".len]);
5604 try bw.writeAll("\")");
55495605 }
5550 try writer.writeAll(" = ");
5551 try f.writeCValue(writer, input_val, .Other);
5552 try writer.writeAll(";\n");
5606 try bw.writeAll(" = ");
5607 try f.writeCValue(bw, input_val, .Other);
5608 try bw.writeByte(';');
5609 try f.object.newline();
55535610 }
55545611 }
55555612 for (0..clobbers_len) |_| {
......@@ -5609,14 +5666,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56095666 }
56105667 }
56115668
5612 try writer.writeAll("__asm");
5613 if (is_volatile) try writer.writeAll(" volatile");
5614 try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});
5669 try bw.writeAll("__asm");
5670 if (is_volatile) try bw.writeAll(" volatile");
5671 try bw.print("({fs}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});
56155672 }
56165673
56175674 extra_i = constraints_extra_begin;
56185675 var locals_index = locals_begin;
5619 try writer.writeByte(':');
5676 try bw.writeByte(':');
56205677 for (outputs, 0..) |output, index| {
56215678 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
56225679 const constraint = mem.sliceTo(extra_bytes, 0);
......@@ -5625,22 +5682,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56255682 // for the string, we still use the next u32 for the null terminator.
56265683 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56275684
5628 if (index > 0) try writer.writeByte(',');
5629 try writer.writeByte(' ');
5630 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});
5685 if (index > 0) try bw.writeByte(',');
5686 try bw.writeByte(' ');
5687 if (!mem.eql(u8, name, "_")) try bw.print("[{s}]", .{name});
56315688 const is_reg = constraint[1] == '{';
5632 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
5689 try bw.print("{fs}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
56335690 if (is_reg) {
5634 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
5691 try f.writeCValue(bw, .{ .local = locals_index }, .Other);
56355692 locals_index += 1;
56365693 } else if (output == .none) {
5637 try f.writeCValue(writer, inst_local, .FunctionArgument);
5694 try f.writeCValue(bw, inst_local, .FunctionArgument);
56385695 } else {
5639 try f.writeCValueDeref(writer, try f.resolveInst(output));
5696 try f.writeCValueDeref(bw, try f.resolveInst(output));
56405697 }
5641 try writer.writeByte(')');
5698 try bw.writeByte(')');
56425699 }
5643 try writer.writeByte(':');
5700 try bw.writeByte(':');
56445701 for (inputs, 0..) |input, index| {
56455702 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
56465703 const constraint = mem.sliceTo(extra_bytes, 0);
......@@ -5649,21 +5706,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56495706 // for the string, we still use the next u32 for the null terminator.
56505707 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56515708
5652 if (index > 0) try writer.writeByte(',');
5653 try writer.writeByte(' ');
5654 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});
5709 if (index > 0) try bw.writeByte(',');
5710 try bw.writeByte(' ');
5711 if (!mem.eql(u8, name, "_")) try bw.print("[{s}]", .{name});
56555712
56565713 const is_reg = constraint[0] == '{';
56575714 const input_val = try f.resolveInst(input);
5658 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
5659 try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
5715 try bw.print("{fs}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
5716 try f.writeCValue(bw, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
56605717 const input_local_idx = locals_index;
56615718 locals_index += 1;
56625719 break :local .{ .local = input_local_idx };
56635720 } else input_val, .Other);
5664 try writer.writeByte(')');
5721 try bw.writeByte(')');
56655722 }
5666 try writer.writeByte(':');
5723 try bw.writeByte(':');
56675724 for (0..clobbers_len) |clobber_i| {
56685725 const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0);
56695726 // This equation accounts for the fact that even if we have exactly 4 bytes
......@@ -5672,10 +5729,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56725729
56735730 if (clobber.len == 0) continue;
56745731
5675 if (clobber_i > 0) try writer.writeByte(',');
5676 try writer.print(" {s}", .{fmtStringLiteral(clobber, null)});
5732 if (clobber_i > 0) try bw.writeByte(',');
5733 try bw.print(" {fs}", .{fmtStringLiteral(clobber, null)});
56775734 }
5678 try writer.writeAll(");\n");
5735 try bw.writeAll(");");
5736 try f.object.newline();
56795737
56805738 extra_i = constraints_extra_begin;
56815739 locals_index = locals_begin;
......@@ -5689,14 +5747,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56895747
56905748 const is_reg = constraint[1] == '{';
56915749 if (is_reg) {
5692 try f.writeCValueDeref(writer, if (output == .none)
5750 try f.writeCValueDeref(bw, if (output == .none)
56935751 .{ .local_ref = inst_local.new_local }
56945752 else
56955753 try f.resolveInst(output));
5696 try writer.writeAll(" = ");
5697 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
5754 try bw.writeAll(" = ");
5755 try f.writeCValue(bw, .{ .local = locals_index }, .Other);
56985756 locals_index += 1;
5699 try writer.writeAll(";\n");
5757 try bw.writeByte(';');
5758 try f.object.newline();
57005759 }
57015760 }
57025761
......@@ -5726,14 +5785,14 @@ fn airIsNull(
57265785 const ctype_pool = &f.object.dg.ctype_pool;
57275786 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
57285787
5729 const writer = f.object.writer();
5788 const bw = &f.object.code.buffered_writer;
57305789 const operand = try f.resolveInst(un_op);
57315790 try reap(f, inst, &.{un_op});
57325791
57335792 const local = try f.allocLocal(inst, .bool);
5734 const a = try Assignment.start(f, writer, .bool);
5735 try f.writeCValue(writer, local, .Other);
5736 try a.assign(f, writer);
5793 const a = try Assignment.start(f, bw, .bool);
5794 try f.writeCValue(bw, local, .Other);
5795 try a.assign(f, bw);
57375796
57385797 const operand_ty = f.typeOf(un_op);
57395798 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
......@@ -5741,9 +5800,9 @@ fn airIsNull(
57415800 const rhs = switch (opt_ctype.info(ctype_pool)) {
57425801 .basic, .pointer => rhs: {
57435802 if (is_ptr)
5744 try f.writeCValueDeref(writer, operand)
5803 try f.writeCValueDeref(bw, operand)
57455804 else
5746 try f.writeCValue(writer, operand, .Other);
5805 try f.writeCValue(bw, operand, .Other);
57475806 break :rhs if (opt_ctype.isBool())
57485807 "true"
57495808 else if (opt_ctype.isInteger())
......@@ -5755,24 +5814,24 @@ fn airIsNull(
57555814 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
57565815 .is_null, .payload => rhs: {
57575816 if (is_ptr)
5758 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" })
5817 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "is_null" })
57595818 else
5760 try f.writeCValueMember(writer, operand, .{ .identifier = "is_null" });
5819 try f.writeCValueMember(bw, operand, .{ .identifier = "is_null" });
57615820 break :rhs "true";
57625821 },
57635822 .ptr, .len => rhs: {
57645823 if (is_ptr)
5765 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "ptr" })
5824 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "ptr" })
57665825 else
5767 try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });
5826 try f.writeCValueMember(bw, operand, .{ .identifier = "ptr" });
57685827 break :rhs "NULL";
57695828 },
57705829 else => unreachable,
57715830 },
57725831 };
5773 try writer.writeAll(compareOperatorC(operator));
5774 try writer.writeAll(rhs);
5775 try a.end(f, writer);
5832 try bw.writeAll(compareOperatorC(operator));
5833 try bw.writeAll(rhs);
5834 try a.end(f, bw);
57765835 return local;
57775836}
57785837
......@@ -5794,16 +5853,16 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue
57945853 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
57955854 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
57965855 .is_null, .payload => {
5797 const writer = f.object.writer();
5856 const bw = &f.object.code.buffered_writer;
57985857 const local = try f.allocLocal(inst, inst_ty);
5799 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
5800 try f.writeCValue(writer, local, .Other);
5801 try a.assign(f, writer);
5858 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
5859 try f.writeCValue(bw, local, .Other);
5860 try a.assign(f, bw);
58025861 if (is_ptr) {
5803 try writer.writeByte('&');
5804 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
5805 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
5806 try a.end(f, writer);
5862 try bw.writeByte('&');
5863 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
5864 } else try f.writeCValueMember(bw, operand, .{ .identifier = "payload" });
5865 try a.end(f, bw);
58075866 return local;
58085867 },
58095868 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
......@@ -5816,7 +5875,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
58165875 const pt = f.object.dg.pt;
58175876 const zcu = pt.zcu;
58185877 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5819 const writer = f.object.writer();
5878 const bw = &f.object.code.buffered_writer;
58205879 const operand = try f.resolveInst(ty_op.operand);
58215880 try reap(f, inst, &.{ty_op.operand});
58225881 const operand_ty = f.typeOf(ty_op.operand);
......@@ -5825,40 +5884,40 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
58255884 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);
58265885 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {
58275886 .basic => {
5828 const a = try Assignment.start(f, writer, opt_ctype);
5829 try f.writeCValueDeref(writer, operand);
5830 try a.assign(f, writer);
5831 try f.object.dg.renderValue(writer, Value.false, .Other);
5832 try a.end(f, writer);
5887 const a = try Assignment.start(f, bw, opt_ctype);
5888 try f.writeCValueDeref(bw, operand);
5889 try a.assign(f, bw);
5890 try f.object.dg.renderValue(bw, Value.false, .Other);
5891 try a.end(f, bw);
58335892 return .none;
58345893 },
58355894 .pointer => {
58365895 if (f.liveness.isUnused(inst)) return .none;
58375896 const local = try f.allocLocal(inst, inst_ty);
5838 const a = try Assignment.start(f, writer, opt_ctype);
5839 try f.writeCValue(writer, local, .Other);
5840 try a.assign(f, writer);
5841 try f.writeCValue(writer, operand, .Other);
5842 try a.end(f, writer);
5897 const a = try Assignment.start(f, bw, opt_ctype);
5898 try f.writeCValue(bw, local, .Other);
5899 try a.assign(f, bw);
5900 try f.writeCValue(bw, operand, .Other);
5901 try a.end(f, bw);
58435902 return local;
58445903 },
58455904 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
58465905 .aggregate => {
58475906 {
5848 const a = try Assignment.start(f, writer, opt_ctype);
5849 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" });
5850 try a.assign(f, writer);
5851 try f.object.dg.renderValue(writer, Value.false, .Other);
5852 try a.end(f, writer);
5907 const a = try Assignment.start(f, bw, opt_ctype);
5908 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "is_null" });
5909 try a.assign(f, bw);
5910 try f.object.dg.renderValue(bw, Value.false, .Other);
5911 try a.end(f, bw);
58535912 }
58545913 if (f.liveness.isUnused(inst)) return .none;
58555914 const local = try f.allocLocal(inst, inst_ty);
5856 const a = try Assignment.start(f, writer, opt_ctype);
5857 try f.writeCValue(writer, local, .Other);
5858 try a.assign(f, writer);
5859 try writer.writeByte('&');
5860 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
5861 try a.end(f, writer);
5915 const a = try Assignment.start(f, bw, opt_ctype);
5916 try f.writeCValue(bw, local, .Other);
5917 try a.assign(f, bw);
5918 try bw.writeByte('&');
5919 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
5920 try a.end(f, bw);
58625921 return local;
58635922 },
58645923 }
......@@ -5966,42 +6025,43 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
59666025 const field_ptr_val = try f.resolveInst(extra.field_ptr);
59676026 try reap(f, inst, &.{extra.field_ptr});
59686027
5969 const writer = f.object.writer();
6028 const bw = &f.object.code.buffered_writer;
59706029 const local = try f.allocLocal(inst, container_ptr_ty);
5971 try f.writeCValue(writer, local, .Other);
5972 try writer.writeAll(" = (");
5973 try f.renderType(writer, container_ptr_ty);
5974 try writer.writeByte(')');
6030 try f.writeCValue(bw, local, .Other);
6031 try bw.writeAll(" = (");
6032 try f.renderType(bw, container_ptr_ty);
6033 try bw.writeByte(')');
59756034
59766035 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) {
5977 .begin => try f.writeCValue(writer, field_ptr_val, .Other),
6036 .begin => try f.writeCValue(bw, field_ptr_val, .Other),
59786037 .field => |field| {
59796038 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59806039
5981 try writer.writeAll("((");
5982 try f.renderType(writer, u8_ptr_ty);
5983 try writer.writeByte(')');
5984 try f.writeCValue(writer, field_ptr_val, .Other);
5985 try writer.writeAll(" - offsetof(");
5986 try f.renderType(writer, container_ty);
5987 try writer.writeAll(", ");
5988 try f.writeCValue(writer, field, .Other);
5989 try writer.writeAll("))");
6040 try bw.writeAll("((");
6041 try f.renderType(bw, u8_ptr_ty);
6042 try bw.writeByte(')');
6043 try f.writeCValue(bw, field_ptr_val, .Other);
6044 try bw.writeAll(" - offsetof(");
6045 try f.renderType(bw, container_ty);
6046 try bw.writeAll(", ");
6047 try f.writeCValue(bw, field, .Other);
6048 try bw.writeAll("))");
59906049 },
59916050 .byte_offset => |byte_offset| {
59926051 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59936052
5994 try writer.writeAll("((");
5995 try f.renderType(writer, u8_ptr_ty);
5996 try writer.writeByte(')');
5997 try f.writeCValue(writer, field_ptr_val, .Other);
5998 try writer.print(" - {})", .{
6053 try bw.writeAll("((");
6054 try f.renderType(bw, u8_ptr_ty);
6055 try bw.writeByte(')');
6056 try f.writeCValue(bw, field_ptr_val, .Other);
6057 try bw.print(" - {f})", .{
59996058 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),
60006059 });
60016060 },
60026061 }
60036062
6004 try writer.writeAll(";\n");
6063 try bw.writeByte(';');
6064 try f.object.newline();
60056065 return local;
60066066}
60076067
......@@ -6020,33 +6080,34 @@ fn fieldPtr(
60206080 // Ensure complete type definition is visible before accessing fields.
60216081 _ = try f.ctypeFromType(container_ty, .complete);
60226082
6023 const writer = f.object.writer();
6083 const bw = &f.object.code.buffered_writer;
60246084 const local = try f.allocLocal(inst, field_ptr_ty);
6025 try f.writeCValue(writer, local, .Other);
6026 try writer.writeAll(" = (");
6027 try f.renderType(writer, field_ptr_ty);
6028 try writer.writeByte(')');
6085 try f.writeCValue(bw, local, .Other);
6086 try bw.writeAll(" = (");
6087 try f.renderType(bw, field_ptr_ty);
6088 try bw.writeByte(')');
60296089
60306090 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) {
6031 .begin => try f.writeCValue(writer, container_ptr_val, .Other),
6091 .begin => try f.writeCValue(bw, container_ptr_val, .Other),
60326092 .field => |field| {
6033 try writer.writeByte('&');
6034 try f.writeCValueDerefMember(writer, container_ptr_val, field);
6093 try bw.writeByte('&');
6094 try f.writeCValueDerefMember(bw, container_ptr_val, field);
60356095 },
60366096 .byte_offset => |byte_offset| {
60376097 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
60386098
6039 try writer.writeAll("((");
6040 try f.renderType(writer, u8_ptr_ty);
6041 try writer.writeByte(')');
6042 try f.writeCValue(writer, container_ptr_val, .Other);
6043 try writer.print(" + {})", .{
6099 try bw.writeAll("((");
6100 try f.renderType(bw, u8_ptr_ty);
6101 try bw.writeByte(')');
6102 try f.writeCValue(bw, container_ptr_val, .Other);
6103 try bw.print(" + {f})", .{
60446104 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),
60456105 });
60466106 },
60476107 }
60486108
6049 try writer.writeAll(";\n");
6109 try bw.writeByte(';');
6110 try f.object.newline();
60506111 return local;
60516112}
60526113
......@@ -6066,7 +6127,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
60666127 const struct_byval = try f.resolveInst(extra.struct_operand);
60676128 try reap(f, inst, &.{extra.struct_operand});
60686129 const struct_ty = f.typeOf(extra.struct_operand);
6069 const writer = f.object.writer();
6130 const bw = &f.object.code.buffered_writer;
60706131
60716132 // Ensure complete type definition is visible before accessing fields.
60726133 _ = try f.ctypeFromType(struct_ty, .complete);
......@@ -6093,42 +6154,44 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
60936154 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));
60946155
60956156 const temp_local = try f.allocLocal(inst, field_int_ty);
6096 try f.writeCValue(writer, temp_local, .Other);
6097 try writer.writeAll(" = zig_wrap_");
6098 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
6099 try writer.writeAll("((");
6100 try f.renderType(writer, field_int_ty);
6101 try writer.writeByte(')');
6157 try f.writeCValue(bw, temp_local, .Other);
6158 try bw.writeAll(" = zig_wrap_");
6159 try f.object.dg.renderTypeForBuiltinFnName(bw, field_int_ty);
6160 try bw.writeAll("((");
6161 try f.renderType(bw, field_int_ty);
6162 try bw.writeByte(')');
61026163 const cant_cast = int_info.bits > 64;
61036164 if (cant_cast) {
61046165 if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
6105 try writer.writeAll("zig_lo_");
6106 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
6107 try writer.writeByte('(');
6166 try bw.writeAll("zig_lo_");
6167 try f.object.dg.renderTypeForBuiltinFnName(bw, struct_ty);
6168 try bw.writeByte('(');
61086169 }
61096170 if (bit_offset > 0) {
6110 try writer.writeAll("zig_shr_");
6111 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
6112 try writer.writeByte('(');
6171 try bw.writeAll("zig_shr_");
6172 try f.object.dg.renderTypeForBuiltinFnName(bw, struct_ty);
6173 try bw.writeByte('(');
61136174 }
6114 try f.writeCValue(writer, struct_byval, .Other);
6115 if (bit_offset > 0) try writer.print(", {})", .{
6175 try f.writeCValue(bw, struct_byval, .Other);
6176 if (bit_offset > 0) try bw.print(", {f})", .{
61166177 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
61176178 });
6118 if (cant_cast) try writer.writeByte(')');
6119 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
6120 try writer.writeAll(");\n");
6179 if (cant_cast) try bw.writeByte(')');
6180 try f.object.dg.renderBuiltinInfo(bw, field_int_ty, .bits);
6181 try bw.writeAll(");");
6182 try f.object.newline();
61216183 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;
61226184
61236185 const local = try f.allocLocal(inst, inst_ty);
61246186 if (local.new_local != temp_local.new_local) {
6125 try writer.writeAll("memcpy(");
6126 try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);
6127 try writer.writeAll(", ");
6128 try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
6129 try writer.writeAll(", sizeof(");
6130 try f.renderType(writer, inst_ty);
6131 try writer.writeAll("));\n");
6187 try bw.writeAll("memcpy(");
6188 try f.writeCValue(bw, .{ .local_ref = local.new_local }, .FunctionArgument);
6189 try bw.writeAll(", ");
6190 try f.writeCValue(bw, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
6191 try bw.writeAll(", sizeof(");
6192 try f.renderType(bw, inst_ty);
6193 try bw.writeAll("));");
6194 try f.object.newline();
61326195 }
61336196 try freeLocal(f, inst, temp_local.new_local, null);
61346197 return local;
......@@ -6149,10 +6212,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
61496212 .@"packed" => {
61506213 const operand_lval = if (struct_byval == .constant) blk: {
61516214 const operand_local = try f.allocLocal(inst, struct_ty);
6152 try f.writeCValue(writer, operand_local, .Other);
6153 try writer.writeAll(" = ");
6154 try f.writeCValue(writer, struct_byval, .Other);
6155 try writer.writeAll(";\n");
6215 try f.writeCValue(bw, operand_local, .Other);
6216 try bw.writeAll(" = ");
6217 try f.writeCValue(bw, struct_byval, .Other);
6218 try bw.writeByte(';');
6219 try f.object.newline();
61566220 break :blk operand_local;
61576221 } else struct_byval;
61586222 const local = try f.allocLocal(inst, inst_ty);
......@@ -6163,13 +6227,14 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
61636227 },
61646228 else => true,
61656229 }) {
6166 try writer.writeAll("memcpy(&");
6167 try f.writeCValue(writer, local, .Other);
6168 try writer.writeAll(", &");
6169 try f.writeCValue(writer, operand_lval, .Other);
6170 try writer.writeAll(", sizeof(");
6171 try f.renderType(writer, inst_ty);
6172 try writer.writeAll("));\n");
6230 try bw.writeAll("memcpy(&");
6231 try f.writeCValue(bw, local, .Other);
6232 try bw.writeAll(", &");
6233 try f.writeCValue(bw, operand_lval, .Other);
6234 try bw.writeAll(", sizeof(");
6235 try f.renderType(bw, inst_ty);
6236 try bw.writeAll("));");
6237 try f.object.newline();
61736238 }
61746239 try f.freeCValue(inst, operand_lval);
61756240 return local;
......@@ -6180,11 +6245,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
61806245 };
61816246
61826247 const local = try f.allocLocal(inst, inst_ty);
6183 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
6184 try f.writeCValue(writer, local, .Other);
6185 try a.assign(f, writer);
6186 try f.writeCValueMember(writer, struct_byval, field_name);
6187 try a.end(f, writer);
6248 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6249 try f.writeCValue(bw, local, .Other);
6250 try a.assign(f, bw);
6251 try f.writeCValueMember(bw, struct_byval, field_name);
6252 try a.end(f, bw);
61886253 return local;
61896254}
61906255
......@@ -6211,21 +6276,22 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
62116276 return local;
62126277 }
62136278
6214 const writer = f.object.writer();
6215 try f.writeCValue(writer, local, .Other);
6216 try writer.writeAll(" = ");
6279 const bw = &f.object.code.buffered_writer;
6280 try f.writeCValue(bw, local, .Other);
6281 try bw.writeAll(" = ");
62176282
62186283 if (!payload_ty.hasRuntimeBits(zcu))
6219 try f.writeCValue(writer, operand, .Other)
6284 try f.writeCValue(bw, operand, .Other)
62206285 else if (error_ty.errorSetIsEmpty(zcu))
6221 try writer.print("{}", .{
6286 try bw.print("{f}", .{
62226287 try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)),
62236288 })
62246289 else if (operand_is_ptr)
6225 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
6290 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" })
62266291 else
6227 try f.writeCValueMember(writer, operand, .{ .identifier = "error" });
6228 try writer.writeAll(";\n");
6292 try f.writeCValueMember(bw, operand, .{ .identifier = "error" });
6293 try bw.writeByte(';');
6294 try f.object.newline();
62296295 return local;
62306296}
62316297
......@@ -6240,29 +6306,30 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
62406306 const operand_ty = f.typeOf(ty_op.operand);
62416307 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
62426308
6243 const writer = f.object.writer();
6309 const bw = &f.object.code.buffered_writer;
62446310 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
62456311 if (!is_ptr) return .none;
62466312
62476313 const local = try f.allocLocal(inst, inst_ty);
6248 try f.writeCValue(writer, local, .Other);
6249 try writer.writeAll(" = (");
6250 try f.renderType(writer, inst_ty);
6251 try writer.writeByte(')');
6252 try f.writeCValue(writer, operand, .Other);
6253 try writer.writeAll(";\n");
6314 try f.writeCValue(bw, local, .Other);
6315 try bw.writeAll(" = (");
6316 try f.renderType(bw, inst_ty);
6317 try bw.writeByte(')');
6318 try f.writeCValue(bw, operand, .Other);
6319 try bw.writeByte(';');
6320 try f.object.newline();
62546321 return local;
62556322 }
62566323
62576324 const local = try f.allocLocal(inst, inst_ty);
6258 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
6259 try f.writeCValue(writer, local, .Other);
6260 try a.assign(f, writer);
6325 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6326 try f.writeCValue(bw, local, .Other);
6327 try a.assign(f, bw);
62616328 if (is_ptr) {
6262 try writer.writeByte('&');
6263 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
6264 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });
6265 try a.end(f, writer);
6329 try bw.writeByte('&');
6330 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
6331 } else try f.writeCValueMember(bw, operand, .{ .identifier = "payload" });
6332 try a.end(f, bw);
62666333 return local;
62676334}
62686335
......@@ -6281,21 +6348,21 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
62816348 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
62826349 .is_null, .payload => {
62836350 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);
6284 const writer = f.object.writer();
6351 const bw = &f.object.code.buffered_writer;
62856352 const local = try f.allocLocal(inst, inst_ty);
62866353 {
6287 const a = try Assignment.start(f, writer, .bool);
6288 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
6289 try a.assign(f, writer);
6290 try writer.writeAll("false");
6291 try a.end(f, writer);
6354 const a = try Assignment.start(f, bw, .bool);
6355 try f.writeCValueMember(bw, local, .{ .identifier = "is_null" });
6356 try a.assign(f, bw);
6357 try bw.writeAll("false");
6358 try a.end(f, bw);
62926359 }
62936360 {
6294 const a = try Assignment.start(f, writer, operand_ctype);
6295 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6296 try a.assign(f, writer);
6297 try f.writeCValue(writer, operand, .Other);
6298 try a.end(f, writer);
6361 const a = try Assignment.start(f, bw, operand_ctype);
6362 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6363 try a.assign(f, bw);
6364 try f.writeCValue(bw, operand, .Other);
6365 try a.end(f, bw);
62996366 }
63006367 return local;
63016368 },
......@@ -6317,7 +6384,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
63176384 const err = try f.resolveInst(ty_op.operand);
63186385 try reap(f, inst, &.{ty_op.operand});
63196386
6320 const writer = f.object.writer();
6387 const bw = &f.object.code.buffered_writer;
63216388 const local = try f.allocLocal(inst, inst_ty);
63226389
63236390 if (repr_is_err and err == .local and err.local == local.new_local) {
......@@ -6326,21 +6393,21 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
63266393 }
63276394
63286395 if (!repr_is_err) {
6329 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
6330 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6331 try a.assign(f, writer);
6332 try f.object.dg.renderUndefValue(writer, payload_ty, .Other);
6333 try a.end(f, writer);
6396 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
6397 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6398 try a.assign(f, bw);
6399 try f.object.dg.renderUndefValue(bw, payload_ty, .Other);
6400 try a.end(f, bw);
63346401 }
63356402 {
6336 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));
6403 const a = try Assignment.start(f, bw, try f.ctypeFromType(err_ty, .complete));
63376404 if (repr_is_err)
6338 try f.writeCValue(writer, local, .Other)
6405 try f.writeCValue(bw, local, .Other)
63396406 else
6340 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
6341 try a.assign(f, writer);
6342 try f.writeCValue(writer, err, .Other);
6343 try a.end(f, writer);
6407 try f.writeCValueMember(bw, local, .{ .identifier = "error" });
6408 try a.assign(f, bw);
6409 try f.writeCValue(bw, err, .Other);
6410 try a.end(f, bw);
63446411 }
63456412 return local;
63466413}
......@@ -6348,7 +6415,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
63486415fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
63496416 const pt = f.object.dg.pt;
63506417 const zcu = pt.zcu;
6351 const writer = f.object.writer();
6418 const bw = &f.object.code.buffered_writer;
63526419 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63536420 const inst_ty = f.typeOfIndex(inst);
63546421 const operand = try f.resolveInst(ty_op.operand);
......@@ -6362,31 +6429,31 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
63626429
63636430 // First, set the non-error value.
63646431 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
6365 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));
6366 try f.writeCValueDeref(writer, operand);
6367 try a.assign(f, writer);
6368 try writer.print("{}", .{try f.fmtIntLiteral(no_err)});
6369 try a.end(f, writer);
6432 const a = try Assignment.start(f, bw, try f.ctypeFromType(operand_ty, .complete));
6433 try f.writeCValueDeref(bw, operand);
6434 try a.assign(f, bw);
6435 try bw.print("{f}", .{try f.fmtIntLiteral(no_err)});
6436 try a.end(f, bw);
63706437 return .none;
63716438 }
63726439 {
6373 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_int_ty, .complete));
6374 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" });
6375 try a.assign(f, writer);
6376 try writer.print("{}", .{try f.fmtIntLiteral(no_err)});
6377 try a.end(f, writer);
6440 const a = try Assignment.start(f, bw, try f.ctypeFromType(err_int_ty, .complete));
6441 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" });
6442 try a.assign(f, bw);
6443 try bw.print("{f}", .{try f.fmtIntLiteral(no_err)});
6444 try a.end(f, bw);
63786445 }
63796446
63806447 // Then return the payload pointer (only if it is used)
63816448 if (f.liveness.isUnused(inst)) return .none;
63826449
63836450 const local = try f.allocLocal(inst, inst_ty);
6384 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
6385 try f.writeCValue(writer, local, .Other);
6386 try a.assign(f, writer);
6387 try writer.writeByte('&');
6388 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });
6389 try a.end(f, writer);
6451 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6452 try f.writeCValue(bw, local, .Other);
6453 try a.assign(f, bw);
6454 try bw.writeByte('&');
6455 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
6456 try a.end(f, bw);
63906457 return local;
63916458}
63926459
......@@ -6417,24 +6484,24 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
64176484 const err_ty = inst_ty.errorUnionSet(zcu);
64186485 try reap(f, inst, &.{ty_op.operand});
64196486
6420 const writer = f.object.writer();
6487 const bw = &f.object.code.buffered_writer;
64216488 const local = try f.allocLocal(inst, inst_ty);
64226489 if (!repr_is_err) {
6423 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
6424 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6425 try a.assign(f, writer);
6426 try f.writeCValue(writer, payload, .Other);
6427 try a.end(f, writer);
6490 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
6491 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6492 try a.assign(f, bw);
6493 try f.writeCValue(bw, payload, .Other);
6494 try a.end(f, bw);
64286495 }
64296496 {
6430 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));
6497 const a = try Assignment.start(f, bw, try f.ctypeFromType(err_ty, .complete));
64316498 if (repr_is_err)
6432 try f.writeCValue(writer, local, .Other)
6499 try f.writeCValue(bw, local, .Other)
64336500 else
6434 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
6435 try a.assign(f, writer);
6436 try f.object.dg.renderValue(writer, try pt.intValue(try pt.errorIntType(), 0), .Other);
6437 try a.end(f, writer);
6501 try f.writeCValueMember(bw, local, .{ .identifier = "error" });
6502 try a.assign(f, bw);
6503 try f.object.dg.renderValue(bw, try pt.intValue(try pt.errorIntType(), 0), .Other);
6504 try a.end(f, bw);
64386505 }
64396506 return local;
64406507}
......@@ -6444,7 +6511,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
64446511 const zcu = pt.zcu;
64456512 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
64466513
6447 const writer = f.object.writer();
6514 const bw = &f.object.code.buffered_writer;
64486515 const operand = try f.resolveInst(un_op);
64496516 try reap(f, inst, &.{un_op});
64506517 const operand_ty = f.typeOf(un_op);
......@@ -6453,25 +6520,25 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
64536520 const payload_ty = err_union_ty.errorUnionPayload(zcu);
64546521 const error_ty = err_union_ty.errorUnionSet(zcu);
64556522
6456 const a = try Assignment.start(f, writer, .bool);
6457 try f.writeCValue(writer, local, .Other);
6458 try a.assign(f, writer);
6523 const a = try Assignment.start(f, bw, .bool);
6524 try f.writeCValue(bw, local, .Other);
6525 try a.assign(f, bw);
64596526 const err_int_ty = try pt.errorIntType();
64606527 if (!error_ty.errorSetIsEmpty(zcu))
64616528 if (payload_ty.hasRuntimeBits(zcu))
64626529 if (is_ptr)
6463 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
6530 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" })
64646531 else
6465 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
6532 try f.writeCValueMember(bw, operand, .{ .identifier = "error" })
64666533 else
6467 try f.writeCValue(writer, operand, .Other)
6534 try f.writeCValue(bw, operand, .Other)
64686535 else
6469 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);
6470 try writer.writeByte(' ');
6471 try writer.writeAll(operator);
6472 try writer.writeByte(' ');
6473 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);
6474 try a.end(f, writer);
6536 try f.object.dg.renderValue(bw, try pt.intValue(err_int_ty, 0), .Other);
6537 try bw.writeByte(' ');
6538 try bw.writeAll(operator);
6539 try bw.writeByte(' ');
6540 try f.object.dg.renderValue(bw, try pt.intValue(err_int_ty, 0), .Other);
6541 try a.end(f, bw);
64756542 return local;
64766543}
64776544
......@@ -6485,45 +6552,45 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
64856552 try reap(f, inst, &.{ty_op.operand});
64866553 const inst_ty = f.typeOfIndex(inst);
64876554 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
6488 const writer = f.object.writer();
6555 const bw = &f.object.code.buffered_writer;
64896556 const local = try f.allocLocal(inst, inst_ty);
64906557 const operand_ty = f.typeOf(ty_op.operand);
64916558 const array_ty = operand_ty.childType(zcu);
64926559
64936560 {
6494 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));
6495 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });
6496 try a.assign(f, writer);
6561 const a = try Assignment.start(f, bw, try f.ctypeFromType(ptr_ty, .complete));
6562 try f.writeCValueMember(bw, local, .{ .identifier = "ptr" });
6563 try a.assign(f, bw);
64976564 if (operand == .undef) {
6498 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);
6565 try f.writeCValue(bw, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);
64996566 } else {
65006567 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);
65016568 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
65026569 const elem_ty = array_ty.childType(zcu);
65036570 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);
65046571 if (!ptr_child_ctype.eql(elem_ctype)) {
6505 try writer.writeByte('(');
6506 try f.renderCType(writer, ptr_ctype);
6507 try writer.writeByte(')');
6572 try bw.writeByte('(');
6573 try f.renderCType(bw, ptr_ctype);
6574 try bw.writeByte(')');
65086575 }
65096576 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
65106577 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;
65116578 if (operand_child_ctype.info(ctype_pool) == .array) {
6512 try writer.writeByte('&');
6513 try f.writeCValueDeref(writer, operand);
6514 try writer.print("[{}]", .{try f.fmtIntLiteral(.zero_usize)});
6515 } else try f.writeCValue(writer, operand, .Other);
6579 try bw.writeByte('&');
6580 try f.writeCValueDeref(bw, operand);
6581 try bw.print("[{f}]", .{try f.fmtIntLiteral(.zero_usize)});
6582 } else try f.writeCValue(bw, operand, .Other);
65166583 }
6517 try a.end(f, writer);
6584 try a.end(f, bw);
65186585 }
65196586 {
6520 const a = try Assignment.start(f, writer, .usize);
6521 try f.writeCValueMember(writer, local, .{ .identifier = "len" });
6522 try a.assign(f, writer);
6523 try writer.print("{}", .{
6587 const a = try Assignment.start(f, bw, .usize);
6588 try f.writeCValueMember(bw, local, .{ .identifier = "len" });
6589 try a.assign(f, bw);
6590 try bw.print("{f}", .{
65246591 try f.fmtIntLiteral(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
65256592 });
6526 try a.end(f, writer);
6593 try a.end(f, bw);
65276594 }
65286595
65296596 return local;
......@@ -6550,32 +6617,32 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
65506617 else
65516618 unreachable;
65526619
6553 const writer = f.object.writer();
6620 const bw = &f.object.code.buffered_writer;
65546621 const local = try f.allocLocal(inst, inst_ty);
6555 const v = try Vectorize.start(f, inst, writer, operand_ty);
6556 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));
6557 try f.writeCValue(writer, local, .Other);
6558 try v.elem(f, writer);
6559 try a.assign(f, writer);
6622 const v = try Vectorize.start(f, inst, bw, operand_ty);
6623 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
6624 try f.writeCValue(bw, local, .Other);
6625 try v.elem(f, bw);
6626 try a.assign(f, bw);
65606627 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6561 try writer.writeAll("zig_wrap_");
6562 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
6563 try writer.writeByte('(');
6564 }
6565 try writer.writeAll("zig_");
6566 try writer.writeAll(operation);
6567 try writer.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
6568 try writer.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
6569 try writer.writeByte('(');
6570 try f.writeCValue(writer, operand, .FunctionArgument);
6571 try v.elem(f, writer);
6572 try writer.writeByte(')');
6628 try bw.writeAll("zig_wrap_");
6629 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_scalar_ty);
6630 try bw.writeByte('(');
6631 }
6632 try bw.writeAll("zig_");
6633 try bw.writeAll(operation);
6634 try bw.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
6635 try bw.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
6636 try bw.writeByte('(');
6637 try f.writeCValue(bw, operand, .FunctionArgument);
6638 try v.elem(f, bw);
6639 try bw.writeByte(')');
65736640 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6574 try f.object.dg.renderBuiltinInfo(writer, inst_scalar_ty, .bits);
6575 try writer.writeByte(')');
6641 try f.object.dg.renderBuiltinInfo(bw, inst_scalar_ty, .bits);
6642 try bw.writeByte(')');
65766643 }
6577 try a.end(f, writer);
6578 try v.end(f, inst, writer);
6644 try a.end(f, bw);
6645 try v.end(f, inst, bw);
65796646
65806647 return local;
65816648}
......@@ -6600,27 +6667,28 @@ fn airUnBuiltinCall(
66006667 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
66016668 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
66026669
6603 const writer = f.object.writer();
6670 const bw = &f.object.code.buffered_writer;
66046671 const local = try f.allocLocal(inst, inst_ty);
6605 const v = try Vectorize.start(f, inst, writer, operand_ty);
6672 const v = try Vectorize.start(f, inst, bw, operand_ty);
66066673 if (!ref_ret) {
6607 try f.writeCValue(writer, local, .Other);
6608 try v.elem(f, writer);
6609 try writer.writeAll(" = ");
6674 try f.writeCValue(bw, local, .Other);
6675 try v.elem(f, bw);
6676 try bw.writeAll(" = ");
66106677 }
6611 try writer.print("zig_{s}_", .{operation});
6612 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
6613 try writer.writeByte('(');
6678 try bw.print("zig_{s}_", .{operation});
6679 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6680 try bw.writeByte('(');
66146681 if (ref_ret) {
6615 try f.writeCValue(writer, local, .FunctionArgument);
6616 try v.elem(f, writer);
6617 try writer.writeAll(", ");
6682 try f.writeCValue(bw, local, .FunctionArgument);
6683 try v.elem(f, bw);
6684 try bw.writeAll(", ");
66186685 }
6619 try f.writeCValue(writer, operand, .FunctionArgument);
6620 try v.elem(f, writer);
6621 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);
6622 try writer.writeAll(");\n");
6623 try v.end(f, inst, writer);
6686 try f.writeCValue(bw, operand, .FunctionArgument);
6687 try v.elem(f, bw);
6688 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6689 try bw.writeAll(");");
6690 try f.object.newline();
6691 try v.end(f, inst, bw);
66246692
66256693 return local;
66266694}
......@@ -6650,31 +6718,31 @@ fn airBinBuiltinCall(
66506718 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
66516719 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
66526720
6653 const writer = f.object.writer();
6721 const bw = &f.object.code.buffered_writer;
66546722 const local = try f.allocLocal(inst, inst_ty);
66556723 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6656 const v = try Vectorize.start(f, inst, writer, operand_ty);
6724 const v = try Vectorize.start(f, inst, bw, operand_ty);
66576725 if (!ref_ret) {
6658 try f.writeCValue(writer, local, .Other);
6659 try v.elem(f, writer);
6660 try writer.writeAll(" = ");
6726 try f.writeCValue(bw, local, .Other);
6727 try v.elem(f, bw);
6728 try bw.writeAll(" = ");
66616729 }
6662 try writer.print("zig_{s}_", .{operation});
6663 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
6664 try writer.writeByte('(');
6730 try bw.print("zig_{s}_", .{operation});
6731 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6732 try bw.writeByte('(');
66656733 if (ref_ret) {
6666 try f.writeCValue(writer, local, .FunctionArgument);
6667 try v.elem(f, writer);
6668 try writer.writeAll(", ");
6669 }
6670 try f.writeCValue(writer, lhs, .FunctionArgument);
6671 try v.elem(f, writer);
6672 try writer.writeAll(", ");
6673 try f.writeCValue(writer, rhs, .FunctionArgument);
6674 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, writer);
6675 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);
6676 try writer.writeAll(");\n");
6677 try v.end(f, inst, writer);
6734 try f.writeCValue(bw, local, .FunctionArgument);
6735 try v.elem(f, bw);
6736 try bw.writeAll(", ");
6737 }
6738 try f.writeCValue(bw, lhs, .FunctionArgument);
6739 try v.elem(f, bw);
6740 try bw.writeAll(", ");
6741 try f.writeCValue(bw, rhs, .FunctionArgument);
6742 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, bw);
6743 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6744 try bw.writeAll(");\n");
6745 try v.end(f, inst, bw);
66786746
66796747 return local;
66806748}
......@@ -6701,38 +6769,39 @@ fn airCmpBuiltinCall(
67016769 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
67026770 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
67036771
6704 const writer = f.object.writer();
6772 const bw = &f.object.code.buffered_writer;
67056773 const local = try f.allocLocal(inst, inst_ty);
6706 const v = try Vectorize.start(f, inst, writer, operand_ty);
6774 const v = try Vectorize.start(f, inst, bw, operand_ty);
67076775 if (!ref_ret) {
6708 try f.writeCValue(writer, local, .Other);
6709 try v.elem(f, writer);
6710 try writer.writeAll(" = ");
6776 try f.writeCValue(bw, local, .Other);
6777 try v.elem(f, bw);
6778 try bw.writeAll(" = ");
67116779 }
6712 try writer.print("zig_{s}_", .{switch (operation) {
6780 try bw.print("zig_{s}_", .{switch (operation) {
67136781 else => @tagName(operation),
67146782 .operator => compareOperatorAbbrev(operator),
67156783 }});
6716 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
6717 try writer.writeByte('(');
6784 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6785 try bw.writeByte('(');
67186786 if (ref_ret) {
6719 try f.writeCValue(writer, local, .FunctionArgument);
6720 try v.elem(f, writer);
6721 try writer.writeAll(", ");
6722 }
6723 try f.writeCValue(writer, lhs, .FunctionArgument);
6724 try v.elem(f, writer);
6725 try writer.writeAll(", ");
6726 try f.writeCValue(writer, rhs, .FunctionArgument);
6727 try v.elem(f, writer);
6728 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);
6729 try writer.writeByte(')');
6730 if (!ref_ret) try writer.print("{s}{}", .{
6787 try f.writeCValue(bw, local, .FunctionArgument);
6788 try v.elem(f, bw);
6789 try bw.writeAll(", ");
6790 }
6791 try f.writeCValue(bw, lhs, .FunctionArgument);
6792 try v.elem(f, bw);
6793 try bw.writeAll(", ");
6794 try f.writeCValue(bw, rhs, .FunctionArgument);
6795 try v.elem(f, bw);
6796 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6797 try bw.writeByte(')');
6798 if (!ref_ret) try bw.print("{s}{f}", .{
67316799 compareOperatorC(operator),
67326800 try f.fmtIntLiteral(try pt.intValue(.i32, 0)),
67336801 });
6734 try writer.writeAll(";\n");
6735 try v.end(f, inst, writer);
6802 try bw.writeByte(';');
6803 try f.object.newline();
6804 try v.end(f, inst, bw);
67366805
67376806 return local;
67386807}
......@@ -6750,7 +6819,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
67506819 const ty = ptr_ty.childType(zcu);
67516820 const ctype = try f.ctypeFromType(ty, .complete);
67526821
6753 const writer = f.object.writer();
6822 const bw = &f.object.code.buffered_writer;
67546823 const new_value_mat = try Materialize.start(f, inst, ty, new_value);
67556824 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
67566825
......@@ -6762,76 +6831,78 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
67626831 const local = try f.allocLocal(inst, inst_ty);
67636832 if (inst_ty.isPtrLikeOptional(zcu)) {
67646833 {
6765 const a = try Assignment.start(f, writer, ctype);
6766 try f.writeCValue(writer, local, .Other);
6767 try a.assign(f, writer);
6768 try f.writeCValue(writer, expected_value, .Other);
6769 try a.end(f, writer);
6834 const a = try Assignment.start(f, bw, ctype);
6835 try f.writeCValue(bw, local, .Other);
6836 try a.assign(f, bw);
6837 try f.writeCValue(bw, expected_value, .Other);
6838 try a.end(f, bw);
67706839 }
67716840
6772 try writer.writeAll("if (");
6773 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6774 try f.renderType(writer, ty);
6775 try writer.writeByte(')');
6776 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
6777 try writer.writeAll(" *)");
6778 try f.writeCValue(writer, ptr, .Other);
6779 try writer.writeAll(", ");
6780 try f.writeCValue(writer, local, .FunctionArgument);
6781 try writer.writeAll(", ");
6782 try new_value_mat.mat(f, writer);
6783 try writer.writeAll(", ");
6784 try writeMemoryOrder(writer, extra.successOrder());
6785 try writer.writeAll(", ");
6786 try writeMemoryOrder(writer, extra.failureOrder());
6787 try writer.writeAll(", ");
6788 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6789 try writer.writeAll(", ");
6790 try f.renderType(writer, repr_ty);
6791 try writer.writeByte(')');
6792 try writer.writeAll(") {\n");
6793 f.object.indent_writer.pushIndent();
6841 try bw.writeAll("if (");
6842 try bw.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6843 try f.renderType(bw, ty);
6844 try bw.writeByte(')');
6845 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6846 try bw.writeAll(" *)");
6847 try f.writeCValue(bw, ptr, .Other);
6848 try bw.writeAll(", ");
6849 try f.writeCValue(bw, local, .FunctionArgument);
6850 try bw.writeAll(", ");
6851 try new_value_mat.mat(f, bw);
6852 try bw.writeAll(", ");
6853 try writeMemoryOrder(bw, extra.successOrder());
6854 try bw.writeAll(", ");
6855 try writeMemoryOrder(bw, extra.failureOrder());
6856 try bw.writeAll(", ");
6857 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6858 try bw.writeAll(", ");
6859 try f.renderType(bw, repr_ty);
6860 try bw.writeByte(')');
6861 try bw.writeAll(") {");
6862 f.object.indent();
6863 try f.object.newline();
67946864 {
6795 const a = try Assignment.start(f, writer, ctype);
6796 try f.writeCValue(writer, local, .Other);
6797 try a.assign(f, writer);
6798 try writer.writeAll("NULL");
6799 try a.end(f, writer);
6865 const a = try Assignment.start(f, bw, ctype);
6866 try f.writeCValue(bw, local, .Other);
6867 try a.assign(f, bw);
6868 try bw.writeAll("NULL");
6869 try a.end(f, bw);
68006870 }
6801 f.object.indent_writer.popIndent();
6802 try writer.writeAll("}\n");
6871 f.object.outdent();
6872 try bw.writeByte('}');
6873 try f.object.newline();
68036874 } else {
68046875 {
6805 const a = try Assignment.start(f, writer, ctype);
6806 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6807 try a.assign(f, writer);
6808 try f.writeCValue(writer, expected_value, .Other);
6809 try a.end(f, writer);
6876 const a = try Assignment.start(f, bw, ctype);
6877 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6878 try a.assign(f, bw);
6879 try f.writeCValue(bw, expected_value, .Other);
6880 try a.end(f, bw);
68106881 }
68116882 {
6812 const a = try Assignment.start(f, writer, .bool);
6813 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });
6814 try a.assign(f, writer);
6815 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6816 try f.renderType(writer, ty);
6817 try writer.writeByte(')');
6818 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
6819 try writer.writeAll(" *)");
6820 try f.writeCValue(writer, ptr, .Other);
6821 try writer.writeAll(", ");
6822 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
6823 try writer.writeAll(", ");
6824 try new_value_mat.mat(f, writer);
6825 try writer.writeAll(", ");
6826 try writeMemoryOrder(writer, extra.successOrder());
6827 try writer.writeAll(", ");
6828 try writeMemoryOrder(writer, extra.failureOrder());
6829 try writer.writeAll(", ");
6830 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6831 try writer.writeAll(", ");
6832 try f.renderType(writer, repr_ty);
6833 try writer.writeByte(')');
6834 try a.end(f, writer);
6883 const a = try Assignment.start(f, bw, .bool);
6884 try f.writeCValueMember(bw, local, .{ .identifier = "is_null" });
6885 try a.assign(f, bw);
6886 try bw.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6887 try f.renderType(bw, ty);
6888 try bw.writeByte(')');
6889 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6890 try bw.writeAll(" *)");
6891 try f.writeCValue(bw, ptr, .Other);
6892 try bw.writeAll(", ");
6893 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6894 try bw.writeAll(", ");
6895 try new_value_mat.mat(f, bw);
6896 try bw.writeAll(", ");
6897 try writeMemoryOrder(bw, extra.successOrder());
6898 try bw.writeAll(", ");
6899 try writeMemoryOrder(bw, extra.failureOrder());
6900 try bw.writeAll(", ");
6901 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6902 try bw.writeAll(", ");
6903 try f.renderType(bw, repr_ty);
6904 try bw.writeByte(')');
6905 try a.end(f, bw);
68356906 }
68366907 }
68376908 try new_value_mat.end(f, inst);
......@@ -6855,7 +6926,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
68556926 const ptr = try f.resolveInst(pl_op.operand);
68566927 const operand = try f.resolveInst(extra.operand);
68576928
6858 const writer = f.object.writer();
6929 const bw = &f.object.code.buffered_writer;
68596930 const operand_mat = try Materialize.start(f, inst, ty, operand);
68606931 try reap(f, inst, &.{ pl_op.operand, extra.operand });
68616932
......@@ -6865,31 +6936,32 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
68656936 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;
68666937
68676938 const local = try f.allocLocal(inst, inst_ty);
6868 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6869 if (is_float) try writer.writeAll("_float") else if (is_128) try writer.writeAll("_int128");
6870 try writer.writeByte('(');
6871 try f.writeCValue(writer, local, .Other);
6872 try writer.writeAll(", (");
6939 try bw.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6940 if (is_float) try bw.writeAll("_float") else if (is_128) try bw.writeAll("_int128");
6941 try bw.writeByte('(');
6942 try f.writeCValue(bw, local, .Other);
6943 try bw.writeAll(", (");
68736944 const use_atomic = switch (extra.op()) {
68746945 else => true,
68756946 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.
68766947 .Nand, .Min, .Max => is_float or is_128,
68776948 };
6878 if (use_atomic) try writer.writeAll("zig_atomic(");
6879 try f.renderType(writer, ty);
6880 if (use_atomic) try writer.writeByte(')');
6881 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
6882 try writer.writeAll(" *)");
6883 try f.writeCValue(writer, ptr, .Other);
6884 try writer.writeAll(", ");
6885 try operand_mat.mat(f, writer);
6886 try writer.writeAll(", ");
6887 try writeMemoryOrder(writer, extra.ordering());
6888 try writer.writeAll(", ");
6889 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6890 try writer.writeAll(", ");
6891 try f.renderType(writer, repr_ty);
6892 try writer.writeAll(");\n");
6949 if (use_atomic) try bw.writeAll("zig_atomic(");
6950 try f.renderType(bw, ty);
6951 if (use_atomic) try bw.writeByte(')');
6952 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6953 try bw.writeAll(" *)");
6954 try f.writeCValue(bw, ptr, .Other);
6955 try bw.writeAll(", ");
6956 try operand_mat.mat(f, bw);
6957 try bw.writeAll(", ");
6958 try writeMemoryOrder(bw, extra.ordering());
6959 try bw.writeAll(", ");
6960 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6961 try bw.writeAll(", ");
6962 try f.renderType(bw, repr_ty);
6963 try bw.writeAll(");");
6964 try f.object.newline();
68936965 try operand_mat.end(f, inst);
68946966
68956967 if (f.liveness.isUnused(inst)) {
......@@ -6915,24 +6987,25 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
69156987 ty;
69166988
69176989 const inst_ty = f.typeOfIndex(inst);
6918 const writer = f.object.writer();
6990 const bw = &f.object.code.buffered_writer;
69196991 const local = try f.allocLocal(inst, inst_ty);
69206992
6921 try writer.writeAll("zig_atomic_load(");
6922 try f.writeCValue(writer, local, .Other);
6923 try writer.writeAll(", (zig_atomic(");
6924 try f.renderType(writer, ty);
6925 try writer.writeByte(')');
6926 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
6927 try writer.writeAll(" *)");
6928 try f.writeCValue(writer, ptr, .Other);
6929 try writer.writeAll(", ");
6930 try writeMemoryOrder(writer, atomic_load.order);
6931 try writer.writeAll(", ");
6932 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6933 try writer.writeAll(", ");
6934 try f.renderType(writer, repr_ty);
6935 try writer.writeAll(");\n");
6993 try bw.writeAll("zig_atomic_load(");
6994 try f.writeCValue(bw, local, .Other);
6995 try bw.writeAll(", (zig_atomic(");
6996 try f.renderType(bw, ty);
6997 try bw.writeByte(')');
6998 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6999 try bw.writeAll(" *)");
7000 try f.writeCValue(bw, ptr, .Other);
7001 try bw.writeAll(", ");
7002 try writeMemoryOrder(bw, atomic_load.order);
7003 try bw.writeAll(", ");
7004 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
7005 try bw.writeAll(", ");
7006 try f.renderType(bw, repr_ty);
7007 try bw.writeAll(");");
7008 try f.object.newline();
69367009
69377010 return local;
69387011}
......@@ -6946,7 +7019,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
69467019 const ptr = try f.resolveInst(bin_op.lhs);
69477020 const element = try f.resolveInst(bin_op.rhs);
69487021
6949 const writer = f.object.writer();
7022 const bw = &f.object.code.buffered_writer;
69507023 const element_mat = try Materialize.start(f, inst, ty, element);
69517024 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
69527025
......@@ -6955,31 +7028,32 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
69557028 else
69567029 ty;
69577030
6958 try writer.writeAll("zig_atomic_store((zig_atomic(");
6959 try f.renderType(writer, ty);
6960 try writer.writeByte(')');
6961 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");
6962 try writer.writeAll(" *)");
6963 try f.writeCValue(writer, ptr, .Other);
6964 try writer.writeAll(", ");
6965 try element_mat.mat(f, writer);
6966 try writer.print(", {s}, ", .{order});
6967 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);
6968 try writer.writeAll(", ");
6969 try f.renderType(writer, repr_ty);
6970 try writer.writeAll(");\n");
7031 try bw.writeAll("zig_atomic_store((zig_atomic(");
7032 try f.renderType(bw, ty);
7033 try bw.writeByte(')');
7034 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
7035 try bw.writeAll(" *)");
7036 try f.writeCValue(bw, ptr, .Other);
7037 try bw.writeAll(", ");
7038 try element_mat.mat(f, bw);
7039 try bw.print(", {s}, ", .{order});
7040 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
7041 try bw.writeAll(", ");
7042 try f.renderType(bw, repr_ty);
7043 try bw.writeAll(");");
7044 try f.object.newline();
69717045 try element_mat.end(f, inst);
69727046
69737047 return .none;
69747048}
69757049
6976fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {
7050fn writeSliceOrPtr(f: *Function, bw: *std.io.BufferedWriter, ptr: CValue, ptr_ty: Type) !void {
69777051 const pt = f.object.dg.pt;
69787052 const zcu = pt.zcu;
69797053 if (ptr_ty.isSlice(zcu)) {
6980 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });
7054 try f.writeCValueMember(bw, ptr, .{ .identifier = "ptr" });
69817055 } else {
6982 try f.writeCValue(writer, ptr, .FunctionArgument);
7056 try f.writeCValue(bw, ptr, .FunctionArgument);
69837057 }
69847058}
69857059
......@@ -6993,7 +7067,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
69937067 const elem_ty = f.typeOf(bin_op.rhs);
69947068 const elem_abi_size = elem_ty.abiSize(zcu);
69957069 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false;
6996 const writer = f.object.writer();
7070 const bw = &f.object.code.buffered_writer;
69977071
69987072 if (val_is_undef) {
69997073 if (!safety) {
......@@ -7001,24 +7075,25 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70017075 return .none;
70027076 }
70037077
7004 try writer.writeAll("memset(");
7078 try bw.writeAll("memset(");
70057079 switch (dest_ty.ptrSize(zcu)) {
70067080 .slice => {
7007 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });
7008 try writer.writeAll(", 0xaa, ");
7009 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });
7081 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "ptr" });
7082 try bw.writeAll(", 0xaa, ");
7083 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
70107084 if (elem_abi_size > 1) {
7011 try writer.print(" * {d});\n", .{elem_abi_size});
7012 } else {
7013 try writer.writeAll(");\n");
7085 try bw.print(" * {d}", .{elem_abi_size});
70147086 }
7087 try bw.writeAll(");");
7088 try f.object.newline();
70157089 },
70167090 .one => {
70177091 const array_ty = dest_ty.childType(zcu);
70187092 const len = array_ty.arrayLen(zcu) * elem_abi_size;
70197093
7020 try f.writeCValue(writer, dest_slice, .FunctionArgument);
7021 try writer.print(", 0xaa, {d});\n", .{len});
7094 try f.writeCValue(bw, dest_slice, .FunctionArgument);
7095 try bw.print(", 0xaa, {d});", .{len});
7096 try f.object.newline();
70227097 },
70237098 .many, .c => unreachable,
70247099 }
......@@ -7039,38 +7114,38 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70397114
70407115 const index = try f.allocLocal(inst, .usize);
70417116
7042 try writer.writeAll("for (");
7043 try f.writeCValue(writer, index, .Other);
7044 try writer.writeAll(" = ");
7045 try f.object.dg.renderValue(writer, .zero_usize, .Other);
7046 try writer.writeAll("; ");
7047 try f.writeCValue(writer, index, .Other);
7048 try writer.writeAll(" != ");
7117 try bw.writeAll("for (");
7118 try f.writeCValue(bw, index, .Other);
7119 try bw.writeAll(" = ");
7120 try f.object.dg.renderValue(bw, .zero_usize, .Other);
7121 try bw.writeAll("; ");
7122 try f.writeCValue(bw, index, .Other);
7123 try bw.writeAll(" != ");
70497124 switch (dest_ty.ptrSize(zcu)) {
70507125 .slice => {
7051 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });
7126 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
70527127 },
70537128 .one => {
70547129 const array_ty = dest_ty.childType(zcu);
7055 try writer.print("{d}", .{array_ty.arrayLen(zcu)});
7130 try bw.print("{d}", .{array_ty.arrayLen(zcu)});
70567131 },
70577132 .many, .c => unreachable,
70587133 }
7059 try writer.writeAll("; ++");
7060 try f.writeCValue(writer, index, .Other);
7061 try writer.writeAll(") ");
7062
7063 const a = try Assignment.start(f, writer, try f.ctypeFromType(elem_ty, .complete));
7064 try writer.writeAll("((");
7065 try f.renderType(writer, elem_ptr_ty);
7066 try writer.writeByte(')');
7067 try writeSliceOrPtr(f, writer, dest_slice, dest_ty);
7068 try writer.writeAll(")[");
7069 try f.writeCValue(writer, index, .Other);
7070 try writer.writeByte(']');
7071 try a.assign(f, writer);
7072 try f.writeCValue(writer, value, .Other);
7073 try a.end(f, writer);
7134 try bw.writeAll("; ++");
7135 try f.writeCValue(bw, index, .Other);
7136 try bw.writeAll(") ");
7137
7138 const a = try Assignment.start(f, bw, try f.ctypeFromType(elem_ty, .complete));
7139 try bw.writeAll("((");
7140 try f.renderType(bw, elem_ptr_ty);
7141 try bw.writeByte(')');
7142 try writeSliceOrPtr(f, bw, dest_slice, dest_ty);
7143 try bw.writeAll(")[");
7144 try f.writeCValue(bw, index, .Other);
7145 try bw.writeByte(']');
7146 try a.assign(f, bw);
7147 try f.writeCValue(bw, value, .Other);
7148 try a.end(f, bw);
70747149
70757150 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
70767151 try freeLocal(f, inst, index.new_local, null);
......@@ -7080,24 +7155,26 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70807155
70817156 const bitcasted = try bitcast(f, .u8, value, elem_ty);
70827157
7083 try writer.writeAll("memset(");
7158 try bw.writeAll("memset(");
70847159 switch (dest_ty.ptrSize(zcu)) {
70857160 .slice => {
7086 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });
7087 try writer.writeAll(", ");
7088 try f.writeCValue(writer, bitcasted, .FunctionArgument);
7089 try writer.writeAll(", ");
7090 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });
7091 try writer.writeAll(");\n");
7161 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "ptr" });
7162 try bw.writeAll(", ");
7163 try f.writeCValue(bw, bitcasted, .FunctionArgument);
7164 try bw.writeAll(", ");
7165 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
7166 try bw.writeAll(");");
7167 try f.object.newline();
70927168 },
70937169 .one => {
70947170 const array_ty = dest_ty.childType(zcu);
70957171 const len = array_ty.arrayLen(zcu) * elem_abi_size;
70967172
7097 try f.writeCValue(writer, dest_slice, .FunctionArgument);
7098 try writer.writeAll(", ");
7099 try f.writeCValue(writer, bitcasted, .FunctionArgument);
7100 try writer.print(", {d});\n", .{len});
7173 try f.writeCValue(bw, dest_slice, .FunctionArgument);
7174 try bw.writeAll(", ");
7175 try f.writeCValue(bw, bitcasted, .FunctionArgument);
7176 try bw.print(", {d});", .{len});
7177 try f.object.newline();
71017178 },
71027179 .many, .c => unreachable,
71037180 }
......@@ -7114,22 +7191,23 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV
71147191 const src_ptr = try f.resolveInst(bin_op.rhs);
71157192 const dest_ty = f.typeOf(bin_op.lhs);
71167193 const src_ty = f.typeOf(bin_op.rhs);
7117 const writer = f.object.writer();
7194 const bw = &f.object.code.buffered_writer;
71187195
71197196 if (dest_ty.ptrSize(zcu) != .one) {
7120 try writer.writeAll("if (");
7121 try writeArrayLen(f, writer, dest_ptr, dest_ty);
7122 try writer.writeAll(" != 0) ");
7123 }
7124 try writer.writeAll(function_paren);
7125 try writeSliceOrPtr(f, writer, dest_ptr, dest_ty);
7126 try writer.writeAll(", ");
7127 try writeSliceOrPtr(f, writer, src_ptr, src_ty);
7128 try writer.writeAll(", ");
7129 try writeArrayLen(f, writer, dest_ptr, dest_ty);
7130 try writer.writeAll(" * sizeof(");
7131 try f.renderType(writer, dest_ty.elemType2(zcu));
7132 try writer.writeAll("));\n");
7197 try bw.writeAll("if (");
7198 try writeArrayLen(f, dest_ptr, dest_ty);
7199 try bw.writeAll(" != 0) ");
7200 }
7201 try bw.writeAll(function_paren);
7202 try writeSliceOrPtr(f, bw, dest_ptr, dest_ty);
7203 try bw.writeAll(", ");
7204 try writeSliceOrPtr(f, bw, src_ptr, src_ty);
7205 try bw.writeAll(", ");
7206 try writeArrayLen(f, dest_ptr, dest_ty);
7207 try bw.writeAll(" * sizeof(");
7208 try f.renderType(bw, dest_ty.elemType2(zcu));
7209 try bw.writeAll("));");
7210 try f.object.newline();
71337211
71347212 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
71357213 return .none;
......@@ -7138,13 +7216,13 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV
71387216fn writeArrayLen(f: *Function, dest_ptr: CValue, dest_ty: Type) !void {
71397217 const pt = f.object.dg.pt;
71407218 const zcu = pt.zcu;
7141 const writer = f.object.writer();
7219 const bw = &f.object.code.buffered_writer;
71427220 switch (dest_ty.ptrSize(zcu)) {
7143 .one => try writer.print("{}", .{
7221 .one => try bw.print("{f}", .{
71447222 try f.fmtIntLiteral(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),
71457223 }),
71467224 .many, .c => unreachable,
7147 .slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),
7225 .slice => try f.writeCValueMember(bw, dest_ptr, .{ .identifier = "len" }),
71487226 }
71497227}
71507228
......@@ -7161,12 +7239,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
71617239 if (layout.tag_size == 0) return .none;
71627240 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
71637241
7164 const writer = f.object.writer();
7165 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));
7166 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });
7167 try a.assign(f, writer);
7168 try f.writeCValue(writer, new_tag, .Other);
7169 try a.end(f, writer);
7242 const bw = &f.object.code.buffered_writer;
7243 const a = try Assignment.start(f, bw, try f.ctypeFromType(tag_ty, .complete));
7244 try f.writeCValueDerefMember(bw, union_ptr, .{ .identifier = "tag" });
7245 try a.assign(f, bw);
7246 try f.writeCValue(bw, new_tag, .Other);
7247 try a.end(f, bw);
71707248 return .none;
71717249}
71727250
......@@ -7183,13 +7261,13 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
71837261 if (layout.tag_size == 0) return .none;
71847262
71857263 const inst_ty = f.typeOfIndex(inst);
7186 const writer = f.object.writer();
7264 const bw = &f.object.code.buffered_writer;
71877265 const local = try f.allocLocal(inst, inst_ty);
7188 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));
7189 try f.writeCValue(writer, local, .Other);
7190 try a.assign(f, writer);
7191 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });
7192 try a.end(f, writer);
7266 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
7267 try f.writeCValue(bw, local, .Other);
7268 try a.assign(f, bw);
7269 try f.writeCValueMember(bw, operand, .{ .identifier = "tag" });
7270 try a.end(f, bw);
71937271 return local;
71947272}
71957273
......@@ -7201,14 +7279,15 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
72017279 const operand = try f.resolveInst(un_op);
72027280 try reap(f, inst, &.{un_op});
72037281
7204 const writer = f.object.writer();
7282 const bw = &f.object.code.buffered_writer;
72057283 const local = try f.allocLocal(inst, inst_ty);
7206 try f.writeCValue(writer, local, .Other);
7207 try writer.print(" = {s}(", .{
7284 try f.writeCValue(bw, local, .Other);
7285 try bw.print(" = {s}(", .{
72087286 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),
72097287 });
7210 try f.writeCValue(writer, operand, .Other);
7211 try writer.writeAll(");\n");
7288 try f.writeCValue(bw, operand, .Other);
7289 try bw.writeAll(");");
7290 try f.object.newline();
72127291
72137292 return local;
72147293}
......@@ -7216,16 +7295,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
72167295fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
72177296 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
72187297
7219 const writer = f.object.writer();
7298 const bw = &f.object.code.buffered_writer;
72207299 const inst_ty = f.typeOfIndex(inst);
72217300 const operand = try f.resolveInst(un_op);
72227301 try reap(f, inst, &.{un_op});
72237302 const local = try f.allocLocal(inst, inst_ty);
7224 try f.writeCValue(writer, local, .Other);
7303 try f.writeCValue(bw, local, .Other);
72257304
7226 try writer.writeAll(" = zig_errorName[");
7227 try f.writeCValue(writer, operand, .Other);
7228 try writer.writeAll(" - 1];\n");
7305 try bw.writeAll(" = zig_errorName[");
7306 try f.writeCValue(bw, operand, .Other);
7307 try bw.writeAll(" - 1];");
7308 try f.object.newline();
72297309 return local;
72307310}
72317311
......@@ -7240,16 +7320,16 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
72407320 const inst_ty = f.typeOfIndex(inst);
72417321 const inst_scalar_ty = inst_ty.scalarType(zcu);
72427322
7243 const writer = f.object.writer();
7323 const bw = &f.object.code.buffered_writer;
72447324 const local = try f.allocLocal(inst, inst_ty);
7245 const v = try Vectorize.start(f, inst, writer, inst_ty);
7246 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));
7247 try f.writeCValue(writer, local, .Other);
7248 try v.elem(f, writer);
7249 try a.assign(f, writer);
7250 try f.writeCValue(writer, operand, .Other);
7251 try a.end(f, writer);
7252 try v.end(f, inst, writer);
7325 const v = try Vectorize.start(f, inst, bw, inst_ty);
7326 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_scalar_ty, .complete));
7327 try f.writeCValue(bw, local, .Other);
7328 try v.elem(f, bw);
7329 try a.assign(f, bw);
7330 try f.writeCValue(bw, operand, .Other);
7331 try a.end(f, bw);
7332 try v.end(f, inst, bw);
72537333
72547334 return local;
72557335}
......@@ -7265,22 +7345,23 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
72657345
72667346 const inst_ty = f.typeOfIndex(inst);
72677347
7268 const writer = f.object.writer();
7348 const bw = &f.object.code.buffered_writer;
72697349 const local = try f.allocLocal(inst, inst_ty);
7270 const v = try Vectorize.start(f, inst, writer, inst_ty);
7271 try f.writeCValue(writer, local, .Other);
7272 try v.elem(f, writer);
7273 try writer.writeAll(" = ");
7274 try f.writeCValue(writer, pred, .Other);
7275 try v.elem(f, writer);
7276 try writer.writeAll(" ? ");
7277 try f.writeCValue(writer, lhs, .Other);
7278 try v.elem(f, writer);
7279 try writer.writeAll(" : ");
7280 try f.writeCValue(writer, rhs, .Other);
7281 try v.elem(f, writer);
7282 try writer.writeAll(";\n");
7283 try v.end(f, inst, writer);
7350 const v = try Vectorize.start(f, inst, bw, inst_ty);
7351 try f.writeCValue(bw, local, .Other);
7352 try v.elem(f, bw);
7353 try bw.writeAll(" = ");
7354 try f.writeCValue(bw, pred, .Other);
7355 try v.elem(f, bw);
7356 try bw.writeAll(" ? ");
7357 try f.writeCValue(bw, lhs, .Other);
7358 try v.elem(f, bw);
7359 try bw.writeAll(" : ");
7360 try f.writeCValue(bw, rhs, .Other);
7361 try v.elem(f, bw);
7362 try bw.writeByte(';');
7363 try f.object.newline();
7364 try v.end(f, inst, bw);
72847365
72857366 return local;
72867367}
......@@ -7294,24 +7375,24 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
72947375 const operand = try f.resolveInst(unwrapped.operand);
72957376 const inst_ty = unwrapped.result_ty;
72967377
7297 const writer = f.object.writer();
7378 const bw = &f.object.code.buffered_writer;
72987379 const local = try f.allocLocal(inst, inst_ty);
72997380 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
73007381 for (mask, 0..) |mask_elem, out_idx| {
7301 try f.writeCValue(writer, local, .Other);
7302 try writer.writeByte('[');
7303 try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other);
7304 try writer.writeAll("] = ");
7382 try f.writeCValue(bw, local, .Other);
7383 try bw.writeByte('[');
7384 try f.object.dg.renderValue(bw, try pt.intValue(.usize, out_idx), .Other);
7385 try bw.writeAll("] = ");
73057386 switch (mask_elem.unwrap()) {
73067387 .elem => |src_idx| {
7307 try f.writeCValue(writer, operand, .Other);
7308 try writer.writeByte('[');
7309 try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other);
7310 try writer.writeByte(']');
7388 try f.writeCValue(bw, operand, .Other);
7389 try bw.writeByte('[');
7390 try f.object.dg.renderValue(bw, try pt.intValue(.usize, src_idx), .Other);
7391 try bw.writeByte(']');
73117392 },
7312 .value => |val| try f.object.dg.renderValue(writer, .fromInterned(val), .Other),
7393 .value => |val| try f.object.dg.renderValue(bw, .fromInterned(val), .Other),
73137394 }
7314 try writer.writeAll(";\n");
7395 try bw.writeAll(";\n");
73157396 }
73167397
73177398 return local;
......@@ -7328,7 +7409,7 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
73287409 const inst_ty = unwrapped.result_ty;
73297410 const elem_ty = inst_ty.childType(zcu);
73307411
7331 const writer = f.object.writer();
7412 const writer = &f.object.code.buffered_writer;
73327413 const local = try f.allocLocal(inst, inst_ty);
73337414 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands
73347415 for (mask, 0..) |mask_elem, out_idx| {
......@@ -7366,7 +7447,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
73667447 const operand = try f.resolveInst(reduce.operand);
73677448 try reap(f, inst, &.{reduce.operand});
73687449 const operand_ty = f.typeOf(reduce.operand);
7369 const writer = f.object.writer();
7450 const bw = &f.object.code.buffered_writer;
73707451
73717452 const use_operator = scalar_ty.bitSize(zcu) <= 64;
73727453 const op: union(enum) {
......@@ -7413,10 +7494,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
74137494 // }
74147495
74157496 const accum = try f.allocLocal(inst, scalar_ty);
7416 try f.writeCValue(writer, accum, .Other);
7417 try writer.writeAll(" = ");
7497 try f.writeCValue(bw, accum, .Other);
7498 try bw.writeAll(" = ");
74187499
7419 try f.object.dg.renderValue(writer, switch (reduce.operation) {
7500 try f.object.dg.renderValue(bw, switch (reduce.operation) {
74207501 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
74217502 .bool => Value.false,
74227503 .int => try pt.intValue(scalar_ty, 0),
......@@ -7453,42 +7534,44 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
74537534 else => unreachable,
74547535 },
74557536 }, .Other);
7456 try writer.writeAll(";\n");
7537 try bw.writeByte(';');
7538 try f.object.newline();
74577539
7458 const v = try Vectorize.start(f, inst, writer, operand_ty);
7459 try f.writeCValue(writer, accum, .Other);
7540 const v = try Vectorize.start(f, inst, bw, operand_ty);
7541 try f.writeCValue(bw, accum, .Other);
74607542 switch (op) {
74617543 .builtin => |func| {
7462 try writer.print(" = zig_{s}_", .{func.operation});
7463 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
7464 try writer.writeByte('(');
7465 try f.writeCValue(writer, accum, .FunctionArgument);
7466 try writer.writeAll(", ");
7467 try f.writeCValue(writer, operand, .Other);
7468 try v.elem(f, writer);
7469 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, func.info);
7470 try writer.writeByte(')');
7544 try bw.print(" = zig_{s}_", .{func.operation});
7545 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
7546 try bw.writeByte('(');
7547 try f.writeCValue(bw, accum, .FunctionArgument);
7548 try bw.writeAll(", ");
7549 try f.writeCValue(bw, operand, .Other);
7550 try v.elem(f, bw);
7551 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, func.info);
7552 try bw.writeByte(')');
74717553 },
74727554 .infix => |ass| {
7473 try writer.writeAll(ass);
7474 try f.writeCValue(writer, operand, .Other);
7475 try v.elem(f, writer);
7555 try bw.writeAll(ass);
7556 try f.writeCValue(bw, operand, .Other);
7557 try v.elem(f, bw);
74767558 },
74777559 .ternary => |cmp| {
7478 try writer.writeAll(" = ");
7479 try f.writeCValue(writer, accum, .Other);
7480 try writer.writeAll(cmp);
7481 try f.writeCValue(writer, operand, .Other);
7482 try v.elem(f, writer);
7483 try writer.writeAll(" ? ");
7484 try f.writeCValue(writer, accum, .Other);
7485 try writer.writeAll(" : ");
7486 try f.writeCValue(writer, operand, .Other);
7487 try v.elem(f, writer);
7560 try bw.writeAll(" = ");
7561 try f.writeCValue(bw, accum, .Other);
7562 try bw.writeAll(cmp);
7563 try f.writeCValue(bw, operand, .Other);
7564 try v.elem(f, bw);
7565 try bw.writeAll(" ? ");
7566 try f.writeCValue(bw, accum, .Other);
7567 try bw.writeAll(" : ");
7568 try f.writeCValue(bw, operand, .Other);
7569 try v.elem(f, bw);
74887570 },
74897571 }
7490 try writer.writeAll(";\n");
7491 try v.end(f, inst, writer);
7572 try bw.writeByte(';');
7573 try f.object.newline();
7574 try v.end(f, inst, bw);
74927575
74937576 return accum;
74947577}
......@@ -7514,7 +7597,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
75147597 }
75157598 }
75167599
7517 const writer = f.object.writer();
7600 const bw = &f.object.code.buffered_writer;
75187601 const local = try f.allocLocal(inst, inst_ty);
75197602 switch (ip.indexToKey(inst_ty.toIntern())) {
75207603 inline .array_type, .vector_type => |info, tag| {
......@@ -7522,20 +7605,20 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
75227605 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),
75237606 };
75247607 for (resolved_elements, 0..) |element, i| {
7525 try a.restart(f, writer);
7526 try f.writeCValue(writer, local, .Other);
7527 try writer.print("[{d}]", .{i});
7528 try a.assign(f, writer);
7529 try f.writeCValue(writer, element, .Other);
7530 try a.end(f, writer);
7608 try a.restart(f, bw);
7609 try f.writeCValue(bw, local, .Other);
7610 try bw.print("[{d}]", .{i});
7611 try a.assign(f, bw);
7612 try f.writeCValue(bw, element, .Other);
7613 try a.end(f, bw);
75317614 }
75327615 if (tag == .array_type and info.sentinel != .none) {
7533 try a.restart(f, writer);
7534 try f.writeCValue(writer, local, .Other);
7535 try writer.print("[{d}]", .{info.len});
7536 try a.assign(f, writer);
7537 try f.object.dg.renderValue(writer, Value.fromInterned(info.sentinel), .Other);
7538 try a.end(f, writer);
7616 try a.restart(f, bw);
7617 try f.writeCValue(bw, local, .Other);
7618 try bw.print("[{d}]", .{info.len});
7619 try a.assign(f, bw);
7620 try f.object.dg.renderValue(bw, Value.fromInterned(info.sentinel), .Other);
7621 try a.end(f, bw);
75397622 }
75407623 },
75417624 .struct_type => {
......@@ -7547,19 +7630,19 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
75477630 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
75487631 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75497632
7550 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
7551 try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
7633 const a = try Assignment.start(f, bw, try f.ctypeFromType(field_ty, .complete));
7634 try f.writeCValueMember(bw, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
75527635 .{ .identifier = field_name.toSlice(ip) }
75537636 else
75547637 .{ .field = field_index });
7555 try a.assign(f, writer);
7556 try f.writeCValue(writer, resolved_elements[field_index], .Other);
7557 try a.end(f, writer);
7638 try a.assign(f, bw);
7639 try f.writeCValue(bw, resolved_elements[field_index], .Other);
7640 try a.end(f, bw);
75587641 }
75597642 },
75607643 .@"packed" => {
7561 try f.writeCValue(writer, local, .Other);
7562 try writer.writeAll(" = ");
7644 try f.writeCValue(bw, local, .Other);
7645 try bw.writeAll(" = ");
75637646
75647647 const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));
75657648 const int_info = backing_int_ty.intInfo(zcu);
......@@ -7575,9 +7658,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
75757658 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75767659
75777660 if (!empty) {
7578 try writer.writeAll("zig_or_");
7579 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
7580 try writer.writeByte('(');
7661 try bw.writeAll("zig_or_");
7662 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7663 try bw.writeByte('(');
75817664 }
75827665 empty = false;
75837666 }
......@@ -7587,57 +7670,58 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
75877670 const field_ty = inst_ty.fieldType(field_index, zcu);
75887671 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75897672
7590 if (!empty) try writer.writeAll(", ");
7673 if (!empty) try bw.writeAll(", ");
75917674 // TODO: Skip this entire shift if val is 0?
7592 try writer.writeAll("zig_shlw_");
7593 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
7594 try writer.writeByte('(');
7675 try bw.writeAll("zig_shlw_");
7676 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7677 try bw.writeByte('(');
75957678
75967679 if (field_ty.isAbiInt(zcu)) {
7597 try writer.writeAll("zig_and_");
7598 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
7599 try writer.writeByte('(');
7680 try bw.writeAll("zig_and_");
7681 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7682 try bw.writeByte('(');
76007683 }
76017684
76027685 if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {
7603 try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);
7686 try f.renderIntCast(bw, inst_ty, element, .{}, field_ty, .FunctionArgument);
76047687 } else {
7605 try writer.writeByte('(');
7606 try f.renderType(writer, inst_ty);
7607 try writer.writeByte(')');
7688 try bw.writeByte('(');
7689 try f.renderType(bw, inst_ty);
7690 try bw.writeByte(')');
76087691 if (field_ty.isPtrAtRuntime(zcu)) {
7609 try writer.writeByte('(');
7610 try f.renderType(writer, switch (int_info.signedness) {
7692 try bw.writeByte('(');
7693 try f.renderType(bw, switch (int_info.signedness) {
76117694 .unsigned => .usize,
76127695 .signed => .isize,
76137696 });
7614 try writer.writeByte(')');
7697 try bw.writeByte(')');
76157698 }
7616 try f.writeCValue(writer, element, .Other);
7699 try f.writeCValue(bw, element, .Other);
76177700 }
76187701
76197702 if (field_ty.isAbiInt(zcu)) {
7620 try writer.writeAll(", ");
7703 try bw.writeAll(", ");
76217704 const field_int_info = field_ty.intInfo(zcu);
76227705 const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)
76237706 try pt.intValue(backing_int_ty, -1)
76247707 else
76257708 try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);
7626 try f.object.dg.renderValue(writer, field_mask, .FunctionArgument);
7627 try writer.writeByte(')');
7709 try f.object.dg.renderValue(bw, field_mask, .FunctionArgument);
7710 try bw.writeByte(')');
76287711 }
76297712
7630 try writer.print(", {}", .{
7713 try bw.print(", {f}", .{
76317714 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
76327715 });
7633 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);
7634 try writer.writeByte(')');
7635 if (!empty) try writer.writeByte(')');
7716 try f.object.dg.renderBuiltinInfo(bw, inst_ty, .bits);
7717 try bw.writeByte(')');
7718 if (!empty) try bw.writeByte(')');
76367719
76377720 bit_offset += field_ty.bitSize(zcu);
76387721 empty = false;
76397722 }
7640 try writer.writeAll(";\n");
7723 try bw.writeByte(';');
7724 try f.object.newline();
76417725 },
76427726 }
76437727 },
......@@ -7646,11 +7730,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
76467730 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
76477731 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
76487732
7649 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));
7650 try f.writeCValueMember(writer, local, .{ .field = field_index });
7651 try a.assign(f, writer);
7652 try f.writeCValue(writer, resolved_elements[field_index], .Other);
7653 try a.end(f, writer);
7733 const a = try Assignment.start(f, bw, try f.ctypeFromType(field_ty, .complete));
7734 try f.writeCValueMember(bw, local, .{ .field = field_index });
7735 try a.assign(f, bw);
7736 try f.writeCValue(bw, resolved_elements[field_index], .Other);
7737 try a.end(f, bw);
76547738 },
76557739 else => unreachable,
76567740 }
......@@ -7672,7 +7756,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
76727756 const payload = try f.resolveInst(extra.init);
76737757 try reap(f, inst, &.{extra.init});
76747758
7675 const writer = f.object.writer();
7759 const bw = &f.object.code.buffered_writer;
76767760 const local = try f.allocLocal(inst, union_ty);
76777761 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
76787762
......@@ -7682,20 +7766,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
76827766 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
76837767 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
76847768
7685 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));
7686 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });
7687 try a.assign(f, writer);
7688 try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))});
7689 try a.end(f, writer);
7769 const a = try Assignment.start(f, bw, try f.ctypeFromType(tag_ty, .complete));
7770 try f.writeCValueMember(bw, local, .{ .identifier = "tag" });
7771 try a.assign(f, bw);
7772 try bw.print("{f}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))});
7773 try a.end(f, bw);
76907774 }
76917775 break :field .{ .payload_identifier = field_name.toSlice(ip) };
76927776 } else .{ .identifier = field_name.toSlice(ip) };
76937777
7694 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));
7695 try f.writeCValueMember(writer, local, field);
7696 try a.assign(f, writer);
7697 try f.writeCValue(writer, payload, .Other);
7698 try a.end(f, writer);
7778 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
7779 try f.writeCValueMember(bw, local, field);
7780 try a.assign(f, bw);
7781 try f.writeCValue(bw, payload, .Other);
7782 try a.end(f, bw);
76997783 return local;
77007784}
77017785
......@@ -7708,15 +7792,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
77087792 const ptr = try f.resolveInst(prefetch.ptr);
77097793 try reap(f, inst, &.{prefetch.ptr});
77107794
7711 const writer = f.object.writer();
7795 const bw = &f.object.code.buffered_writer;
77127796 switch (prefetch.cache) {
77137797 .data => {
7714 try writer.writeAll("zig_prefetch(");
7798 try bw.writeAll("zig_prefetch(");
77157799 if (ptr_ty.isSlice(zcu))
7716 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" })
7800 try f.writeCValueMember(bw, ptr, .{ .identifier = "ptr" })
77177801 else
7718 try f.writeCValue(writer, ptr, .FunctionArgument);
7719 try writer.print(", {d}, {d});\n", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7802 try f.writeCValue(bw, ptr, .FunctionArgument);
7803 try bw.print(", {d}, {d});", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7804 try f.object.newline();
77207805 },
77217806 // The available prefetch intrinsics do not accept a cache argument; only
77227807 // address, rw, and locality.
......@@ -7729,13 +7814,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
77297814fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
77307815 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
77317816
7732 const writer = f.object.writer();
7817 const bw = &f.object.code.buffered_writer;
77337818 const inst_ty = f.typeOfIndex(inst);
77347819 const local = try f.allocLocal(inst, inst_ty);
7735 try f.writeCValue(writer, local, .Other);
7820 try f.writeCValue(bw, local, .Other);
77367821
7737 try writer.writeAll(" = ");
7738 try writer.print("zig_wasm_memory_size({d});\n", .{pl_op.payload});
7822 try bw.writeAll(" = ");
7823 try bw.print("zig_wasm_memory_size({d});", .{pl_op.payload});
7824 try f.object.newline();
77397825
77407826 return local;
77417827}
......@@ -7743,17 +7829,18 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
77437829fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
77447830 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
77457831
7746 const writer = f.object.writer();
7832 const bw = &f.object.code.buffered_writer;
77477833 const inst_ty = f.typeOfIndex(inst);
77487834 const operand = try f.resolveInst(pl_op.operand);
77497835 try reap(f, inst, &.{pl_op.operand});
77507836 const local = try f.allocLocal(inst, inst_ty);
7751 try f.writeCValue(writer, local, .Other);
7837 try f.writeCValue(bw, local, .Other);
77527838
7753 try writer.writeAll(" = ");
7754 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
7755 try f.writeCValue(writer, operand, .FunctionArgument);
7756 try writer.writeAll(");\n");
7839 try bw.writeAll(" = ");
7840 try bw.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
7841 try f.writeCValue(bw, operand, .FunctionArgument);
7842 try bw.writeAll(");");
7843 try f.object.newline();
77577844 return local;
77587845}
77597846
......@@ -7771,24 +7858,25 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
77717858 const inst_ty = f.typeOfIndex(inst);
77727859 const inst_scalar_ty = inst_ty.scalarType(zcu);
77737860
7774 const writer = f.object.writer();
7861 const bw = &f.object.code.buffered_writer;
77757862 const local = try f.allocLocal(inst, inst_ty);
7776 const v = try Vectorize.start(f, inst, writer, inst_ty);
7777 try f.writeCValue(writer, local, .Other);
7778 try v.elem(f, writer);
7779 try writer.writeAll(" = zig_fma_");
7780 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);
7781 try writer.writeByte('(');
7782 try f.writeCValue(writer, mulend1, .FunctionArgument);
7783 try v.elem(f, writer);
7784 try writer.writeAll(", ");
7785 try f.writeCValue(writer, mulend2, .FunctionArgument);
7786 try v.elem(f, writer);
7787 try writer.writeAll(", ");
7788 try f.writeCValue(writer, addend, .FunctionArgument);
7789 try v.elem(f, writer);
7790 try writer.writeAll(");\n");
7791 try v.end(f, inst, writer);
7863 const v = try Vectorize.start(f, inst, bw, inst_ty);
7864 try f.writeCValue(bw, local, .Other);
7865 try v.elem(f, bw);
7866 try bw.writeAll(" = zig_fma_");
7867 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_scalar_ty);
7868 try bw.writeByte('(');
7869 try f.writeCValue(bw, mulend1, .FunctionArgument);
7870 try v.elem(f, bw);
7871 try bw.writeAll(", ");
7872 try f.writeCValue(bw, mulend2, .FunctionArgument);
7873 try v.elem(f, bw);
7874 try bw.writeAll(", ");
7875 try f.writeCValue(bw, addend, .FunctionArgument);
7876 try v.elem(f, bw);
7877 try bw.writeAll(");");
7878 try f.object.newline();
7879 try v.end(f, inst, bw);
77927880
77937881 return local;
77947882}
......@@ -7812,15 +7900,16 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
78127900 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
78137901 assert(function_info.varargs);
78147902
7815 const writer = f.object.writer();
7903 const bw = &f.object.code.buffered_writer;
78167904 const local = try f.allocLocal(inst, inst_ty);
7817 try writer.writeAll("va_start(*(va_list *)&");
7818 try f.writeCValue(writer, local, .Other);
7905 try bw.writeAll("va_start(*(va_list *)&");
7906 try f.writeCValue(bw, local, .Other);
78197907 if (function_info.param_ctypes.len > 0) {
7820 try writer.writeAll(", ");
7821 try f.writeCValue(writer, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
7908 try bw.writeAll(", ");
7909 try f.writeCValue(bw, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
78227910 }
7823 try writer.writeAll(");\n");
7911 try bw.writeAll(");");
7912 try f.object.newline();
78247913 return local;
78257914}
78267915
......@@ -7831,14 +7920,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
78317920 const va_list = try f.resolveInst(ty_op.operand);
78327921 try reap(f, inst, &.{ty_op.operand});
78337922
7834 const writer = f.object.writer();
7923 const bw = &f.object.code.buffered_writer;
78357924 const local = try f.allocLocal(inst, inst_ty);
7836 try f.writeCValue(writer, local, .Other);
7837 try writer.writeAll(" = va_arg(*(va_list *)");
7838 try f.writeCValue(writer, va_list, .Other);
7839 try writer.writeAll(", ");
7840 try f.renderType(writer, ty_op.ty.toType());
7841 try writer.writeAll(");\n");
7925 try f.writeCValue(bw, local, .Other);
7926 try bw.writeAll(" = va_arg(*(va_list *)");
7927 try f.writeCValue(bw, va_list, .Other);
7928 try bw.writeAll(", ");
7929 try f.renderType(bw, ty_op.ty.toType());
7930 try bw.writeAll(");");
7931 try f.object.newline();
78427932 return local;
78437933}
78447934
......@@ -7848,10 +7938,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
78487938 const va_list = try f.resolveInst(un_op);
78497939 try reap(f, inst, &.{un_op});
78507940
7851 const writer = f.object.writer();
7852 try writer.writeAll("va_end(*(va_list *)");
7853 try f.writeCValue(writer, va_list, .Other);
7854 try writer.writeAll(");\n");
7941 const bw = &f.object.code.buffered_writer;
7942 try bw.writeAll("va_end(*(va_list *)");
7943 try f.writeCValue(bw, va_list, .Other);
7944 try bw.writeAll(");");
7945 try f.object.newline();
78557946 return .none;
78567947}
78577948
......@@ -7862,13 +7953,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
78627953 const va_list = try f.resolveInst(ty_op.operand);
78637954 try reap(f, inst, &.{ty_op.operand});
78647955
7865 const writer = f.object.writer();
7956 const bw = &f.object.code.buffered_writer;
78667957 const local = try f.allocLocal(inst, inst_ty);
7867 try writer.writeAll("va_copy(*(va_list *)&");
7868 try f.writeCValue(writer, local, .Other);
7869 try writer.writeAll(", *(va_list *)");
7870 try f.writeCValue(writer, va_list, .Other);
7871 try writer.writeAll(");\n");
7958 try bw.writeAll("va_copy(*(va_list *)&");
7959 try f.writeCValue(bw, local, .Other);
7960 try bw.writeAll(", *(va_list *)");
7961 try f.writeCValue(bw, va_list, .Other);
7962 try bw.writeAll(");");
7963 try f.object.newline();
78727964 return local;
78737965}
78747966
......@@ -7883,8 +7975,8 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
78837975 };
78847976}
78857977
7886fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {
7887 return w.writeAll(toMemoryOrder(order));
7978fn writeMemoryOrder(bw: *std.io.BufferedWriter, order: std.builtin.AtomicOrder) !void {
7979 return bw.writeAll(toMemoryOrder(order));
78887980}
78897981
78907982fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 {
......@@ -8027,8 +8119,7 @@ fn compareOperatorC(operator: std.math.CompareOperator) []const u8 {
80278119const StringLiteral = struct {
80288120 len: usize,
80298121 cur_len: usize,
8030 bytes_written: usize,
8031 writer: *std.io.BufferedWriter,
8122 bw: *std.io.BufferedWriter,
80328123
80338124 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,
80348125 // regardless of the length of the string literal initializing it. Array initializer syntax is
......@@ -8041,65 +8132,62 @@ const StringLiteral = struct {
80418132 const max_char_len = 4;
80428133 const max_literal_len = @min(16380 - max_char_len, 4095);
80438134
8044 fn init(writer: *std.io.BufferedWriter, len: usize) StringLiteral {
8135 fn init(bw: *std.io.BufferedWriter, len: usize) StringLiteral {
80458136 return .{
80468137 .cur_len = 0,
80478138 .len = len,
8048 .writer = writer,
8049 .bytes_written = 0,
8139 .bw = bw,
80508140 };
80518141 }
80528142
8053 pub fn start(self: *StringLiteral) std.io.Writer.Error!void {
8054 const writer = self.writer;
8055 if (self.len <= max_string_initializer_len) {
8056 self.bytes_written += try writer.writeByteCount('\"');
8143 pub fn start(sl: *StringLiteral) std.io.Writer.Error!void {
8144 if (sl.len <= max_string_initializer_len) {
8145 try sl.bw.writeByte('\"');
80578146 } else {
8058 self.bytes_written += try writer.writeByteCount('{');
8147 try sl.bw.writeByte('{');
80598148 }
80608149 }
80618150
8062 pub fn end(self: *StringLiteral) std.io.Writer.Error!void {
8063 const writer = self.writer;
8064 if (self.len <= max_string_initializer_len) {
8065 self.bytes_written += try writer.writeByteCount('\"');
8151 pub fn end(sl: *StringLiteral) std.io.Writer.Error!void {
8152 if (sl.len <= max_string_initializer_len) {
8153 try sl.bw.writeByte('\"');
80668154 } else {
8067 self.bytes_written += try writer.writeByteCount('}');
8155 try sl.bw.writeByte('}');
80688156 }
80698157 }
80708158
8071 fn writeStringLiteralChar(writer: *std.io.BufferedWriter, c: u8) std.io.Writer.Error!usize {
8159 fn writeStringLiteralChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
80728160 switch (c) {
8073 7 => return writer.writeAllCount("\\a"),
8074 8 => return writer.writeAllCount("\\b"),
8075 '\t' => return writer.writeAllCount("\\t"),
8076 '\n' => return writer.writeAllCount("\\n"),
8077 11 => return writer.writeAllCount("\\v"),
8078 12 => return writer.writeAllCount("\\f"),
8079 '\r' => return writer.writeAllCount("\\r"),
8080 '"', '\'', '?', '\\' => return writer.printCount("\\{c}", .{c}),
8161 7 => try sl.bw.writeAll("\\a"),
8162 8 => try sl.bw.writeAll("\\b"),
8163 '\t' => try sl.bw.writeAll("\\t"),
8164 '\n' => try sl.bw.writeAll("\\n"),
8165 11 => try sl.bw.writeAll("\\v"),
8166 12 => try sl.bw.writeAll("\\f"),
8167 '\r' => try sl.bw.writeAll("\\r"),
8168 '"', '\'', '?', '\\' => try sl.bw.print("\\{c}", .{c}),
80818169 else => switch (c) {
8082 ' '...'~' => return writer.writeByteCount(c),
8083 else => return writer.printCount("\\{o:0>3}", .{c}),
8170 ' '...'~' => try sl.bw.writeByte(c),
8171 else => try sl.bw.print("\\{o:0>3}", .{c}),
80848172 },
80858173 }
80868174 }
80878175
8088 pub fn writeChar(self: *StringLiteral, c: u8) std.io.Writer.Error!void {
8089 const writer = self.writer;
8090 if (self.len <= max_string_initializer_len) {
8091 if (self.cur_len == 0 and self.bytes_written > 1)
8092 self.bytes_written += try writer.writeAllCount("\"\"");
8176 pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
8177 if (sl.len <= max_string_initializer_len) {
8178 if (sl.cur_len == 0 and sl.bw.count > 1)
8179 try sl.bw.writeAll("\"\"");
80938180
8094 const char_length = try writeStringLiteralChar(writer, c);
8095 self.bytes_written += char_length;
8096 assert(char_length <= max_char_len);
8097 self.cur_len += char_length;
8181 const count = sl.bw.count;
8182 try sl.writeStringLiteralChar(c);
8183 const char_len = sl.bw.count - count;
8184 assert(char_len <= max_char_len);
8185 sl.cur_len += char_len;
80988186
8099 if (self.cur_len >= max_literal_len) self.cur_len = 0;
8187 if (sl.cur_len >= max_literal_len) sl.cur_len = 0;
81008188 } else {
8101 if (self.bytes_written > 1) self.bytes_written += try writer.writeByteCount(',');
8102 self.bytes_written += try writer.printCount("'\\x{x}'", .{c});
8189 if (sl.bw.count > 1) try sl.bw.writeByte(',');
8190 try sl.bw.print("'\\x{x}'", .{c});
81038191 }
81048192 }
81058193};
......@@ -8107,13 +8195,12 @@ const StringLiteral = struct {
81078195const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };
81088196fn formatStringLiteral(
81098197 data: FormatStringContext,
8198 bw: *std.io.BufferedWriter,
81108199 comptime fmt: []const u8,
8111 _: std.fmt.FormatOptions,
8112 writer: anytype,
8113) @TypeOf(writer).Error!void {
8200) std.io.Writer.Error!void {
81148201 if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt);
81158202
8116 var literal: StringLiteral = .init(writer, data.str.len + @intFromBool(data.sentinel != null));
8203 var literal: StringLiteral = .init(bw, data.str.len + @intFromBool(data.sentinel != null));
81178204 try literal.start();
81188205 for (data.str) |c| try literal.writeChar(c);
81198206 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);
......@@ -8139,10 +8226,9 @@ const FormatIntLiteralContext = struct {
81398226};
81408227fn formatIntLiteral(
81418228 data: FormatIntLiteralContext,
8229 bw: *std.io.BufferedWriter,
81428230 comptime fmt: []const u8,
8143 options: std.fmt.FormatOptions,
8144 writer: anytype,
8145) @TypeOf(writer).Error!void {
8231) std.io.Writer.Error!void {
81468232 const pt = data.dg.pt;
81478233 const zcu = pt.zcu;
81488234 const target = &data.dg.mod.resolved_target.result;
......@@ -8167,7 +8253,7 @@ fn formatIntLiteral(
81678253
81688254 var int_buf: Value.BigIntSpace = undefined;
81698255 const int = if (data.val.isUndefDeep(zcu)) blk: {
8170 undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits));
8256 undef_limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)) catch return error.WriteFailed;
81718257 @memset(undef_limbs, undefPattern(BigIntLimb));
81728258
81738259 var undef_int = BigInt.Mutable{
......@@ -8185,7 +8271,7 @@ fn formatIntLiteral(
81858271 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();
81868272
81878273 var wrap = BigInt.Mutable{
8188 .limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)),
8274 .limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)) catch return error.WriteFailed,
81898275 .len = undefined,
81908276 .positive = undefined,
81918277 };
......@@ -8222,30 +8308,30 @@ fn formatIntLiteral(
82228308 if (c_limb_info.count == 1) {
82238309 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
82248310 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
8225 return writer.print("{s}_{s}", .{
8226 data.ctype.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{
8311 return bw.print("{s}_{s}", .{
8312 data.ctype.getStandardDefineAbbrev() orelse return bw.print("zig_{s}Int_{c}{d}", .{
82278313 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
82288314 }),
82298315 if (int.positive) "MAX" else "MIN",
82308316 });
82318317
8232 if (!int.positive) try writer.writeByte('-');
8233 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);
8318 if (!int.positive) try bw.writeByte('-');
8319 try data.ctype.renderLiteralPrefix(bw, data.kind, ctype_pool);
82348320
82358321 const style: struct { base: u8, case: std.fmt.Case = undefined } = switch (fmt.len) {
82368322 0 => .{ .base = 10 },
82378323 1 => switch (fmt[0]) {
82388324 'b' => style: {
8239 try writer.writeAll("0b");
8325 try bw.writeAll("0b");
82408326 break :style .{ .base = 2 };
82418327 },
82428328 'o' => style: {
8243 try writer.writeByte('0');
8329 try bw.writeByte('0');
82448330 break :style .{ .base = 8 };
82458331 },
82468332 'd' => .{ .base = 10 },
82478333 'x', 'X' => |base| style: {
8248 try writer.writeAll("0x");
8334 try bw.writeAll("0x");
82498335 break :style .{ .base = 16, .case = switch (base) {
82508336 'x' => .lower,
82518337 'X' => .upper,
......@@ -8257,11 +8343,12 @@ fn formatIntLiteral(
82578343 else => @compileError("Invalid fmt: " ++ fmt),
82588344 };
82598345
8260 const string = try int.abs().toStringAlloc(allocator, style.base, style.case);
8346 const string = int.abs().toStringAlloc(allocator, style.base, style.case) catch
8347 return error.WriteFailed;
82618348 defer allocator.free(string);
8262 try writer.writeAll(string);
8349 try bw.writeAll(string);
82638350 } else {
8264 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);
8351 try data.ctype.renderLiteralPrefix(bw, data.kind, ctype_pool);
82658352 wrap.truncate(int, .unsigned, c_bits);
82668353 @memset(wrap.limbs[wrap.len..], 0);
82678354 wrap.len = wrap.limbs.len;
......@@ -8304,17 +8391,18 @@ fn formatIntLiteral(
83048391 c_limb_ctype = c_limb_info.ctype;
83058392 }
83068393
8307 if (limb_offset > 0) try writer.writeAll(", ");
8394 if (limb_offset > 0) try bw.writeAll(", ");
83088395 try formatIntLiteral(.{
83098396 .dg = data.dg,
83108397 .int_info = c_limb_int_info,
83118398 .kind = data.kind,
83128399 .ctype = c_limb_ctype,
8313 .val = try pt.intValue_big(.comptime_int, c_limb_mut.toConst()),
8314 }, fmt, options, writer);
8400 .val = pt.intValue_big(.comptime_int, c_limb_mut.toConst()) catch
8401 return error.WriteFailed,
8402 }, bw, fmt);
83158403 }
83168404 }
8317 try data.ctype.renderLiteralSuffix(writer, ctype_pool);
8405 try data.ctype.renderLiteralSuffix(bw, ctype_pool);
83188406}
83198407
83208408const Materialize = struct {
......@@ -8328,8 +8416,8 @@ const Materialize = struct {
83288416 } };
83298417 }
83308418
8331 pub fn mat(self: Materialize, f: *Function, writer: anytype) !void {
8332 try f.writeCValue(writer, self.local, .Other);
8419 pub fn mat(self: Materialize, f: *Function, bw: *std.io.BufferedWriter) !void {
8420 try f.writeCValue(bw, self.local, .Other);
83338421 }
83348422
83358423 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
......@@ -8340,36 +8428,37 @@ const Materialize = struct {
83408428const Assignment = struct {
83418429 ctype: CType,
83428430
8343 pub fn start(f: *Function, writer: anytype, ctype: CType) !Assignment {
8431 pub fn start(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !Assignment {
83448432 const self: Assignment = .{ .ctype = ctype };
8345 try self.restart(f, writer);
8433 try self.restart(f, bw);
83468434 return self;
83478435 }
83488436
8349 pub fn restart(self: Assignment, f: *Function, writer: anytype) !void {
8437 pub fn restart(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
83508438 switch (self.strategy(f)) {
83518439 .assign => {},
8352 .memcpy => try writer.writeAll("memcpy("),
8440 .memcpy => try bw.writeAll("memcpy("),
83538441 }
83548442 }
83558443
8356 pub fn assign(self: Assignment, f: *Function, writer: anytype) !void {
8444 pub fn assign(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
83578445 switch (self.strategy(f)) {
8358 .assign => try writer.writeAll(" = "),
8359 .memcpy => try writer.writeAll(", "),
8446 .assign => try bw.writeAll(" = "),
8447 .memcpy => try bw.writeAll(", "),
83608448 }
83618449 }
83628450
8363 pub fn end(self: Assignment, f: *Function, writer: anytype) !void {
8451 pub fn end(self: Assignment, f: *Function, bw: *std.io.BufferedWriter) !void {
83648452 switch (self.strategy(f)) {
83658453 .assign => {},
83668454 .memcpy => {
8367 try writer.writeAll(", sizeof(");
8368 try f.renderCType(writer, self.ctype);
8369 try writer.writeAll("))");
8455 try bw.writeAll(", sizeof(");
8456 try f.renderCType(bw, self.ctype);
8457 try bw.writeAll("))");
83708458 },
83718459 }
8372 try writer.writeAll(";\n");
8460 try bw.writeByte(';');
8461 try f.object.newline();
83738462 }
83748463
83758464 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
......@@ -8383,7 +8472,7 @@ const Assignment = struct {
83838472const Vectorize = struct {
83848473 index: CValue = .none,
83858474
8386 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {
8475 pub fn start(f: *Function, inst: Air.Inst.Index, writer: *std.io.BufferedWriter, ty: Type) !Vectorize {
83878476 const pt = f.object.dg.pt;
83888477 const zcu = pt.zcu;
83898478 return if (ty.zigTypeTag(zcu) == .vector) index: {
......@@ -8391,29 +8480,31 @@ const Vectorize = struct {
83918480
83928481 try writer.writeAll("for (");
83938482 try f.writeCValue(writer, local, .Other);
8394 try writer.print(" = {d}; ", .{try f.fmtIntLiteral(.zero_usize)});
8483 try writer.print(" = {fd}; ", .{try f.fmtIntLiteral(.zero_usize)});
83958484 try f.writeCValue(writer, local, .Other);
8396 try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))});
8485 try writer.print(" < {fd}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))});
83978486 try f.writeCValue(writer, local, .Other);
8398 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(.one_usize)});
8399 f.object.indent_writer.pushIndent();
8487 try writer.print(" += {fd}) {{\n", .{try f.fmtIntLiteral(.one_usize)});
8488 f.object.indent();
8489 try f.object.newline();
84008490
84018491 break :index .{ .index = local };
84028492 } else .{};
84038493 }
84048494
8405 pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void {
8495 pub fn elem(self: Vectorize, f: *Function, bw: *std.io.BufferedWriter) !void {
84068496 if (self.index != .none) {
8407 try writer.writeByte('[');
8408 try f.writeCValue(writer, self.index, .Other);
8409 try writer.writeByte(']');
8497 try bw.writeByte('[');
8498 try f.writeCValue(bw, self.index, .Other);
8499 try bw.writeByte(']');
84108500 }
84118501 }
84128502
8413 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {
8503 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, bw: *std.io.BufferedWriter) !void {
84148504 if (self.index != .none) {
8415 f.object.indent_writer.popIndent();
8416 try writer.writeAll("}\n");
8505 f.object.outdent();
8506 try bw.writeByte('}');
8507 try f.object.newline();
84178508 try freeLocal(f, inst, self.index.new_local, null);
84188509 }
84198510 }
src/codegen/c/Type.zig+20-21
......@@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {
209209 };
210210}
211211
212pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *const Pool) @TypeOf(writer).Error!void {
212pub fn renderLiteralPrefix(ctype: CType, bw: *std.io.BufferedWriter, kind: Kind, pool: *const Pool) std.io.Writer.Error!void {
213213 switch (ctype.info(pool)) {
214214 .basic => |basic_info| switch (basic_info) {
215215 .void => unreachable,
......@@ -224,7 +224,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
224224 .uintptr_t,
225225 .intptr_t,
226226 => switch (kind) {
227 else => try writer.print("({s})", .{@tagName(basic_info)}),
227 else => try bw.print("({s})", .{@tagName(basic_info)}),
228228 .global => {},
229229 },
230230 .int,
......@@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
246246 .int32_t,
247247 .uint64_t,
248248 .int64_t,
249 => try writer.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),
249 => try bw.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),
250250 .zig_u128,
251251 .zig_i128,
252252 .zig_f16,
......@@ -255,7 +255,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
255255 .zig_f80,
256256 .zig_f128,
257257 .zig_c_longdouble,
258 => try writer.print("zig_{s}_{s}(", .{
258 => try bw.print("zig_{s}_{s}(", .{
259259 switch (kind) {
260260 else => "make",
261261 .global => "init",
......@@ -265,12 +265,12 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
265265 .va_list => unreachable,
266266 _ => unreachable,
267267 },
268 .array, .vector => try writer.writeByte('{'),
268 .array, .vector => try bw.writeByte('{'),
269269 else => unreachable,
270270 }
271271}
272272
273pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @TypeOf(writer).Error!void {
273pub fn renderLiteralSuffix(ctype: CType, bw: *std.io.BufferedWriter, pool: *const Pool) std.io.Writer.Error!void {
274274 switch (ctype.info(pool)) {
275275 .basic => |basic_info| switch (basic_info) {
276276 .void => unreachable,
......@@ -280,20 +280,20 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty
280280 .short,
281281 .int,
282282 => {},
283 .long => try writer.writeByte('l'),
284 .@"long long" => try writer.writeAll("ll"),
283 .long => try bw.writeByte('l'),
284 .@"long long" => try bw.writeAll("ll"),
285285 .@"unsigned char",
286286 .@"unsigned short",
287287 .@"unsigned int",
288 => try writer.writeByte('u'),
288 => try bw.writeByte('u'),
289289 .@"unsigned long",
290290 .size_t,
291291 .uintptr_t,
292 => try writer.writeAll("ul"),
293 .@"unsigned long long" => try writer.writeAll("ull"),
294 .float => try writer.writeByte('f'),
292 => try bw.writeAll("ul"),
293 .@"unsigned long long" => try bw.writeAll("ull"),
294 .float => try bw.writeByte('f'),
295295 .double => {},
296 .@"long double" => try writer.writeByte('l'),
296 .@"long double" => try bw.writeByte('l'),
297297 .bool,
298298 .ptrdiff_t,
299299 .intptr_t,
......@@ -314,11 +314,11 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty
314314 .zig_f80,
315315 .zig_f128,
316316 .zig_c_longdouble,
317 => try writer.writeByte(')'),
317 => try bw.writeByte(')'),
318318 .va_list => unreachable,
319319 _ => unreachable,
320320 },
321 .array, .vector => try writer.writeByte('}'),
321 .array, .vector => try bw.writeByte('}'),
322322 else => unreachable,
323323 }
324324}
......@@ -940,15 +940,14 @@ pub const Pool = struct {
940940 const FormatData = struct { string: String, pool: *const Pool };
941941 fn format(
942942 data: FormatData,
943 bw: *std.io.BufferedWriter,
943944 comptime fmt_str: []const u8,
944 _: std.fmt.FormatOptions,
945 writer: anytype,
946 ) @TypeOf(writer).Error!void {
945 ) std.io.Writer.Error!void {
947946 if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");
948947 if (data.string.toSlice(data.pool)) |slice|
949 try writer.writeAll(slice)
948 try bw.writeAll(slice)
950949 else
951 try writer.print("f{d}", .{@intFromEnum(data.string.index)});
950 try bw.print("f{d}", .{@intFromEnum(data.string.index)});
952951 }
953952 pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {
954953 return .{ .data = .{ .string = str, .pool = pool } };
......@@ -2890,7 +2889,7 @@ pub const Pool = struct {
28902889 comptime fmt_str: []const u8,
28912890 fmt_args: anytype,
28922891 ) !String {
2893 try pool.string_bytes.writer(allocator).print(fmt_str, fmt_args);
2892 try pool.string_bytes.print(allocator, fmt_str, fmt_args);
28942893 return pool.trailingString(allocator);
28952894 }
28962895
src/codegen/spirv.zig+1
......@@ -1262,6 +1262,7 @@ const NavGen = struct {
12621262 fn resolveTypeName(self: *NavGen, ty: Type) Allocator.Error![]const u8 {
12631263 var aw: std.io.AllocatingWriter = undefined;
12641264 aw.init(self.gpa);
1265 defer aw.deinit();
12651266 ty.print(&aw.buffered_writer, self.pt) catch return error.OutOfMemory;
12661267 return aw.toOwnedSlice();
12671268 }
src/link.zig+3-3
......@@ -1038,7 +1038,7 @@ pub const File = struct {
10381038 var fr = file.reader();
10391039 var br = fr.interface().unbuffered();
10401040 br.readSlice(buf) catch |err| switch (err) {
1041 error.ReadFailed => if (fr.err) |_| unreachable else |e| return e,
1041 error.ReadFailed => return fr.err.?,
10421042 error.EndOfStream => return error.UnexpectedEndOfFile,
10431043 };
10441044 var ld_script = try LdScript.parse(gpa, diags, path, buf);
......@@ -2107,7 +2107,7 @@ fn resolvePathInputLib(
21072107 br.readSlice(ld_script_bytes.items) catch |err| switch (err) {
21082108 error.ReadFailed => fatal("failed to read '{f'}': {s}", .{
21092109 test_path,
2110 @errorName(if (fr.err) |_| unreachable else |e| e),
2110 @errorName(fr.err.?),
21112111 }),
21122112 error.EndOfStream => break :ok,
21132113 };
......@@ -2124,7 +2124,7 @@ fn resolvePathInputLib(
21242124 fatal("{f}: linker script too big", .{test_path});
21252125 try ld_script_bytes.resize(gpa, size);
21262126 br.readSlice(ld_script_bytes.items[@intCast(fr.pos)..]) catch |err| switch (err) {
2127 error.ReadFailed => if (fr.err) |_| unreachable else |e| fatal("failed to read {f}: {s}", .{ test_path, @errorName(e) }),
2127 error.ReadFailed => fatal("failed to read {f}: {s}", .{ test_path, @errorName(fr.err.?) }),
21282128 error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}),
21292129 };
21302130 var diags: Diags = .init(gpa);