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 {...@@ -1790,7 +1790,7 @@ const ElfDumper = struct {
1790 .p32 => @sizeOf(u32),1790 .p32 => @sizeOf(u32),
1791 .p64 => @sizeOf(u64),1791 .p64 => @sizeOf(u64),
1792 };1792 };
1793 try br.discard(num * ptr_size);1793 _ = try br.discard(.limited(num * ptr_size));
1794 const strtab = br.bufferContents();1794 const strtab = br.bufferContents();
17951795
1796 assert(ctx.symtab.len == 0);1796 assert(ctx.symtab.len == 0);
...@@ -2569,7 +2569,7 @@ const WasmDumper = struct {...@@ -2569,7 +2569,7 @@ const WasmDumper = struct {
2569 if (!flags.passive) try parseDumpInit(step, br, bw);2569 if (!flags.passive) try parseDumpInit(step, br, bw);
2570 const size = try br.takeLeb128(u32);2570 const size = try br.takeLeb128(u32);
2571 try bw.print("size {d}\n", .{size});2571 try bw.print("size {d}\n", .{size});
2572 try br.discard(size); // we do not care about the content of the segments2572 _ = try br.discard(.limited(size)); // we do not care about the content of the segments
2573 }2573 }
2574 },2574 },
2575 else => unreachable,2575 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...@@ -304,8 +304,8 @@ pub fn dumpHexFallible(bw: *std.io.BufferedWriter, ttyconf: std.io.tty.Config, b
304test dumpHexFallible {304test dumpHexFallible {
305 const bytes: []const u8 = &.{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x12, 0x13 };305 const bytes: []const u8 = &.{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x12, 0x13 };
306 var aw: std.io.AllocatingWriter = undefined;306 var aw: std.io.AllocatingWriter = undefined;
307 defer aw.deinit();
308 var bw = aw.init(std.testing.allocator);307 var bw = aw.init(std.testing.allocator);
308 defer aw.deinit();
309309
310 try dumpHexFallible(&bw, .no_color, bytes);310 try dumpHexFallible(&bw, .no_color, bytes);
311 const expected = try std.fmt.allocPrint(std.testing.allocator,311 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 {...@@ -856,6 +856,7 @@ pub fn count(comptime fmt: []const u8, args: anytype) usize {
856pub fn allocPrint(gpa: Allocator, comptime fmt: []const u8, args: anytype) Allocator.Error![]u8 {856pub fn allocPrint(gpa: Allocator, comptime fmt: []const u8, args: anytype) Allocator.Error![]u8 {
857 var aw: std.io.AllocatingWriter = undefined;857 var aw: std.io.AllocatingWriter = undefined;
858 try aw.initCapacity(gpa, fmt.len);858 try aw.initCapacity(gpa, fmt.len);
859 defer aw.deinit();
859 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {860 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {
860 error.WriteFailed => return error.OutOfMemory,861 error.WriteFailed => return error.OutOfMemory,
861 };862 };
...@@ -870,6 +871,7 @@ pub fn allocPrintSentinel(...@@ -870,6 +871,7 @@ pub fn allocPrintSentinel(
870) Allocator.Error![:sentinel]u8 {871) Allocator.Error![:sentinel]u8 {
871 var aw: std.io.AllocatingWriter = undefined;872 var aw: std.io.AllocatingWriter = undefined;
872 try aw.initCapacity(gpa, fmt.len);873 try aw.initCapacity(gpa, fmt.len);
874 defer aw.deinit();
873 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {875 aw.buffered_writer.print(fmt, args) catch |err| switch (err) {
874 error.WriteFailed => return error.OutOfMemory,876 error.WriteFailed => return error.OutOfMemory,
875 };877 };
lib/std/fs/File.zig+2-2
...@@ -934,7 +934,7 @@ pub fn writeFileAll(self: File, in_file: File, options: BufferedWriter.WriteFile...@@ -934,7 +934,7 @@ pub fn writeFileAll(self: File, in_file: File, options: BufferedWriter.WriteFile
934 var buffer: [2000]u8 = undefined;934 var buffer: [2000]u8 = undefined;
935 var bw = file_writer.interface().buffered(&buffer);935 var bw = file_writer.interface().buffered(&buffer);
936 bw.writeFileAll(in_file, options) catch |err| switch (err) {936 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.?,
938 else => |e| return e,938 else => |e| return e,
939 };939 };
940}940}
...@@ -1232,7 +1232,7 @@ pub const Reader = struct {...@@ -1232,7 +1232,7 @@ pub const Reader = struct {
12321232
1233pub const Writer = struct {1233pub const Writer = struct {
1234 file: File,1234 file: File,
1235 err: WriteError!void = {},1235 err: ?WriteError = null,
1236 mode: Writer.Mode = .positional,1236 mode: Writer.Mode = .positional,
1237 pos: u64 = 0,1237 pos: u64 = 0,
1238 sendfile_err: ?SendfileError = null,1238 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 {...@@ -73,7 +73,7 @@ pub fn readVecAll(br: *BufferedReader, data: [][]u8) Reader.Error!void {
73 defer data[index] = untruncated;73 defer data[index] = untruncated;
74 truncate += try br.readVec(data[index..]);74 truncate += try br.readVec(data[index..]);
75 }75 }
76 while (index < data.len and truncate <= data[index].len) {76 while (index < data.len and truncate >= data[index].len) {
77 truncate -= data[index].len;77 truncate -= data[index].len;
78 index += 1;78 index += 1;
79 }79 }
lib/std/io/BufferedWriter.zig+1-1
...@@ -150,7 +150,7 @@ pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void {...@@ -150,7 +150,7 @@ pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void {
150 defer data[index] = untruncated;150 defer data[index] = untruncated;
151 truncate += try bw.writeVec(data[index..]);151 truncate += try bw.writeVec(data[index..]);
152 }152 }
153 while (index < data.len and truncate <= data[index].len) {153 while (index < data.len and truncate >= data[index].len) {
154 truncate -= data[index].len;154 truncate -= data[index].len;
155 index += 1;155 index += 1;
156 }156 }
lib/std/io/Reader.zig+1-1
...@@ -177,8 +177,8 @@ pub const ReadAllocError = std.mem.Allocator.Error || ShortError;...@@ -177,8 +177,8 @@ pub const ReadAllocError = std.mem.Allocator.Error || ShortError;
177pub fn readAlloc(r: Reader, gpa: std.mem.Allocator, max_size: usize) ReadAllocError![]u8 {177pub fn readAlloc(r: Reader, gpa: std.mem.Allocator, max_size: usize) ReadAllocError![]u8 {
178 const readFn = r.vtable.read;178 const readFn = r.vtable.read;
179 var aw: std.io.AllocatingWriter = undefined;179 var aw: std.io.AllocatingWriter = undefined;
180 errdefer aw.deinit();
181 aw.init(gpa);180 aw.init(gpa);
181 errdefer aw.deinit();
182 var remaining = max_size;182 var remaining = max_size;
183 while (remaining > 0) {183 while (remaining > 0) {
184 const n = readFn(r.context, &aw.buffered_writer, .limited(remaining)) catch |err| switch (err) {184 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(...@@ -1053,8 +1053,8 @@ fn expectSerializeEqual(
1053 options: SerializeOptions,1053 options: SerializeOptions,
1054) !void {1054) !void {
1055 var aw: std.io.AllocatingWriter = undefined;1055 var aw: std.io.AllocatingWriter = undefined;
1056 defer aw.deinit();
1057 const bw = aw.init(std.testing.allocator);1056 const bw = aw.init(std.testing.allocator);
1057 defer aw.deinit();
10581058
1059 try serialize(value, options, bw);1059 try serialize(value, options, bw);
1060 try std.testing.expectEqualStrings(expected, aw.getWritten());1060 try std.testing.expectEqualStrings(expected, aw.getWritten());
...@@ -1155,8 +1155,8 @@ test "std.zon stringify whitespace, high level API" {...@@ -1155,8 +1155,8 @@ test "std.zon stringify whitespace, high level API" {
11551155
1156test "std.zon stringify whitespace, low level API" {1156test "std.zon stringify whitespace, low level API" {
1157 var aw: std.io.AllocatingWriter = undefined;1157 var aw: std.io.AllocatingWriter = undefined;
1158 defer aw.deinit();
1159 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };1158 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1159 defer aw.deinit();
11601160
1161 for ([2]bool{ true, false }) |whitespace| {1161 for ([2]bool{ true, false }) |whitespace| {
1162 s.options = .{ .whitespace = whitespace };1162 s.options = .{ .whitespace = whitespace };
...@@ -1512,8 +1512,8 @@ test "std.zon stringify whitespace, low level API" {...@@ -1512,8 +1512,8 @@ test "std.zon stringify whitespace, low level API" {
15121512
1513test "std.zon stringify utf8 codepoints" {1513test "std.zon stringify utf8 codepoints" {
1514 var aw: std.io.AllocatingWriter = undefined;1514 var aw: std.io.AllocatingWriter = undefined;
1515 defer aw.deinit();
1516 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };1515 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1516 defer aw.deinit();
15171517
1518 // Printable ASCII1518 // Printable ASCII
1519 try s.int('a');1519 try s.int('a');
...@@ -1622,8 +1622,8 @@ test "std.zon stringify utf8 codepoints" {...@@ -1622,8 +1622,8 @@ test "std.zon stringify utf8 codepoints" {
16221622
1623test "std.zon stringify strings" {1623test "std.zon stringify strings" {
1624 var aw: std.io.AllocatingWriter = undefined;1624 var aw: std.io.AllocatingWriter = undefined;
1625 defer aw.deinit();
1626 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };1625 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1626 defer aw.deinit();
16271627
1628 // Minimal case1628 // Minimal case
1629 try s.string("abc⚡\n");1629 try s.string("abc⚡\n");
...@@ -1692,8 +1692,8 @@ test "std.zon stringify strings" {...@@ -1692,8 +1692,8 @@ test "std.zon stringify strings" {
16921692
1693test "std.zon stringify multiline strings" {1693test "std.zon stringify multiline strings" {
1694 var aw: std.io.AllocatingWriter = undefined;1694 var aw: std.io.AllocatingWriter = undefined;
1695 defer aw.deinit();
1696 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };1695 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
1696 defer aw.deinit();
16971697
1698 inline for (.{ true, false }) |whitespace| {1698 inline for (.{ true, false }) |whitespace| {
1699 s.options.whitespace = whitespace;1699 s.options.whitespace = whitespace;
...@@ -1912,8 +1912,8 @@ test "std.zon stringify skip default fields" {...@@ -1912,8 +1912,8 @@ test "std.zon stringify skip default fields" {
19121912
1913test "std.zon depth limits" {1913test "std.zon depth limits" {
1914 var aw: std.io.AllocatingWriter = undefined;1914 var aw: std.io.AllocatingWriter = undefined;
1915 defer aw.deinit();
1916 const bw = aw.init(std.testing.allocator);1915 const bw = aw.init(std.testing.allocator);
1916 defer aw.deinit();
19171917
1918 const Recurse = struct { r: []const @This() };1918 const Recurse = struct { r: []const @This() };
19191919
...@@ -2173,8 +2173,8 @@ test "std.zon stringify primitives" {...@@ -2173,8 +2173,8 @@ test "std.zon stringify primitives" {
21732173
2174test "std.zon stringify ident" {2174test "std.zon stringify ident" {
2175 var aw: std.io.AllocatingWriter = undefined;2175 var aw: std.io.AllocatingWriter = undefined;
2176 defer aw.deinit();
2177 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };2176 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2177 defer aw.deinit();
21782178
2179 try expectSerializeEqual(".{ .a = 0 }", .{ .a = 0 }, .{});2179 try expectSerializeEqual(".{ .a = 0 }", .{ .a = 0 }, .{});
2180 try s.ident("a");2180 try s.ident("a");
...@@ -2220,8 +2220,8 @@ test "std.zon stringify ident" {...@@ -2220,8 +2220,8 @@ test "std.zon stringify ident" {
22202220
2221test "std.zon stringify as tuple" {2221test "std.zon stringify as tuple" {
2222 var aw: std.io.AllocatingWriter = undefined;2222 var aw: std.io.AllocatingWriter = undefined;
2223 defer aw.deinit();
2224 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };2223 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2224 defer aw.deinit();
22252225
2226 // Tuples2226 // Tuples
2227 try s.tuple(.{ 1, 2 }, .{});2227 try s.tuple(.{ 1, 2 }, .{});
...@@ -2241,8 +2241,8 @@ test "std.zon stringify as tuple" {...@@ -2241,8 +2241,8 @@ test "std.zon stringify as tuple" {
22412241
2242test "std.zon stringify as float" {2242test "std.zon stringify as float" {
2243 var aw: std.io.AllocatingWriter = undefined;2243 var aw: std.io.AllocatingWriter = undefined;
2244 defer aw.deinit();
2245 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };2244 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2245 defer aw.deinit();
22462246
2247 // Comptime float2247 // Comptime float
2248 try s.float(2.5);2248 try s.float(2.5);
...@@ -2345,8 +2345,8 @@ test "std.zon pointers" {...@@ -2345,8 +2345,8 @@ test "std.zon pointers" {
23452345
2346test "std.zon tuple/struct field" {2346test "std.zon tuple/struct field" {
2347 var aw: std.io.AllocatingWriter = undefined;2347 var aw: std.io.AllocatingWriter = undefined;
2348 defer aw.deinit();
2349 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };2348 var s: Serializer = .{ .writer = aw.init(std.testing.allocator) };
2349 defer aw.deinit();
23502350
2351 // Test on structs2351 // Test on structs
2352 {2352 {
src/Sema.zig+1
...@@ -37371,6 +37371,7 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,...@@ -37371,6 +37371,7 @@ fn notePathToComptimeAllocPtr(sema: *Sema, msg: *Zcu.ErrorMsg, src: LazySrcLoc,
3737137371
37372 var second_path_aw: std.io.AllocatingWriter = undefined;37372 var second_path_aw: std.io.AllocatingWriter = undefined;
37373 second_path_aw.init(arena);37373 second_path_aw.init(arena);
37374 defer second_path_aw.deinit();
37374 const inter_name = try std.fmt.allocPrint(arena, "v{d}", .{intermediate_value_count});37375 const inter_name = try std.fmt.allocPrint(arena, "v{d}", .{intermediate_value_count});
37375 const deriv_start = @import("print_value.zig").printPtrDerivation(37376 const deriv_start = @import("print_value.zig").printPtrDerivation(
37376 derivation,37377 derivation,
src/Zcu.zig+4-4
...@@ -2857,7 +2857,7 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.F...@@ -2857,7 +2857,7 @@ pub fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.F
2857 var cache_fr = cache_file.reader();2857 var cache_fr = cache_file.reader();
2858 var cache_br = cache_fr.interface().unbuffered();2858 var cache_br = cache_fr.interface().unbuffered();
2859 cache_br.readVecAll(&vecs) catch |err| switch (err) {2859 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.?,
2861 error.EndOfStream => return error.UnexpectedFileSize,2861 error.EndOfStream => return error.UnexpectedFileSize,
2862 };2862 };
2863 if (data_has_safety_tag) {2863 if (data_has_safety_tag) {
...@@ -2912,7 +2912,7 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S...@@ -2912,7 +2912,7 @@ pub fn saveZirCache(gpa: Allocator, cache_file: std.fs.File, stat: std.fs.File.S
2912 var cache_fw = cache_file.writer();2912 var cache_fw = cache_file.writer();
2913 var cache_bw = cache_fw.interface().unbuffered();2913 var cache_bw = cache_fw.interface().unbuffered();
2914 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {2914 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.?,
2916 };2916 };
2917}2917}
29182918
...@@ -2943,7 +2943,7 @@ pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir...@@ -2943,7 +2943,7 @@ pub fn saveZoirCache(cache_file: std.fs.File, stat: std.fs.File.Stat, zoir: Zoir
2943 var cache_fw = cache_file.writer();2943 var cache_fw = cache_file.writer();
2944 var cache_bw = cache_fw.interface().unbuffered();2944 var cache_bw = cache_fw.interface().unbuffered();
2945 cache_bw.writeVecAll(&vecs) catch |err| switch (err) {2945 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.?,
2947 };2947 };
2948}2948}
29492949
...@@ -2986,7 +2986,7 @@ pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs...@@ -2986,7 +2986,7 @@ pub fn loadZoirCacheBody(gpa: Allocator, header: Zoir.Header, cache_file: std.fs
2986 var cache_fr = cache_file.reader();2986 var cache_fr = cache_file.reader();
2987 var cache_br = cache_fr.interface().unbuffered();2987 var cache_br = cache_fr.interface().unbuffered();
2988 cache_br.readVecAll(&vecs) catch |err| switch (err) {2988 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.?,
2990 error.EndOfStream => return error.UnexpectedFileSize,2990 error.EndOfStream => return error.UnexpectedFileSize,
2991 };2991 };
2992 return zoir;2992 return zoir;
src/Zcu/PerThread.zig+2-2
...@@ -254,7 +254,7 @@ pub fn updateFile(...@@ -254,7 +254,7 @@ pub fn updateFile(
254 var source_fr = source_file.reader();254 var source_fr = source_file.reader();
255 var source_br = source_fr.interface().unbuffered();255 var source_br = source_fr.interface().unbuffered();
256 source_br.readSlice(source) catch |err| switch (err) {256 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.?,
258 error.EndOfStream => return error.UnexpectedEndOfFile,258 error.EndOfStream => return error.UnexpectedEndOfFile,
259 };259 };
260260
...@@ -2443,7 +2443,7 @@ fn updateEmbedFileInner(...@@ -2443,7 +2443,7 @@ fn updateEmbedFileInner(
2443 var fr = file.reader();2443 var fr = file.reader();
2444 var br = fr.interface().unbuffered();2444 var br = fr.interface().unbuffered();
2445 br.readSlice(bytes[0..size]) catch |err| switch (err) {2445 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.?,
2447 error.EndOfStream => return error.UnexpectedEof,2447 error.EndOfStream => return error.UnexpectedEof,
2448 };2448 };
2449 bytes[size] = 0;2449 bytes[size] = 0;
src/codegen/c.zig+2006-1915
...@@ -69,6 +69,8 @@ pub const Mir = struct {...@@ -69,6 +69,8 @@ pub const Mir = struct {
69 }69 }
70};70};
7171
72pub const Error = std.io.Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
73
72pub const CType = @import("c/Type.zig");74pub const CType = @import("c/Type.zig");
7375
74pub const CValue = union(enum) {76pub const CValue = union(enum) {
...@@ -342,24 +344,23 @@ fn isReservedIdent(ident: []const u8) bool {...@@ -342,24 +344,23 @@ fn isReservedIdent(ident: []const u8) bool {
342344
343fn formatIdent(345fn formatIdent(
344 ident: []const u8,346 ident: []const u8,
347 bw: *std.io.BufferedWriter,
345 comptime fmt_str: []const u8,348 comptime fmt_str: []const u8,
346 _: std.fmt.FormatOptions,349) std.io.Writer.Error!void {
347 writer: anytype,
348) @TypeOf(writer).Error!void {
349 const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.350 const solo = fmt_str.len != 0 and fmt_str[0] == ' '; // space means solo; not part of a bigger ident.
350 if (solo and isReservedIdent(ident)) {351 if (solo and isReservedIdent(ident)) {
351 try writer.writeAll("zig_e_");352 try bw.writeAll("zig_e_");
352 }353 }
353 for (ident, 0..) |c, i| {354 for (ident, 0..) |c, i| {
354 switch (c) {355 switch (c) {
355 'a'...'z', 'A'...'Z', '_' => try writer.writeByte(c),356 'a'...'z', 'A'...'Z', '_' => try bw.writeByte(c),
356 '.' => try writer.writeByte('_'),357 '.' => try bw.writeByte('_'),
357 '0'...'9' => if (i == 0) {358 '0'...'9' => if (i == 0) {
358 try writer.print("_{x:2}", .{c});359 try bw.print("_{x:2}", .{c});
359 } else {360 } else {
360 try writer.writeByte(c);361 try bw.writeByte(c);
361 },362 },
362 else => try writer.print("_{x:2}", .{c}),363 else => try bw.print("_{x:2}", .{c}),
363 }364 }
364 }365 }
365}366}
...@@ -373,14 +374,13 @@ const CTypePoolStringFormatData = struct {...@@ -373,14 +374,13 @@ const CTypePoolStringFormatData = struct {
373};374};
374fn formatCTypePoolString(375fn formatCTypePoolString(
375 data: CTypePoolStringFormatData,376 data: CTypePoolStringFormatData,
377 bw: *std.io.BufferedWriter,
376 comptime fmt_str: []const u8,378 comptime fmt_str: []const u8,
377 fmt_opts: std.fmt.FormatOptions,379) std.io.Writer.Error!void {
378 writer: anytype,
379) @TypeOf(writer).Error!void {
380 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|380 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)
382 else382 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)});
384}384}
385pub fn fmtCTypePoolString(385pub fn fmtCTypePoolString(
386 ctype_pool_string: CType.Pool.String,386 ctype_pool_string: CType.Pool.String,
...@@ -440,18 +440,18 @@ pub const Function = struct {...@@ -440,18 +440,18 @@ pub const Function = struct {
440 const ty = f.typeOf(ref);440 const ty = f.typeOf(ref);
441441
442 const result: CValue = if (lowersToArray(ty, pt)) result: {442 const result: CValue = if (lowersToArray(ty, pt)) result: {
443 const writer = f.object.codeHeaderWriter();443 const ch = &f.object.code_header.buffered_writer;
444 const decl_c_value = try f.allocLocalValue(.{444 const decl_c_value = try f.allocLocalValue(.{
445 .ctype = try f.ctypeFromType(ty, .complete),445 .ctype = try f.ctypeFromType(ty, .complete),
446 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)),446 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)),
447 });447 });
448 const gpa = f.object.dg.gpa;448 const gpa = f.object.dg.gpa;
449 try f.allocs.put(gpa, decl_c_value.new_local, false);449 try f.allocs.put(gpa, decl_c_value.new_local, false);
450 try writer.writeAll("static ");450 try ch.writeAll("static ");
451 try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, Const, .none, .complete);451 try f.object.dg.renderTypeAndName(ch, ty, decl_c_value, Const, .none, .complete);
452 try writer.writeAll(" = ");452 try ch.writeAll(" = ");
453 try f.object.dg.renderValue(writer, val, .StaticInitializer);453 try f.object.dg.renderValue(ch, val, .StaticInitializer);
454 try writer.writeAll(";\n ");454 try ch.writeAll(";\n ");
455 break :result .{ .local = decl_c_value.new_local };455 break :result .{ .local = decl_c_value.new_local };
456 } else .{ .constant = val };456 } else .{ .constant = val };
457457
...@@ -504,75 +504,75 @@ pub const Function = struct {...@@ -504,75 +504,75 @@ pub const Function = struct {
504 return result;504 return result;
505 }505 }
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 {
508 switch (c_value) {508 switch (c_value) {
509 .none => unreachable,509 .none => unreachable,
510 .new_local, .local => |i| try w.print("t{d}", .{i}),510 .new_local, .local => |i| try bw.print("t{d}", .{i}),
511 .local_ref => |i| try w.print("&t{d}", .{i}),511 .local_ref => |i| try bw.print("&t{d}", .{i}),
512 .constant => |val| try f.object.dg.renderValue(w, val, location),512 .constant => |val| try f.object.dg.renderValue(bw, val, location),
513 .arg => |i| try w.print("a{d}", .{i}),513 .arg => |i| try bw.print("a{d}", .{i}),
514 .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),514 .arg_array => |i| try f.writeCValueMember(bw, .{ .arg = i }, .{ .identifier = "array" }),
515 .undef => |ty| try f.object.dg.renderUndefValue(w, ty, location),515 .undef => |ty| try f.object.dg.renderUndefValue(bw, ty, location),
516 else => try f.object.dg.writeCValue(w, c_value),516 else => try f.object.dg.writeCValue(bw, c_value),
517 }517 }
518 }518 }
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 {
521 switch (c_value) {521 switch (c_value) {
522 .none => unreachable,522 .none => unreachable,
523 .new_local, .local, .constant => {523 .new_local, .local, .constant => {
524 try w.writeAll("(*");524 try bw.writeAll("(*");
525 try f.writeCValue(w, c_value, .Other);525 try f.writeCValue(bw, c_value, .Other);
526 try w.writeByte(')');526 try bw.writeByte(')');
527 },527 },
528 .local_ref => |i| try w.print("t{d}", .{i}),528 .local_ref => |i| try bw.print("t{d}", .{i}),
529 .arg => |i| try w.print("(*a{d})", .{i}),529 .arg => |i| try bw.print("(*a{d})", .{i}),
530 .arg_array => |i| {530 .arg_array => |i| {
531 try w.writeAll("(*");531 try bw.writeAll("(*");
532 try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" });532 try f.writeCValueMember(bw, .{ .arg = i }, .{ .identifier = "array" });
533 try w.writeByte(')');533 try bw.writeByte(')');
534 },534 },
535 else => try f.object.dg.writeCValueDeref(w, c_value),535 else => try f.object.dg.writeCValueDeref(bw, c_value),
536 }536 }
537 }537 }
538538
539 fn writeCValueMember(539 fn writeCValueMember(
540 f: *Function,540 f: *Function,
541 writer: anytype,541 bw: *std.io.BufferedWriter,
542 c_value: CValue,542 c_value: CValue,
543 member: CValue,543 member: CValue,
544 ) error{ OutOfMemory, AnalysisFail }!void {544 ) Error!void {
545 switch (c_value) {545 switch (c_value) {
546 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {546 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {
547 try f.writeCValue(writer, c_value, .Other);547 try f.writeCValue(bw, c_value, .Other);
548 try writer.writeByte('.');548 try bw.writeByte('.');
549 try f.writeCValue(writer, member, .Other);549 try f.writeCValue(bw, member, .Other);
550 },550 },
551 else => return f.object.dg.writeCValueMember(writer, c_value, member),551 else => return f.object.dg.writeCValueMember(bw, c_value, member),
552 }552 }
553 }553 }
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 {
556 switch (c_value) {556 switch (c_value) {
557 .new_local, .local, .arg, .arg_array => {557 .new_local, .local, .arg, .arg_array => {
558 try f.writeCValue(writer, c_value, .Other);558 try f.writeCValue(bw, c_value, .Other);
559 try writer.writeAll("->");559 try bw.writeAll("->");
560 },560 },
561 .constant => {561 .constant => {
562 try writer.writeByte('(');562 try bw.writeByte('(');
563 try f.writeCValue(writer, c_value, .Other);563 try f.writeCValue(bw, c_value, .Other);
564 try writer.writeAll(")->");564 try bw.writeAll(")->");
565 },565 },
566 .local_ref => {566 .local_ref => {
567 try f.writeCValueDeref(writer, c_value);567 try f.writeCValueDeref(bw, c_value);
568 try writer.writeByte('.');568 try bw.writeByte('.');
569 },569 },
570 else => return f.object.dg.writeCValueDerefMember(writer, c_value, member),570 else => return f.object.dg.writeCValueDerefMember(bw, c_value, member),
571 }571 }
572 try f.writeCValue(writer, member, .Other);572 try f.writeCValue(bw, member, .Other);
573 }573 }
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 {
576 return f.object.dg.fail(format, args);576 return f.object.dg.fail(format, args);
577 }577 }
578578
...@@ -584,16 +584,16 @@ pub const Function = struct {...@@ -584,16 +584,16 @@ pub const Function = struct {
584 return f.object.dg.byteSize(ctype);584 return f.object.dg.byteSize(ctype);
585 }585 }
586586
587 fn renderType(f: *Function, w: anytype, ctype: Type) !void {587 fn renderType(f: *Function, bw: *std.io.BufferedWriter, ctype: Type) !void {
588 return f.object.dg.renderType(w, ctype);588 return f.object.dg.renderType(bw, ctype);
589 }589 }
590590
591 fn renderCType(f: *Function, w: anytype, ctype: CType) !void {591 fn renderCType(f: *Function, bw: *std.io.BufferedWriter, ctype: CType) !void {
592 return f.object.dg.renderCType(w, ctype);592 return f.object.dg.renderCType(bw, ctype);
593 }593 }
594594
595 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {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(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);596 return f.object.dg.renderIntCast(bw, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
597 }597 }
598598
599 fn fmtIntLiteral(f: *Function, val: Value) !std.fmt.Formatter(formatIntLiteral) {599 fn fmtIntLiteral(f: *Function, val: Value) !std.fmt.Formatter(formatIntLiteral) {
...@@ -614,14 +614,14 @@ pub const Function = struct {...@@ -614,14 +614,14 @@ pub const Function = struct {
614 gop.value_ptr.* = .{614 gop.value_ptr.* = .{
615 .fn_name = switch (key) {615 .fn_name = switch (key) {
616 .tag_name,616 .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}", .{
618 @tagName(key),618 @tagName(key),
619 fmtIdent(ip.loadEnumType(enum_ty).name.toSlice(ip)),619 fmtIdent(ip.loadEnumType(enum_ty).name.toSlice(ip)),
620 @intFromEnum(enum_ty),620 @intFromEnum(enum_ty),
621 }),621 }),
622 .never_tail,622 .never_tail,
623 .never_inline,623 .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}", .{
625 @tagName(key),625 @tagName(key),
626 fmtIdent(ip.getNav(owner_nav).name.toSlice(ip)),626 fmtIdent(ip.getNav(owner_nav).name.toSlice(ip)),
627 @intFromEnum(owner_nav),627 @intFromEnum(owner_nav),
...@@ -659,12 +659,12 @@ pub const Function = struct {...@@ -659,12 +659,12 @@ pub const Function = struct {
659 },659 },
660 else => {},660 else => {},
661 }661 }
662 const writer = f.object.writer();662 const bw = &f.object.code.buffered_writer;
663 const a = try Assignment.start(f, writer, ctype);663 const a = try Assignment.start(f, bw, ctype);
664 try f.writeCValue(writer, dst, .Other);664 try f.writeCValue(bw, dst, .Other);
665 try a.assign(f, writer);665 try a.assign(f, bw);
666 try f.writeCValue(writer, src, .Other);666 try f.writeCValue(bw, src, .Other);
667 try a.end(f, writer);667 try a.end(f, bw);
668 }668 }
669669
670 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {670 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
...@@ -699,7 +699,7 @@ pub const Object = struct {...@@ -699,7 +699,7 @@ pub const Object = struct {
699699
700 const indent_width = 1;700 const indent_width = 1;
701701
702 fn nl(o: *Object) anyerror!void {702 fn newline(o: *Object) !void {
703 const bw = &o.code.buffered_writer;703 const bw = &o.code.buffered_writer;
704 try bw.writeByte('\n');704 try bw.writeByte('\n');
705 try bw.splatByteAll(' ', o.indent_counter);705 try bw.splatByteAll(' ', o.indent_counter);
...@@ -737,7 +737,7 @@ pub const DeclGen = struct {...@@ -737,7 +737,7 @@ pub const DeclGen = struct {
737 flush,737 flush,
738 };738 };
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 {
741 @branchHint(.cold);741 @branchHint(.cold);
742 const zcu = dg.pt.zcu;742 const zcu = dg.pt.zcu;
743 const src_loc = zcu.navSrcLoc(dg.pass.nav);743 const src_loc = zcu.navSrcLoc(dg.pass.nav);
...@@ -747,10 +747,10 @@ pub const DeclGen = struct {...@@ -747,10 +747,10 @@ pub const DeclGen = struct {
747747
748 fn renderUav(748 fn renderUav(
749 dg: *DeclGen,749 dg: *DeclGen,
750 writer: anytype,750 bw: *std.io.BufferedWriter,
751 uav: InternPool.Key.Ptr.BaseAddr.Uav,751 uav: InternPool.Key.Ptr.BaseAddr.Uav,
752 location: ValueRenderLocation,752 location: ValueRenderLocation,
753 ) error{ OutOfMemory, AnalysisFail }!void {753 ) Error!void {
754 const pt = dg.pt;754 const pt = dg.pt;
755 const zcu = pt.zcu;755 const zcu = pt.zcu;
756 const ip = &zcu.intern_pool;756 const ip = &zcu.intern_pool;
...@@ -761,14 +761,14 @@ pub const DeclGen = struct {...@@ -761,14 +761,14 @@ pub const DeclGen = struct {
761 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.761 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
762 const ptr_ty: Type = .fromInterned(uav.orig_ty);762 const ptr_ty: Type = .fromInterned(uav.orig_ty);
763 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {763 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 });
765 }765 }
766766
767 // Chase function values in order to be able to reference the original function.767 // Chase function values in order to be able to reference the original function.
768 switch (ip.indexToKey(uav.val)) {768 switch (ip.indexToKey(uav.val)) {
769 .variable => unreachable,769 .variable => unreachable,
770 .func => |func| return dg.renderNav(writer, func.owner_nav, location),770 .func => |func| return dg.renderNav(bw, func.owner_nav, location),
771 .@"extern" => |@"extern"| return dg.renderNav(writer, @"extern".owner_nav, location),771 .@"extern" => |@"extern"| return dg.renderNav(bw, @"extern".owner_nav, location),
772 else => {},772 else => {},
773 }773 }
774774
...@@ -782,13 +782,13 @@ pub const DeclGen = struct {...@@ -782,13 +782,13 @@ pub const DeclGen = struct {
782 const need_cast = !elem_ctype.eql(uav_ctype) and782 const need_cast = !elem_ctype.eql(uav_ctype) and
783 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);783 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
784 if (need_cast) {784 if (need_cast) {
785 try writer.writeAll("((");785 try bw.writeAll("((");
786 try dg.renderCType(writer, ptr_ctype);786 try dg.renderCType(bw, ptr_ctype);
787 try writer.writeByte(')');787 try bw.writeByte(')');
788 }788 }
789 try writer.writeByte('&');789 try bw.writeByte('&');
790 try renderUavName(writer, uav_val);790 try renderUavName(bw, uav_val);
791 if (need_cast) try writer.writeByte(')');791 if (need_cast) try bw.writeByte(')');
792792
793 // Indicate that the anon decl should be rendered to the output so that793 // Indicate that the anon decl should be rendered to the output so that
794 // our reference above is not undefined.794 // our reference above is not undefined.
...@@ -809,10 +809,10 @@ pub const DeclGen = struct {...@@ -809,10 +809,10 @@ pub const DeclGen = struct {
809809
810 fn renderNav(810 fn renderNav(
811 dg: *DeclGen,811 dg: *DeclGen,
812 writer: anytype,812 bw: *std.io.BufferedWriter,
813 nav_index: InternPool.Nav.Index,813 nav_index: InternPool.Nav.Index,
814 location: ValueRenderLocation,814 location: ValueRenderLocation,
815 ) error{ OutOfMemory, AnalysisFail }!void {815 ) Error!void {
816 _ = location;816 _ = location;
817 const pt = dg.pt;817 const pt = dg.pt;
818 const zcu = pt.zcu;818 const zcu = pt.zcu;
...@@ -834,7 +834,7 @@ pub const DeclGen = struct {...@@ -834,7 +834,7 @@ pub const DeclGen = struct {
834 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));834 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));
835 const ptr_ty = try pt.navPtrType(owner_nav);835 const ptr_ty = try pt.navPtrType(owner_nav);
836 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {836 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {
837 return dg.writeCValue(writer, .{ .undef = ptr_ty });837 return dg.writeCValue(bw, .{ .undef = ptr_ty });
838 }838 }
839839
840 // We shouldn't cast C function pointers as this is UB (when you call840 // We shouldn't cast C function pointers as this is UB (when you call
...@@ -847,21 +847,21 @@ pub const DeclGen = struct {...@@ -847,21 +847,21 @@ pub const DeclGen = struct {
847 const need_cast = !elem_ctype.eql(nav_ctype) and847 const need_cast = !elem_ctype.eql(nav_ctype) and
848 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);848 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
849 if (need_cast) {849 if (need_cast) {
850 try writer.writeAll("((");850 try bw.writeAll("((");
851 try dg.renderCType(writer, ctype);851 try dg.renderCType(bw, ctype);
852 try writer.writeByte(')');852 try bw.writeByte(')');
853 }853 }
854 try writer.writeByte('&');854 try bw.writeByte('&');
855 try dg.renderNavName(writer, owner_nav);855 try dg.renderNavName(bw, owner_nav);
856 if (need_cast) try writer.writeByte(')');856 if (need_cast) try bw.writeByte(')');
857 }857 }
858858
859 fn renderPointer(859 fn renderPointer(
860 dg: *DeclGen,860 dg: *DeclGen,
861 writer: anytype,861 bw: *std.io.BufferedWriter,
862 derivation: Value.PointerDeriveStep,862 derivation: Value.PointerDeriveStep,
863 location: ValueRenderLocation,863 location: ValueRenderLocation,
864 ) error{ OutOfMemory, AnalysisFail }!void {864 ) Error!void {
865 const pt = dg.pt;865 const pt = dg.pt;
866 const zcu = pt.zcu;866 const zcu = pt.zcu;
867 switch (derivation) {867 switch (derivation) {
...@@ -869,18 +869,18 @@ pub const DeclGen = struct {...@@ -869,18 +869,18 @@ pub const DeclGen = struct {
869 .int => |int| {869 .int => |int| {
870 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);870 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
871 const addr_val = try pt.intValue(.usize, int.addr);871 const addr_val = try pt.intValue(.usize, int.addr);
872 try writer.writeByte('(');872 try bw.writeByte('(');
873 try dg.renderCType(writer, ptr_ctype);873 try dg.renderCType(bw, ptr_ctype);
874 try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)});874 try bw.print("){fx}", .{try dg.fmtIntLiteral(addr_val, .Other)});
875 },875 },
876876
877 .nav_ptr => |nav| try dg.renderNav(writer, nav, location),877 .nav_ptr => |nav| try dg.renderNav(bw, nav, location),
878 .uav_ptr => |uav| try dg.renderUav(writer, uav, location),878 .uav_ptr => |uav| try dg.renderUav(bw, uav, location),
879879
880 inline .eu_payload_ptr, .opt_payload_ptr => |info| {880 inline .eu_payload_ptr, .opt_payload_ptr => |info| {
881 try writer.writeAll("&(");881 try bw.writeAll("&(");
882 try dg.renderPointer(writer, info.parent.*, location);882 try dg.renderPointer(bw, info.parent.*, location);
883 try writer.writeAll(")->payload");883 try bw.writeAll(")->payload");
884 },884 },
885885
886 .field_ptr => |field| {886 .field_ptr => |field| {
...@@ -892,26 +892,26 @@ pub const DeclGen = struct {...@@ -892,26 +892,26 @@ pub const DeclGen = struct {
892 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {892 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {
893 .begin => {893 .begin => {
894 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);894 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
895 try writer.writeByte('(');895 try bw.writeByte('(');
896 try dg.renderCType(writer, ptr_ctype);896 try dg.renderCType(bw, ptr_ctype);
897 try writer.writeByte(')');897 try bw.writeByte(')');
898 try dg.renderPointer(writer, field.parent.*, location);898 try dg.renderPointer(bw, field.parent.*, location);
899 },899 },
900 .field => |name| {900 .field => |name| {
901 try writer.writeAll("&(");901 try bw.writeAll("&(");
902 try dg.renderPointer(writer, field.parent.*, location);902 try dg.renderPointer(bw, field.parent.*, location);
903 try writer.writeAll(")->");903 try bw.writeAll(")->");
904 try dg.writeCValue(writer, name);904 try dg.writeCValue(bw, name);
905 },905 },
906 .byte_offset => |byte_offset| {906 .byte_offset => |byte_offset| {
907 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);907 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
908 try writer.writeByte('(');908 try bw.writeByte('(');
909 try dg.renderCType(writer, ptr_ctype);909 try dg.renderCType(bw, ptr_ctype);
910 try writer.writeByte(')');910 try bw.writeByte(')');
911 const offset_val = try pt.intValue(.usize, byte_offset);911 const offset_val = try pt.intValue(.usize, byte_offset);
912 try writer.writeAll("((char *)");912 try bw.writeAll("((char *)");
913 try dg.renderPointer(writer, field.parent.*, location);913 try dg.renderPointer(bw, field.parent.*, location);
914 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});914 try bw.print(" + {f})", .{try dg.fmtIntLiteral(offset_val, .Other)});
915 },915 },
916 }916 }
917 },917 },
...@@ -919,10 +919,10 @@ pub const DeclGen = struct {...@@ -919,10 +919,10 @@ pub const DeclGen = struct {
919 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {919 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {
920 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.920 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.
921 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);921 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
922 try writer.writeByte('(');922 try bw.writeByte('(');
923 try dg.renderCType(writer, ptr_ctype);923 try dg.renderCType(bw, ptr_ctype);
924 try writer.writeByte(')');924 try bw.writeByte(')');
925 try dg.renderPointer(writer, elem.parent.*, location);925 try dg.renderPointer(bw, elem.parent.*, location);
926 } else {926 } else {
927 const index_val = try pt.intValue(.usize, elem.elem_idx);927 const index_val = try pt.intValue(.usize, elem.elem_idx);
928 // We want to do pointer arithmetic on a pointer to the element type.928 // We want to do pointer arithmetic on a pointer to the element type.
...@@ -931,48 +931,47 @@ pub const DeclGen = struct {...@@ -931,48 +931,47 @@ pub const DeclGen = struct {
931 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);931 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);
932 if (result_ctype.eql(parent_ctype)) {932 if (result_ctype.eql(parent_ctype)) {
933 // The pointer already has an appropriate type - just do the arithmetic.933 // The pointer already has an appropriate type - just do the arithmetic.
934 try writer.writeByte('(');934 try bw.writeByte('(');
935 try dg.renderPointer(writer, elem.parent.*, location);935 try dg.renderPointer(bw, elem.parent.*, location);
936 try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)});936 try bw.print(" + {f})", .{try dg.fmtIntLiteral(index_val, .Other)});
937 } else {937 } else {
938 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,938 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,
939 // and *then* apply the index.939 // and *then* apply the index.
940 try writer.writeAll("((");940 try bw.writeAll("((");
941 try dg.renderCType(writer, result_ctype);941 try dg.renderCType(bw, result_ctype);
942 try writer.writeByte(')');942 try bw.writeByte(')');
943 try dg.renderPointer(writer, elem.parent.*, location);943 try dg.renderPointer(bw, elem.parent.*, location);
944 try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)});944 try bw.print(" + {f})", .{try dg.fmtIntLiteral(index_val, .Other)});
945 }945 }
946 },946 },
947947
948 .offset_and_cast => |oac| {948 .offset_and_cast => |oac| {
949 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);949 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);
950 try writer.writeByte('(');950 try bw.writeByte('(');
951 try dg.renderCType(writer, ptr_ctype);951 try dg.renderCType(bw, ptr_ctype);
952 try writer.writeByte(')');952 try bw.writeByte(')');
953 if (oac.byte_offset == 0) {953 if (oac.byte_offset == 0) {
954 try dg.renderPointer(writer, oac.parent.*, location);954 try dg.renderPointer(bw, oac.parent.*, location);
955 } else {955 } else {
956 const offset_val = try pt.intValue(.usize, oac.byte_offset);956 const offset_val = try pt.intValue(.usize, oac.byte_offset);
957 try writer.writeAll("((char *)");957 try bw.writeAll("((char *)");
958 try dg.renderPointer(writer, oac.parent.*, location);958 try dg.renderPointer(bw, oac.parent.*, location);
959 try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)});959 try bw.print(" + {f})", .{try dg.fmtIntLiteral(offset_val, .Other)});
960 }960 }
961 },961 },
962 }962 }
963 }963 }
964964
965 fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {965 fn renderErrorName(dg: *DeclGen, bw: *std.io.BufferedWriter, err_name: InternPool.NullTerminatedString) !void {
966 const ip = &dg.pt.zcu.intern_pool;966 try bw.print("zig_error_{f}", .{fmtIdent(err_name.toSlice(&dg.pt.zcu.intern_pool))});
967 try writer.print("zig_error_{}", .{fmtIdent(err_name.toSlice(ip))});
968 }967 }
969968
970 fn renderValue(969 fn renderValue(
971 dg: *DeclGen,970 dg: *DeclGen,
972 writer: anytype,971 writer: *std.io.BufferedWriter,
973 val: Value,972 val: Value,
974 location: ValueRenderLocation,973 location: ValueRenderLocation,
975 ) error{ OutOfMemory, AnalysisFail }!void {974 ) Error!void {
976 const pt = dg.pt;975 const pt = dg.pt;
977 const zcu = pt.zcu;976 const zcu = pt.zcu;
978 const ip = &zcu.intern_pool;977 const ip = &zcu.intern_pool;
...@@ -1028,11 +1027,11 @@ pub const DeclGen = struct {...@@ -1028,11 +1027,11 @@ pub const DeclGen = struct {
1028 .empty_enum_value,1027 .empty_enum_value,
1029 => unreachable, // non-runtime values1028 => unreachable, // non-runtime values
1030 .int => |int| switch (int.storage) {1029 .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)}),
1032 .lazy_align, .lazy_size => {1031 .lazy_align, .lazy_size => {
1033 try writer.writeAll("((");1032 try writer.writeAll("((");
1034 try dg.renderCType(writer, ctype);1033 try dg.renderCType(writer, ctype);
1035 try writer.print("){x})", .{try dg.fmtIntLiteral(1034 try writer.print("){fx})", .{try dg.fmtIntLiteral(
1036 try pt.intValue(.usize, val.toUnsignedInt(zcu)),1035 try pt.intValue(.usize, val.toUnsignedInt(zcu)),
1037 .Other,1036 .Other,
1038 )});1037 )});
...@@ -1161,7 +1160,7 @@ pub const DeclGen = struct {...@@ -1161,7 +1160,7 @@ pub const DeclGen = struct {
1161 try writer.writeAll(", ");1160 try writer.writeAll(", ");
1162 empty = false;1161 empty = false;
1163 }1162 }
1164 try writer.print("{x}", .{try dg.fmtIntLiteral(1163 try writer.print("{fx}", .{try dg.fmtIntLiteral(
1165 try pt.intValue_big(repr_ty, repr_val_big.toConst()),1164 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1166 location,1165 location,
1167 )});1166 )});
...@@ -1550,7 +1549,7 @@ pub const DeclGen = struct {...@@ -1550,7 +1549,7 @@ pub const DeclGen = struct {
1550 .payload => {1549 .payload => {
1551 try writer.writeByte('{');1550 try writer.writeByte('{');
1552 if (field_ty.hasRuntimeBits(zcu)) {1551 if (field_ty.hasRuntimeBits(zcu)) {
1553 try writer.print(" .{ } = ", .{fmtIdent(field_name.toSlice(ip))});1552 try writer.print(" .{f } = ", .{fmtIdent(field_name.toSlice(ip))});
1554 try dg.renderValue(1553 try dg.renderValue(
1555 writer,1554 writer,
1556 Value.fromInterned(un.val),1555 Value.fromInterned(un.val),
...@@ -1578,10 +1577,10 @@ pub const DeclGen = struct {...@@ -1578,10 +1577,10 @@ pub const DeclGen = struct {
15781577
1579 fn renderUndefValue(1578 fn renderUndefValue(
1580 dg: *DeclGen,1579 dg: *DeclGen,
1581 writer: anytype,1580 bw: *std.io.BufferedWriter,
1582 ty: Type,1581 ty: Type,
1583 location: ValueRenderLocation,1582 location: ValueRenderLocation,
1584 ) error{ OutOfMemory, AnalysisFail }!void {1583 ) Error!void {
1585 const pt = dg.pt;1584 const pt = dg.pt;
1586 const zcu = pt.zcu;1585 const zcu = pt.zcu;
1587 const ip = &zcu.intern_pool;1586 const ip = &zcu.intern_pool;
...@@ -1611,57 +1610,57 @@ pub const DeclGen = struct {...@@ -1611,57 +1610,57 @@ pub const DeclGen = struct {
1611 // All unsigned ints matching float types are pre-allocated.1610 // All unsigned ints matching float types are pre-allocated.
1612 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;1611 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
16131612
1614 try writer.writeAll("zig_make_");1613 try bw.writeAll("zig_make_");
1615 try dg.renderTypeForBuiltinFnName(writer, ty);1614 try dg.renderTypeForBuiltinFnName(bw, ty);
1616 try writer.writeByte('(');1615 try bw.writeByte('(');
1617 switch (bits) {1616 switch (bits) {
1618 16 => try writer.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),1617 16 => try bw.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1619 32 => try writer.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),1618 32 => try bw.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1620 64 => try writer.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),1619 64 => try bw.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1621 80 => try writer.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),1620 80 => try bw.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1622 128 => try writer.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),1621 128 => try bw.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
1623 else => unreachable,1622 else => unreachable,
1624 }1623 }
1625 try writer.writeAll(", ");1624 try bw.writeAll(", ");
1626 try dg.renderUndefValue(writer, repr_ty, .FunctionArgument);1625 try dg.renderUndefValue(bw, repr_ty, .FunctionArgument);
1627 return writer.writeByte(')');1626 return bw.writeByte(')');
1628 },1627 },
1629 .bool_type => try writer.writeAll(if (safety_on) "0xaa" else "false"),1628 .bool_type => try bw.writeAll(if (safety_on) "0xaa" else "false"),
1630 else => switch (ip.indexToKey(ty.toIntern())) {1629 else => switch (ip.indexToKey(ty.toIntern())) {
1631 .simple_type,1630 .simple_type,
1632 .int_type,1631 .int_type,
1633 .enum_type,1632 .enum_type,
1634 .error_set_type,1633 .error_set_type,
1635 .inferred_error_set_type,1634 .inferred_error_set_type,
1636 => return writer.print("{x}", .{1635 => return bw.print("{fx}", .{
1637 try dg.fmtIntLiteral(try pt.undefValue(ty), location),1636 try dg.fmtIntLiteral(try pt.undefValue(ty), location),
1638 }),1637 }),
1639 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1638 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1640 .one, .many, .c => {1639 .one, .many, .c => {
1641 try writer.writeAll("((");1640 try bw.writeAll("((");
1642 try dg.renderCType(writer, ctype);1641 try dg.renderCType(bw, ctype);
1643 return writer.print("){x})", .{1642 return bw.print("){fx})", .{
1644 try dg.fmtIntLiteral(.undef_usize, .Other),1643 try dg.fmtIntLiteral(.undef_usize, .Other),
1645 });1644 });
1646 },1645 },
1647 .slice => {1646 .slice => {
1648 if (!location.isInitializer()) {1647 if (!location.isInitializer()) {
1649 try writer.writeByte('(');1648 try bw.writeByte('(');
1650 try dg.renderCType(writer, ctype);1649 try dg.renderCType(bw, ctype);
1651 try writer.writeByte(')');1650 try bw.writeByte(')');
1652 }1651 }
16531652
1654 try writer.writeAll("{(");1653 try bw.writeAll("{(");
1655 const ptr_ty = ty.slicePtrFieldType(zcu);1654 const ptr_ty = ty.slicePtrFieldType(zcu);
1656 try dg.renderType(writer, ptr_ty);1655 try dg.renderType(bw, ptr_ty);
1657 return writer.print("){x}, {0x}}}", .{1656 return bw.print("){fx}, {0fx}}}", .{
1658 try dg.fmtIntLiteral(.undef_usize, .Other),1657 try dg.fmtIntLiteral(.undef_usize, .Other),
1659 });1658 });
1660 },1659 },
1661 },1660 },
1662 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {1661 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {
1663 .basic, .pointer => try dg.renderUndefValue(1662 .basic, .pointer => try dg.renderUndefValue(
1664 writer,1663 bw,
1665 .fromInterned(if (ctype.isBool()) .bool_type else child_type),1664 .fromInterned(if (ctype.isBool()) .bool_type else child_type),
1666 location,1665 location,
1667 ),1666 ),
...@@ -1670,21 +1669,21 @@ pub const DeclGen = struct {...@@ -1670,21 +1669,21 @@ pub const DeclGen = struct {
1670 switch (aggregate.fields.at(0, ctype_pool).name.index) {1669 switch (aggregate.fields.at(0, ctype_pool).name.index) {
1671 .is_null, .payload => {},1670 .is_null, .payload => {},
1672 .ptr, .len => return dg.renderUndefValue(1671 .ptr, .len => return dg.renderUndefValue(
1673 writer,1672 bw,
1674 .fromInterned(child_type),1673 .fromInterned(child_type),
1675 location,1674 location,
1676 ),1675 ),
1677 else => unreachable,1676 else => unreachable,
1678 }1677 }
1679 if (!location.isInitializer()) {1678 if (!location.isInitializer()) {
1680 try writer.writeByte('(');1679 try bw.writeByte('(');
1681 try dg.renderCType(writer, ctype);1680 try dg.renderCType(bw, ctype);
1682 try writer.writeByte(')');1681 try bw.writeByte(')');
1683 }1682 }
1684 try writer.writeByte('{');1683 try bw.writeByte('{');
1685 for (0..aggregate.fields.len) |field_index| {1684 for (0..aggregate.fields.len) |field_index| {
1686 if (field_index > 0) try writer.writeByte(',');1685 if (field_index > 0) try bw.writeByte(',');
1687 try dg.renderUndefValue(writer, .fromInterned(1686 try dg.renderUndefValue(bw, .fromInterned(
1688 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1687 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1689 .is_null => .bool_type,1688 .is_null => .bool_type,
1690 .payload => child_type,1689 .payload => child_type,
...@@ -1692,7 +1691,7 @@ pub const DeclGen = struct {...@@ -1692,7 +1691,7 @@ pub const DeclGen = struct {
1692 },1691 },
1693 ), initializer_type);1692 ), initializer_type);
1694 }1693 }
1695 try writer.writeByte('}');1694 try bw.writeByte('}');
1696 },1695 },
1697 },1696 },
1698 .struct_type => {1697 .struct_type => {
...@@ -1700,117 +1699,117 @@ pub const DeclGen = struct {...@@ -1700,117 +1699,117 @@ pub const DeclGen = struct {
1700 switch (loaded_struct.layout) {1699 switch (loaded_struct.layout) {
1701 .auto, .@"extern" => {1700 .auto, .@"extern" => {
1702 if (!location.isInitializer()) {1701 if (!location.isInitializer()) {
1703 try writer.writeByte('(');1702 try bw.writeByte('(');
1704 try dg.renderCType(writer, ctype);1703 try dg.renderCType(bw, ctype);
1705 try writer.writeByte(')');1704 try bw.writeByte(')');
1706 }1705 }
17071706
1708 try writer.writeByte('{');1707 try bw.writeByte('{');
1709 var field_it = loaded_struct.iterateRuntimeOrder(ip);1708 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1710 var need_comma = false;1709 var need_comma = false;
1711 while (field_it.next()) |field_index| {1710 while (field_it.next()) |field_index| {
1712 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1711 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1713 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1712 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17141713
1715 if (need_comma) try writer.writeByte(',');1714 if (need_comma) try bw.writeByte(',');
1716 need_comma = true;1715 need_comma = true;
1717 try dg.renderUndefValue(writer, field_ty, initializer_type);1716 try dg.renderUndefValue(bw, field_ty, initializer_type);
1718 }1717 }
1719 return writer.writeByte('}');1718 return bw.writeByte('}');
1720 },1719 },
1721 .@"packed" => return writer.print("{x}", .{1720 .@"packed" => return bw.print("{fx}", .{
1722 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),1721 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
1723 }),1722 }),
1724 }1723 }
1725 },1724 },
1726 .tuple_type => |tuple_info| {1725 .tuple_type => |tuple_info| {
1727 if (!location.isInitializer()) {1726 if (!location.isInitializer()) {
1728 try writer.writeByte('(');1727 try bw.writeByte('(');
1729 try dg.renderCType(writer, ctype);1728 try dg.renderCType(bw, ctype);
1730 try writer.writeByte(')');1729 try bw.writeByte(')');
1731 }1730 }
17321731
1733 try writer.writeByte('{');1732 try bw.writeByte('{');
1734 var need_comma = false;1733 var need_comma = false;
1735 for (0..tuple_info.types.len) |field_index| {1734 for (0..tuple_info.types.len) |field_index| {
1736 if (tuple_info.values.get(ip)[field_index] != .none) continue;1735 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1737 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);1736 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
1738 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1737 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17391738
1740 if (need_comma) try writer.writeByte(',');1739 if (need_comma) try bw.writeByte(',');
1741 need_comma = true;1740 need_comma = true;
1742 try dg.renderUndefValue(writer, field_ty, initializer_type);1741 try dg.renderUndefValue(bw, field_ty, initializer_type);
1743 }1742 }
1744 return writer.writeByte('}');1743 return bw.writeByte('}');
1745 },1744 },
1746 .union_type => {1745 .union_type => {
1747 const loaded_union = ip.loadUnionType(ty.toIntern());1746 const loaded_union = ip.loadUnionType(ty.toIntern());
1748 switch (loaded_union.flagsUnordered(ip).layout) {1747 switch (loaded_union.flagsUnordered(ip).layout) {
1749 .auto, .@"extern" => {1748 .auto, .@"extern" => {
1750 if (!location.isInitializer()) {1749 if (!location.isInitializer()) {
1751 try writer.writeByte('(');1750 try bw.writeByte('(');
1752 try dg.renderCType(writer, ctype);1751 try dg.renderCType(bw, ctype);
1753 try writer.writeByte(')');1752 try bw.writeByte(')');
1754 }1753 }
17551754
1756 const has_tag = loaded_union.hasTag(ip);1755 const has_tag = loaded_union.hasTag(ip);
1757 if (has_tag) try writer.writeByte('{');1756 if (has_tag) try bw.writeByte('{');
1758 const aggregate = ctype.info(ctype_pool).aggregate;1757 const aggregate = ctype.info(ctype_pool).aggregate;
1759 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {1758 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(',');
1761 switch (if (has_tag)1760 switch (if (has_tag)
1762 aggregate.fields.at(outer_field_index, ctype_pool).name.index1761 aggregate.fields.at(outer_field_index, ctype_pool).name.index
1763 else1762 else
1764 .payload) {1763 .payload) {
1765 .tag => try dg.renderUndefValue(1764 .tag => try dg.renderUndefValue(
1766 writer,1765 bw,
1767 .fromInterned(loaded_union.enum_tag_ty),1766 .fromInterned(loaded_union.enum_tag_ty),
1768 initializer_type,1767 initializer_type,
1769 ),1768 ),
1770 .payload => {1769 .payload => {
1771 try writer.writeByte('{');1770 try bw.writeByte('{');
1772 for (0..loaded_union.field_types.len) |inner_field_index| {1771 for (0..loaded_union.field_types.len) |inner_field_index| {
1773 const inner_field_ty: Type = .fromInterned(1772 const inner_field_ty: Type = .fromInterned(
1774 loaded_union.field_types.get(ip)[inner_field_index],1773 loaded_union.field_types.get(ip)[inner_field_index],
1775 );1774 );
1776 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;1775 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;
1777 try dg.renderUndefValue(1776 try dg.renderUndefValue(
1778 writer,1777 bw,
1779 inner_field_ty,1778 inner_field_ty,
1780 initializer_type,1779 initializer_type,
1781 );1780 );
1782 break;1781 break;
1783 }1782 }
1784 try writer.writeByte('}');1783 try bw.writeByte('}');
1785 },1784 },
1786 else => unreachable,1785 else => unreachable,
1787 }1786 }
1788 }1787 }
1789 if (has_tag) try writer.writeByte('}');1788 if (has_tag) try bw.writeByte('}');
1790 },1789 },
1791 .@"packed" => return writer.print("{x}", .{1790 .@"packed" => return bw.print("{fx}", .{
1792 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),1791 try dg.fmtIntLiteral(try pt.undefValue(ty), .Other),
1793 }),1792 }),
1794 }1793 }
1795 },1794 },
1796 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {1795 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {
1797 .basic => try dg.renderUndefValue(1796 .basic => try dg.renderUndefValue(
1798 writer,1797 bw,
1799 .fromInterned(error_union_type.error_set_type),1798 .fromInterned(error_union_type.error_set_type),
1800 location,1799 location,
1801 ),1800 ),
1802 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,1801 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1803 .aggregate => |aggregate| {1802 .aggregate => |aggregate| {
1804 if (!location.isInitializer()) {1803 if (!location.isInitializer()) {
1805 try writer.writeByte('(');1804 try bw.writeByte('(');
1806 try dg.renderCType(writer, ctype);1805 try dg.renderCType(bw, ctype);
1807 try writer.writeByte(')');1806 try bw.writeByte(')');
1808 }1807 }
1809 try writer.writeByte('{');1808 try bw.writeByte('{');
1810 for (0..aggregate.fields.len) |field_index| {1809 for (0..aggregate.fields.len) |field_index| {
1811 if (field_index > 0) try writer.writeByte(',');1810 if (field_index > 0) try bw.writeByte(',');
1812 try dg.renderUndefValue(1811 try dg.renderUndefValue(
1813 writer,1812 bw,
1814 .fromInterned(1813 .fromInterned(
1815 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1814 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1816 .@"error" => error_union_type.error_set_type,1815 .@"error" => error_union_type.error_set_type,
...@@ -1821,14 +1820,14 @@ pub const DeclGen = struct {...@@ -1821,14 +1820,14 @@ pub const DeclGen = struct {
1821 initializer_type,1820 initializer_type,
1822 );1821 );
1823 }1822 }
1824 try writer.writeByte('}');1823 try bw.writeByte('}');
1825 },1824 },
1826 },1825 },
1827 .array_type, .vector_type => {1826 .array_type, .vector_type => {
1828 const ai = ty.arrayInfo(zcu);1827 const ai = ty.arrayInfo(zcu);
1829 if (ai.elem_type.eql(.u8, zcu)) {1828 if (ai.elem_type.eql(.u8, zcu)) {
1830 const c_len = ty.arrayLenIncludingSentinel(zcu);1829 const c_len = ty.arrayLenIncludingSentinel(zcu);
1831 var literal: StringLiteral = .init(writer, c_len);1830 var literal: StringLiteral = .init(bw, c_len);
1832 try literal.start();1831 try literal.start();
1833 var index: u64 = 0;1832 var index: u64 = 0;
1834 while (index < c_len) : (index += 1)1833 while (index < c_len) : (index += 1)
...@@ -1836,19 +1835,19 @@ pub const DeclGen = struct {...@@ -1836,19 +1835,19 @@ pub const DeclGen = struct {
1836 return literal.end();1835 return literal.end();
1837 } else {1836 } else {
1838 if (!location.isInitializer()) {1837 if (!location.isInitializer()) {
1839 try writer.writeByte('(');1838 try bw.writeByte('(');
1840 try dg.renderCType(writer, ctype);1839 try dg.renderCType(bw, ctype);
1841 try writer.writeByte(')');1840 try bw.writeByte(')');
1842 }1841 }
18431842
1844 try writer.writeByte('{');1843 try bw.writeByte('{');
1845 const c_len = ty.arrayLenIncludingSentinel(zcu);1844 const c_len = ty.arrayLenIncludingSentinel(zcu);
1846 var index: u64 = 0;1845 var index: u64 = 0;
1847 while (index < c_len) : (index += 1) {1846 while (index < c_len) : (index += 1) {
1848 if (index > 0) try writer.writeAll(", ");1847 if (index > 0) try bw.writeAll(", ");
1849 try dg.renderUndefValue(writer, ty.childType(zcu), initializer_type);1848 try dg.renderUndefValue(bw, ty.childType(zcu), initializer_type);
1850 }1849 }
1851 return writer.writeByte('}');1850 return bw.writeByte('}');
1852 }1851 }
1853 },1852 },
1854 .anyframe_type,1853 .anyframe_type,
...@@ -1881,7 +1880,7 @@ pub const DeclGen = struct {...@@ -1881,7 +1880,7 @@ pub const DeclGen = struct {
18811880
1882 fn renderFunctionSignature(1881 fn renderFunctionSignature(
1883 dg: *DeclGen,1882 dg: *DeclGen,
1884 w: anytype,1883 bw: *std.io.BufferedWriter,
1885 fn_val: Value,1884 fn_val: Value,
1886 fn_align: InternPool.Alignment,1885 fn_align: InternPool.Alignment,
1887 kind: CType.Kind,1886 kind: CType.Kind,
...@@ -1903,8 +1902,8 @@ pub const DeclGen = struct {...@@ -1903,8 +1902,8 @@ pub const DeclGen = struct {
1903 const fn_info = zcu.typeToFunc(fn_ty).?;1902 const fn_info = zcu.typeToFunc(fn_ty).?;
1904 if (fn_info.cc == .naked) {1903 if (fn_info.cc == .naked) {
1905 switch (kind) {1904 switch (kind) {
1906 .forward => try w.writeAll("zig_naked_decl "),1905 .forward => try bw.writeAll("zig_naked_decl "),
1907 .complete => try w.writeAll("zig_naked "),1906 .complete => try bw.writeAll("zig_naked "),
1908 else => unreachable,1907 else => unreachable,
1909 }1908 }
1910 }1909 }
...@@ -1913,33 +1912,33 @@ pub const DeclGen = struct {...@@ -1913,33 +1912,33 @@ pub const DeclGen = struct {
1913 const func_analysis = func.analysisUnordered(ip);1912 const func_analysis = func.analysisUnordered(ip);
19141913
1915 if (func_analysis.branch_hint == .cold)1914 if (func_analysis.branch_hint == .cold)
1916 try w.writeAll("zig_cold ");1915 try bw.writeAll("zig_cold ");
19171916
1918 if (kind == .complete and func_analysis.disable_intrinsics or dg.mod.no_builtin)1917 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 ");
1920 }1919 }
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
1926 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {1925 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 });
1928 trailing = .maybe_space;1927 trailing = .maybe_space;
1929 }1928 }
19301929
1931 try w.print("{}", .{trailing});1930 try bw.print("{f}", .{trailing});
1932 switch (name) {1931 switch (name) {
1933 .nav => |nav| try dg.renderNavName(w, nav),1932 .nav => |nav| try dg.renderNavName(bw, nav),
1934 .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}),1933 .fmt_ctype_pool_string => |fmt| try bw.print("{f }", .{fmt}),
1935 .@"export" => |@"export"| try w.print("{ }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),1934 .@"export" => |@"export"| try bw.print("{f }", .{fmtIdent(@"export".extern_name.toSlice(ip))}),
1936 }1935 }
19371936
1938 try renderTypeSuffix(1937 try renderTypeSuffix(
1939 dg.pass,1938 dg.pass,
1940 &dg.ctype_pool,1939 &dg.ctype_pool,
1941 zcu,1940 zcu,
1942 w,1941 bw,
1943 fn_ctype,1942 fn_ctype,
1944 .suffix,1943 .suffix,
1945 CQualifiers.init(.{ .@"const" = switch (kind) {1944 CQualifiers.init(.{ .@"const" = switch (kind) {
...@@ -1951,7 +1950,7 @@ pub const DeclGen = struct {...@@ -1951,7 +1950,7 @@ pub const DeclGen = struct {
19511950
1952 switch (kind) {1951 switch (kind) {
1953 .forward => {1952 .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});
1955 switch (name) {1954 switch (name) {
1956 .nav, .fmt_ctype_pool_string => {},1955 .nav, .fmt_ctype_pool_string => {},
1957 .@"export" => |@"export"| {1956 .@"export" => |@"export"| {
...@@ -1959,17 +1958,17 @@ pub const DeclGen = struct {...@@ -1959,17 +1958,17 @@ pub const DeclGen = struct {
1959 const is_mangled = isMangledIdent(extern_name, true);1958 const is_mangled = isMangledIdent(extern_name, true);
1960 const is_export = @"export".extern_name != @"export".main_name;1959 const is_export = @"export".extern_name != @"export".main_name;
1961 if (is_mangled and is_export) {1960 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})", .{
1963 fmtIdent(extern_name),1962 fmtIdent(extern_name),
1964 fmtStringLiteral(extern_name, null),1963 fmtStringLiteral(extern_name, null),
1965 fmtStringLiteral(@"export".main_name.toSlice(ip), null),1964 fmtStringLiteral(@"export".main_name.toSlice(ip), null),
1966 });1965 });
1967 } else if (is_mangled) {1966 } else if (is_mangled) {
1968 try w.print(" zig_mangled({ }, {s})", .{1967 try bw.print(" zig_mangled({f }, {fs})", .{
1969 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),1968 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),
1970 });1969 });
1971 } else if (is_export) {1970 } else if (is_export) {
1972 try w.print(" zig_export({s}, {s})", .{1971 try bw.print(" zig_export({fs}, {fs})", .{
1973 fmtStringLiteral(@"export".main_name.toSlice(ip), null),1972 fmtStringLiteral(@"export".main_name.toSlice(ip), null),
1974 fmtStringLiteral(extern_name, null),1973 fmtStringLiteral(extern_name, null),
1975 });1974 });
...@@ -2002,13 +2001,13 @@ pub const DeclGen = struct {...@@ -2002,13 +2001,13 @@ pub const DeclGen = struct {
2002 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |2001 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
2003 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |2002 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
2004 ///2003 ///
2005 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{OutOfMemory}!void {2004 fn renderType(dg: *DeclGen, bw: *std.io.BufferedWriter, t: Type) Error!void {
2006 try dg.renderCType(w, try dg.ctypeFromType(t, .complete));2005 try dg.renderCType(bw, try dg.ctypeFromType(t, .complete));
2007 }2006 }
20082007
2009 fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {2008 fn renderCType(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) Error!void {
2010 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});2009 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
2011 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});2010 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, bw, ctype, .suffix, .{});
2012 }2011 }
20132012
2014 const IntCastContext = union(enum) {2013 const IntCastContext = union(enum) {
...@@ -2021,13 +2020,13 @@ pub const DeclGen = struct {...@@ -2021,13 +2020,13 @@ pub const DeclGen = struct {
2021 value: Value,2020 value: Value,
2022 },2021 },
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 {
2025 switch (self.*) {2024 switch (self.*) {
2026 .c_value => |v| {2025 .c_value => |v| {
2027 try v.f.writeCValue(w, v.value, location);2026 try v.f.writeCValue(bw, v.value, location);
2028 try v.v.elem(v.f, w);2027 try v.v.elem(v.f, bw);
2029 },2028 },
2030 .value => |v| try dg.renderValue(w, v.value, location),2029 .value => |v| try dg.renderValue(bw, v.value, location),
2031 }2030 }
2032 }2031 }
2033 };2032 };
...@@ -2067,7 +2066,7 @@ pub const DeclGen = struct {...@@ -2067,7 +2066,7 @@ pub const DeclGen = struct {
2067 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))2066 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
2068 fn renderIntCast(2067 fn renderIntCast(
2069 dg: *DeclGen,2068 dg: *DeclGen,
2070 w: anytype,2069 bw: *std.io.BufferedWriter,
2071 dest_ty: Type,2070 dest_ty: Type,
2072 context: IntCastContext,2071 context: IntCastContext,
2073 src_ty: Type,2072 src_ty: Type,
...@@ -2092,52 +2091,52 @@ pub const DeclGen = struct {...@@ -2092,52 +2091,52 @@ pub const DeclGen = struct {
2092 dest_int_info.signedness != src_int_info.?.signedness);2091 dest_int_info.signedness != src_int_info.?.signedness);
20932092
2094 if (needs_cast) {2093 if (needs_cast) {
2095 try w.writeByte('(');2094 try bw.writeByte('(');
2096 try dg.renderType(w, dest_ty);2095 try dg.renderType(bw, dest_ty);
2097 try w.writeByte(')');2096 try bw.writeByte(')');
2098 }2097 }
2099 if (src_is_ptr) {2098 if (src_is_ptr) {
2100 try w.writeByte('(');2099 try bw.writeByte('(');
2101 try dg.renderType(w, src_eff_ty);2100 try dg.renderType(bw, src_eff_ty);
2102 try w.writeByte(')');2101 try bw.writeByte(')');
2103 }2102 }
2104 try context.writeValue(dg, w, location);2103 try context.writeValue(dg, bw, location);
2105 } else if (dest_bits <= 64 and src_bits > 64) {2104 } else if (dest_bits <= 64 and src_bits > 64) {
2106 assert(!src_is_ptr);2105 assert(!src_is_ptr);
2107 if (dest_bits < 64) {2106 if (dest_bits < 64) {
2108 try w.writeByte('(');2107 try bw.writeByte('(');
2109 try dg.renderType(w, dest_ty);2108 try dg.renderType(bw, dest_ty);
2110 try w.writeByte(')');2109 try bw.writeByte(')');
2111 }2110 }
2112 try w.writeAll("zig_lo_");2111 try bw.writeAll("zig_lo_");
2113 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);2112 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2114 try w.writeByte('(');2113 try bw.writeByte('(');
2115 try context.writeValue(dg, w, .FunctionArgument);2114 try context.writeValue(dg, bw, .FunctionArgument);
2116 try w.writeByte(')');2115 try bw.writeByte(')');
2117 } else if (dest_bits > 64 and src_bits <= 64) {2116 } else if (dest_bits > 64 and src_bits <= 64) {
2118 try w.writeAll("zig_make_");2117 try bw.writeAll("zig_make_");
2119 try dg.renderTypeForBuiltinFnName(w, dest_ty);2118 try dg.renderTypeForBuiltinFnName(bw, dest_ty);
2120 try w.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral?2119 try bw.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral?
2121 if (src_is_ptr) {2120 if (src_is_ptr) {
2122 try w.writeByte('(');2121 try bw.writeByte('(');
2123 try dg.renderType(w, src_eff_ty);2122 try dg.renderType(bw, src_eff_ty);
2124 try w.writeByte(')');2123 try bw.writeByte(')');
2125 }2124 }
2126 try context.writeValue(dg, w, .FunctionArgument);2125 try context.writeValue(dg, bw, .FunctionArgument);
2127 try w.writeByte(')');2126 try bw.writeByte(')');
2128 } else {2127 } else {
2129 assert(!src_is_ptr);2128 assert(!src_is_ptr);
2130 try w.writeAll("zig_make_");2129 try bw.writeAll("zig_make_");
2131 try dg.renderTypeForBuiltinFnName(w, dest_ty);2130 try dg.renderTypeForBuiltinFnName(bw, dest_ty);
2132 try w.writeAll("(zig_hi_");2131 try bw.writeAll("(zig_hi_");
2133 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);2132 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2134 try w.writeByte('(');2133 try bw.writeByte('(');
2135 try context.writeValue(dg, w, .FunctionArgument);2134 try context.writeValue(dg, bw, .FunctionArgument);
2136 try w.writeAll("), zig_lo_");2135 try bw.writeAll("), zig_lo_");
2137 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);2136 try dg.renderTypeForBuiltinFnName(bw, src_eff_ty);
2138 try w.writeByte('(');2137 try bw.writeByte('(');
2139 try context.writeValue(dg, w, .FunctionArgument);2138 try context.writeValue(dg, bw, .FunctionArgument);
2140 try w.writeAll("))");2139 try bw.writeAll("))");
2141 }2140 }
2142 }2141 }
21432142
...@@ -2151,15 +2150,15 @@ pub const DeclGen = struct {...@@ -2151,15 +2150,15 @@ pub const DeclGen = struct {
2151 ///2150 ///
2152 fn renderTypeAndName(2151 fn renderTypeAndName(
2153 dg: *DeclGen,2152 dg: *DeclGen,
2154 w: anytype,2153 bw: *std.io.BufferedWriter,
2155 ty: Type,2154 ty: Type,
2156 name: CValue,2155 name: CValue,
2157 qualifiers: CQualifiers,2156 qualifiers: CQualifiers,
2158 alignment: Alignment,2157 alignment: Alignment,
2159 kind: CType.Kind,2158 kind: CType.Kind,
2160 ) error{ OutOfMemory, AnalysisFail }!void {2159 ) !void {
2161 try dg.renderCTypeAndName(2160 try dg.renderCTypeAndName(
2162 w,2161 bw,
2163 try dg.ctypeFromType(ty, kind),2162 try dg.ctypeFromType(ty, kind),
2164 name,2163 name,
2165 qualifiers,2164 qualifiers,
...@@ -2172,60 +2171,60 @@ pub const DeclGen = struct {...@@ -2172,60 +2171,60 @@ pub const DeclGen = struct {
21722171
2173 fn renderCTypeAndName(2172 fn renderCTypeAndName(
2174 dg: *DeclGen,2173 dg: *DeclGen,
2175 w: anytype,2174 bw: *std.io.BufferedWriter,
2176 ctype: CType,2175 ctype: CType,
2177 name: CValue,2176 name: CValue,
2178 qualifiers: CQualifiers,2177 qualifiers: CQualifiers,
2179 alignas: CType.AlignAs,2178 alignas: CType.AlignAs,
2180 ) error{ OutOfMemory, AnalysisFail }!void {2179 ) !void {
2181 const zcu = dg.pt.zcu;2180 const zcu = dg.pt.zcu;
2182 switch (alignas.abiOrder()) {2181 switch (alignas.abiOrder()) {
2183 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),2182 .lt => try bw.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
2184 .eq => {},2183 .eq => {},
2185 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),2184 .gt => try bw.print("zig_align({}) ", .{alignas.toByteUnits()}),
2186 }2185 }
21872186
2188 try w.print("{}", .{2187 try bw.print("{f}", .{
2189 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers),2188 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, qualifiers),
2190 });2189 });
2191 try dg.writeName(w, name);2190 try dg.writeName(bw, name);
2192 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});2191 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, bw, ctype, .suffix, .{});
2193 }2192 }
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 {
2196 switch (c_value) {2195 switch (c_value) {
2197 .new_local, .local => |i| try w.print("t{d}", .{i}),2196 .new_local, .local => |i| try bw.print("t{d}", .{i}),
2198 .constant => |uav| try renderUavName(w, uav),2197 .constant => |uav| try renderUavName(bw, uav),
2199 .nav => |nav| try dg.renderNavName(w, nav),2198 .nav => |nav| try dg.renderNavName(bw, nav),
2200 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),2199 .identifier => |ident| try bw.print("{f }", .{fmtIdent(ident)}),
2201 else => unreachable,2200 else => unreachable,
2202 }2201 }
2203 }2202 }
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 {
2206 switch (c_value) {2205 switch (c_value) {
2207 .none, .new_local, .local, .local_ref => unreachable,2206 .none, .new_local, .local, .local_ref => unreachable,
2208 .constant => |uav| try renderUavName(w, uav),2207 .constant => |uav| try renderUavName(bw, uav),
2209 .arg, .arg_array => unreachable,2208 .arg, .arg_array => unreachable,
2210 .field => |i| try w.print("f{d}", .{i}),2209 .field => |i| try bw.print("f{d}", .{i}),
2211 .nav => |nav| try dg.renderNavName(w, nav),2210 .nav => |nav| try dg.renderNavName(bw, nav),
2212 .nav_ref => |nav| {2211 .nav_ref => |nav| {
2213 try w.writeByte('&');2212 try bw.writeByte('&');
2214 try dg.renderNavName(w, nav);2213 try dg.renderNavName(bw, nav);
2215 },2214 },
2216 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),2215 .undef => |ty| try dg.renderUndefValue(bw, ty, .Other),
2217 .identifier => |ident| try w.print("{ }", .{fmtIdent(ident)}),2216 .identifier => |ident| try bw.print("{f }", .{fmtIdent(ident)}),
2218 .payload_identifier => |ident| try w.print("{ }.{ }", .{2217 .payload_identifier => |ident| try bw.print("{f }.{f }", .{
2219 fmtIdent("payload"),2218 fmtIdent("payload"),
2220 fmtIdent(ident),2219 fmtIdent(ident),
2221 }),2220 }),
2222 .ctype_pool_string => |string| try w.print("{ }", .{2221 .ctype_pool_string => |string| try bw.print("{f }", .{
2223 fmtCTypePoolString(string, &dg.ctype_pool),2222 fmtCTypePoolString(string, &dg.ctype_pool),
2224 }),2223 }),
2225 }2224 }
2226 }2225 }
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 {
2229 switch (c_value) {2228 switch (c_value) {
2230 .none,2229 .none,
2231 .new_local,2230 .new_local,
...@@ -2236,16 +2235,16 @@ pub const DeclGen = struct {...@@ -2236,16 +2235,16 @@ pub const DeclGen = struct {
2236 .arg_array,2235 .arg_array,
2237 .ctype_pool_string,2236 .ctype_pool_string,
2238 => unreachable,2237 => unreachable,
2239 .field => |i| try w.print("f{d}", .{i}),2238 .field => |i| try bw.print("f{d}", .{i}),
2240 .nav => |nav| {2239 .nav => |nav| {
2241 try w.writeAll("(*");2240 try bw.writeAll("(*");
2242 try dg.renderNavName(w, nav);2241 try dg.renderNavName(bw, nav);
2243 try w.writeByte(')');2242 try bw.writeByte(')');
2244 },2243 },
2245 .nav_ref => |nav| try dg.renderNavName(w, nav),2244 .nav_ref => |nav| try dg.renderNavName(bw, nav),
2246 .undef => unreachable,2245 .undef => unreachable,
2247 .identifier => |ident| try w.print("(*{ })", .{fmtIdent(ident)}),2246 .identifier => |ident| try bw.print("(*{f })", .{fmtIdent(ident)}),
2248 .payload_identifier => |ident| try w.print("(*{ }.{ })", .{2247 .payload_identifier => |ident| try bw.print("(*{f }.{f })", .{
2249 fmtIdent("payload"),2248 fmtIdent("payload"),
2250 fmtIdent(ident),2249 fmtIdent(ident),
2251 }),2250 }),
...@@ -2254,16 +2253,21 @@ pub const DeclGen = struct {...@@ -2254,16 +2253,21 @@ pub const DeclGen = struct {
22542253
2255 fn writeCValueMember(2254 fn writeCValueMember(
2256 dg: *DeclGen,2255 dg: *DeclGen,
2257 writer: anytype,2256 bw: *std.io.BufferedWriter,
2258 c_value: CValue,2257 c_value: CValue,
2259 member: CValue,2258 member: CValue,
2260 ) error{ OutOfMemory, AnalysisFail }!void {2259 ) Error!void {
2261 try dg.writeCValue(writer, c_value);2260 try dg.writeCValue(bw, c_value);
2262 try writer.writeByte('.');2261 try bw.writeByte('.');
2263 try dg.writeCValue(writer, member);2262 try dg.writeCValue(bw, member);
2264 }2263 }
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 {
2267 switch (c_value) {2271 switch (c_value) {
2268 .none,2272 .none,
2269 .new_local,2273 .new_local,
...@@ -2277,15 +2281,15 @@ pub const DeclGen = struct {...@@ -2277,15 +2281,15 @@ pub const DeclGen = struct {
2277 .ctype_pool_string,2281 .ctype_pool_string,
2278 => unreachable,2282 => unreachable,
2279 .nav, .identifier, .payload_identifier => {2283 .nav, .identifier, .payload_identifier => {
2280 try dg.writeCValue(writer, c_value);2284 try dg.writeCValue(bw, c_value);
2281 try writer.writeAll("->");2285 try bw.writeAll("->");
2282 },2286 },
2283 .nav_ref => {2287 .nav_ref => {
2284 try dg.writeCValueDeref(writer, c_value);2288 try dg.writeCValueDeref(bw, c_value);
2285 try writer.writeByte('.');2289 try bw.writeByte('.');
2286 },2290 },
2287 }2291 }
2288 try dg.writeCValue(writer, member);2292 try dg.writeCValue(bw, member);
2289 }2293 }
22902294
2291 fn renderFwdDecl(2295 fn renderFwdDecl(
...@@ -2301,7 +2305,7 @@ pub const DeclGen = struct {...@@ -2301,7 +2305,7 @@ pub const DeclGen = struct {
2301 const zcu = dg.pt.zcu;2305 const zcu = dg.pt.zcu;
2302 const ip = &zcu.intern_pool;2306 const ip = &zcu.intern_pool;
2303 const nav = ip.getNav(nav_index);2307 const nav = ip.getNav(nav_index);
2304 const fwd = dg.fwdDeclWriter();2308 const fwd = &dg.fwd_decl.buffered_writer;
2305 try fwd.writeAll(switch (flags.linkage) {2309 try fwd.writeAll(switch (flags.linkage) {
2306 .internal => "static ",2310 .internal => "static ",
2307 .strong, .weak, .link_once => "zig_extern ",2311 .strong, .weak, .link_once => "zig_extern ",
...@@ -2327,36 +2331,36 @@ pub const DeclGen = struct {...@@ -2327,36 +2331,36 @@ pub const DeclGen = struct {
2327 try fwd.writeAll(";\n");2331 try fwd.writeAll(";\n");
2328 }2332 }
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 {
2331 const zcu = dg.pt.zcu;2335 const zcu = dg.pt.zcu;
2332 const ip = &zcu.intern_pool;2336 const ip = &zcu.intern_pool;
2333 const nav = ip.getNav(nav_index);2337 const nav = ip.getNav(nav_index);
2334 if (nav.getExtern(ip)) |@"extern"| {2338 if (nav.getExtern(ip)) |@"extern"| {
2335 try writer.print("{ }", .{2339 try bw.print("{f }", .{
2336 fmtIdent(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),2340 fmtIdent(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
2337 });2341 });
2338 } else {2342 } else {
2339 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),2343 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2340 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.2344 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2341 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);2345 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2342 try writer.print("{}__{d}", .{2346 try bw.print("{f}__{d}", .{
2343 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),2347 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
2344 @intFromEnum(nav_index),2348 @intFromEnum(nav_index),
2345 });2349 });
2346 }2350 }
2347 }2351 }
23482352
2349 fn renderUavName(writer: anytype, uav: Value) !void {2353 fn renderUavName(bw: *std.io.BufferedWriter, uav: Value) !void {
2350 try writer.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});2354 try bw.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
2351 }2355 }
23522356
2353 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {2357 fn renderTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ty: Type) !void {
2354 try dg.renderCTypeForBuiltinFnName(writer, try dg.ctypeFromType(ty, .complete));2358 try dg.renderCTypeForBuiltinFnName(bw, try dg.ctypeFromType(ty, .complete));
2355 }2359 }
23562360
2357 fn renderCTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ctype: CType) !void {2361 fn renderCTypeForBuiltinFnName(dg: *DeclGen, bw: *std.io.BufferedWriter, ctype: CType) !void {
2358 switch (ctype.info(&dg.ctype_pool)) {2362 switch (ctype.info(&dg.ctype_pool)) {
2359 else => |ctype_info| try writer.print("{c}{d}", .{2363 else => |ctype_info| try bw.print("{c}{d}", .{
2360 if (ctype.isBool())2364 if (ctype.isBool())
2361 signAbbrev(.unsigned)2365 signAbbrev(.unsigned)
2362 else if (ctype.isInteger())2366 else if (ctype.isInteger())
...@@ -2369,11 +2373,11 @@ pub const DeclGen = struct {...@@ -2369,11 +2373,11 @@ pub const DeclGen = struct {
2369 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),2373 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),
2370 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,2374 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,
2371 }),2375 }),
2372 .array => try writer.writeAll("big"),2376 .array => try bw.writeAll("big"),
2373 }2377 }
2374 }2378 }
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 {
2377 const ctype = try dg.ctypeFromType(ty, .complete);2381 const ctype = try dg.ctypeFromType(ty, .complete);
2378 const is_big = ctype.info(&dg.ctype_pool) == .array;2382 const is_big = ctype.info(&dg.ctype_pool) == .array;
2379 switch (info) {2383 switch (info) {
...@@ -2388,8 +2392,8 @@ pub const DeclGen = struct {...@@ -2388,8 +2392,8 @@ pub const DeclGen = struct {
2388 .bits = @intCast(ty.bitSize(zcu)),2392 .bits = @intCast(ty.bitSize(zcu)),
2389 };2393 };
23902394
2391 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});2395 if (is_big) try bw.print(", {}", .{int_info.signedness == .signed});
2392 try writer.print(", {}", .{try dg.fmtIntLiteral(2396 try bw.print(", {f}", .{try dg.fmtIntLiteral(
2393 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),2397 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),
2394 .FunctionArgument,2398 .FunctionArgument,
2395 )});2399 )});
...@@ -2422,35 +2426,32 @@ const RenderCTypeTrailing = enum {...@@ -2422,35 +2426,32 @@ const RenderCTypeTrailing = enum {
24222426
2423 pub fn format(2427 pub fn format(
2424 self: @This(),2428 self: @This(),
2429 bw: *std.io.BufferedWriter,
2425 comptime fmt: []const u8,2430 comptime fmt: []const u8,
2426 _: std.fmt.FormatOptions,2431 ) std.io.Writer.Error!void {
2427 w: anytype,2432 if (fmt.len != 0) @compileError("invalid format string '" ++
2428 ) @TypeOf(w).Error!void {2433 fmt ++ "' for type '" ++ @typeName(@This()) ++ "'");
2429 if (fmt.len != 0)
2430 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++
2431 @typeName(@This()) ++ "'");
2432 comptime assert(fmt.len == 0);
2433 switch (self) {2434 switch (self) {
2434 .no_space => {},2435 .no_space => {},
2435 .maybe_space => try w.writeByte(' '),2436 .maybe_space => try bw.writeByte(' '),
2436 }2437 }
2437 }2438 }
2438};2439};
2439fn renderAlignedTypeName(w: anytype, ctype: CType) !void {2440fn renderAlignedTypeName(bw: *std.io.BufferedWriter, ctype: CType) !void {
2440 try w.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});2441 try bw.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
2441}2442}
2442fn renderFwdDeclTypeName(2443fn renderFwdDeclTypeName(
2443 zcu: *Zcu,2444 zcu: *Zcu,
2444 w: anytype,2445 bw: *std.io.BufferedWriter,
2445 ctype: CType,2446 ctype: CType,
2446 fwd_decl: CType.Info.FwdDecl,2447 fwd_decl: CType.Info.FwdDecl,
2447 attributes: []const u8,2448 attributes: []const u8,
2448) !void {2449) !void {
2449 const ip = &zcu.intern_pool;2450 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 });
2451 switch (fwd_decl.name) {2452 switch (fwd_decl.name) {
2452 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),2453 .anon => try bw.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2453 .index => |index| try w.print("{}__{d}", .{2454 .index => |index| try bw.print("{f}__{d}", .{
2454 fmtIdent(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),2455 fmtIdent(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),
2455 @intFromEnum(index),2456 @intFromEnum(index),
2456 }),2457 }),
...@@ -2460,21 +2461,21 @@ fn renderTypePrefix(...@@ -2460,21 +2461,21 @@ fn renderTypePrefix(
2460 pass: DeclGen.Pass,2461 pass: DeclGen.Pass,
2461 ctype_pool: *const CType.Pool,2462 ctype_pool: *const CType.Pool,
2462 zcu: *Zcu,2463 zcu: *Zcu,
2463 w: anytype,2464 bw: *std.io.BufferedWriter,
2464 ctype: CType,2465 ctype: CType,
2465 parent_fix: CTypeFix,2466 parent_fix: CTypeFix,
2466 qualifiers: CQualifiers,2467 qualifiers: CQualifiers,
2467) @TypeOf(w).Error!RenderCTypeTrailing {2468) std.io.Writer.Error!RenderCTypeTrailing {
2468 var trailing = RenderCTypeTrailing.maybe_space;2469 var trailing = RenderCTypeTrailing.maybe_space;
2469 switch (ctype.info(ctype_pool)) {2470 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
2472 .pointer => |pointer_info| {2473 .pointer => |pointer_info| {
2473 try w.print("{}*", .{try renderTypePrefix(2474 try bw.print("{f}*", .{try renderTypePrefix(
2474 pass,2475 pass,
2475 ctype_pool,2476 ctype_pool,
2476 zcu,2477 zcu,
2477 w,2478 bw,
2478 pointer_info.elem_ctype,2479 pointer_info.elem_ctype,
2479 .prefix,2480 .prefix,
2480 CQualifiers.init(.{2481 CQualifiers.init(.{
...@@ -2486,13 +2487,13 @@ fn renderTypePrefix(...@@ -2486,13 +2487,13 @@ fn renderTypePrefix(
2486 },2487 },
24872488
2488 .aligned => switch (pass) {2489 .aligned => switch (pass) {
2489 .nav => |nav| try w.print("nav__{d}_{d}", .{2490 .nav => |nav| try bw.print("nav__{d}_{d}", .{
2490 @intFromEnum(nav), @intFromEnum(ctype.index),2491 @intFromEnum(nav), @intFromEnum(ctype.index),
2491 }),2492 }),
2492 .uav => |uav| try w.print("uav__{d}_{d}", .{2493 .uav => |uav| try bw.print("uav__{d}_{d}", .{
2493 @intFromEnum(uav), @intFromEnum(ctype.index),2494 @intFromEnum(uav), @intFromEnum(ctype.index),
2494 }),2495 }),
2495 .flush => try renderAlignedTypeName(w, ctype),2496 .flush => try renderAlignedTypeName(bw, ctype),
2496 },2497 },
24972498
2498 .array, .vector => |sequence_info| {2499 .array, .vector => |sequence_info| {
...@@ -2500,14 +2501,14 @@ fn renderTypePrefix(...@@ -2500,14 +2501,14 @@ fn renderTypePrefix(
2500 pass,2501 pass,
2501 ctype_pool,2502 ctype_pool,
2502 zcu,2503 zcu,
2503 w,2504 bw,
2504 sequence_info.elem_ctype,2505 sequence_info.elem_ctype,
2505 .suffix,2506 .suffix,
2506 qualifiers,2507 qualifiers,
2507 );2508 );
2508 switch (parent_fix) {2509 switch (parent_fix) {
2509 .prefix => {2510 .prefix => {
2510 try w.print("{}(", .{child_trailing});2511 try bw.print("{f}(", .{child_trailing});
2511 return .no_space;2512 return .no_space;
2512 },2513 },
2513 .suffix => return child_trailing,2514 .suffix => return child_trailing,
...@@ -2516,31 +2517,31 @@ fn renderTypePrefix(...@@ -2516,31 +2517,31 @@ fn renderTypePrefix(
25162517
2517 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {2518 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2518 .anon => switch (pass) {2519 .anon => switch (pass) {
2519 .nav => |nav| try w.print("nav__{d}_{d}", .{2520 .nav => |nav| try bw.print("nav__{d}_{d}", .{
2520 @intFromEnum(nav), @intFromEnum(ctype.index),2521 @intFromEnum(nav), @intFromEnum(ctype.index),
2521 }),2522 }),
2522 .uav => |uav| try w.print("uav__{d}_{d}", .{2523 .uav => |uav| try bw.print("uav__{d}_{d}", .{
2523 @intFromEnum(uav), @intFromEnum(ctype.index),2524 @intFromEnum(uav), @intFromEnum(ctype.index),
2524 }),2525 }),
2525 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),2526 .flush => try renderFwdDeclTypeName(zcu, bw, ctype, fwd_decl_info, ""),
2526 },2527 },
2527 .index => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),2528 .index => try renderFwdDeclTypeName(zcu, bw, ctype, fwd_decl_info, ""),
2528 },2529 },
25292530
2530 .aggregate => |aggregate_info| switch (aggregate_info.name) {2531 .aggregate => |aggregate_info| switch (aggregate_info.name) {
2531 .anon => {2532 .anon => {
2532 try w.print("{s} {s}", .{2533 try bw.print("{s} {s}", .{
2533 @tagName(aggregate_info.tag),2534 @tagName(aggregate_info.tag),
2534 if (aggregate_info.@"packed") "zig_packed(" else "",2535 if (aggregate_info.@"packed") "zig_packed(" else "",
2535 });2536 });
2536 try renderFields(zcu, w, ctype_pool, aggregate_info, 1);2537 try renderFields(zcu, bw, ctype_pool, aggregate_info, 1);
2537 if (aggregate_info.@"packed") try w.writeByte(')');2538 if (aggregate_info.@"packed") try bw.writeByte(')');
2538 },2539 },
2539 .fwd_decl => |fwd_decl| return renderTypePrefix(2540 .fwd_decl => |fwd_decl| return renderTypePrefix(
2540 pass,2541 pass,
2541 ctype_pool,2542 ctype_pool,
2542 zcu,2543 zcu,
2543 w,2544 bw,
2544 fwd_decl,2545 fwd_decl,
2545 parent_fix,2546 parent_fix,
2546 qualifiers,2547 qualifiers,
...@@ -2552,14 +2553,14 @@ fn renderTypePrefix(...@@ -2552,14 +2553,14 @@ fn renderTypePrefix(
2552 pass,2553 pass,
2553 ctype_pool,2554 ctype_pool,
2554 zcu,2555 zcu,
2555 w,2556 bw,
2556 function_info.return_ctype,2557 function_info.return_ctype,
2557 .suffix,2558 .suffix,
2558 .{},2559 .{},
2559 );2560 );
2560 switch (parent_fix) {2561 switch (parent_fix) {
2561 .prefix => {2562 .prefix => {
2562 try w.print("{}(", .{child_trailing});2563 try bw.print("{f}(", .{child_trailing});
2563 return .no_space;2564 return .no_space;
2564 },2565 },
2565 .suffix => return child_trailing,2566 .suffix => return child_trailing,
...@@ -2568,7 +2569,7 @@ fn renderTypePrefix(...@@ -2568,7 +2569,7 @@ fn renderTypePrefix(
2568 }2569 }
2569 var qualifier_it = qualifiers.iterator();2570 var qualifier_it = qualifiers.iterator();
2570 while (qualifier_it.next()) |qualifier| {2571 while (qualifier_it.next()) |qualifier| {
2571 try w.print("{}{s}", .{ trailing, @tagName(qualifier) });2572 try bw.print("{f}{s}", .{ trailing, @tagName(qualifier) });
2572 trailing = .maybe_space;2573 trailing = .maybe_space;
2573 }2574 }
2574 return trailing;2575 return trailing;
...@@ -2577,105 +2578,105 @@ fn renderTypeSuffix(...@@ -2577,105 +2578,105 @@ fn renderTypeSuffix(
2577 pass: DeclGen.Pass,2578 pass: DeclGen.Pass,
2578 ctype_pool: *const CType.Pool,2579 ctype_pool: *const CType.Pool,
2579 zcu: *Zcu,2580 zcu: *Zcu,
2580 w: anytype,2581 bw: *std.io.BufferedWriter,
2581 ctype: CType,2582 ctype: CType,
2582 parent_fix: CTypeFix,2583 parent_fix: CTypeFix,
2583 qualifiers: CQualifiers,2584 qualifiers: CQualifiers,
2584) @TypeOf(w).Error!void {2585) std.io.Writer.Error!void {
2585 switch (ctype.info(ctype_pool)) {2586 switch (ctype.info(ctype_pool)) {
2586 .basic, .aligned, .fwd_decl, .aggregate => {},2587 .basic, .aligned, .fwd_decl, .aggregate => {},
2587 .pointer => |pointer_info| try renderTypeSuffix(2588 .pointer => |pointer_info| try renderTypeSuffix(
2588 pass,2589 pass,
2589 ctype_pool,2590 ctype_pool,
2590 zcu,2591 zcu,
2591 w,2592 bw,
2592 pointer_info.elem_ctype,2593 pointer_info.elem_ctype,
2593 .prefix,2594 .prefix,
2594 .{},2595 .{},
2595 ),2596 ),
2596 .array, .vector => |sequence_info| {2597 .array, .vector => |sequence_info| {
2597 switch (parent_fix) {2598 switch (parent_fix) {
2598 .prefix => try w.writeByte(')'),2599 .prefix => try bw.writeByte(')'),
2599 .suffix => {},2600 .suffix => {},
2600 }2601 }
26012602
2602 try w.print("[{}]", .{sequence_info.len});2603 try bw.print("[{}]", .{sequence_info.len});
2603 try renderTypeSuffix(pass, ctype_pool, zcu, w, sequence_info.elem_ctype, .suffix, .{});2604 try renderTypeSuffix(pass, ctype_pool, zcu, bw, sequence_info.elem_ctype, .suffix, .{});
2604 },2605 },
2605 .function => |function_info| {2606 .function => |function_info| {
2606 switch (parent_fix) {2607 switch (parent_fix) {
2607 .prefix => try w.writeByte(')'),2608 .prefix => try bw.writeByte(')'),
2608 .suffix => {},2609 .suffix => {},
2609 }2610 }
26102611
2611 try w.writeByte('(');2612 try bw.writeByte('(');
2612 var need_comma = false;2613 var need_comma = false;
2613 for (0..function_info.param_ctypes.len) |param_index| {2614 for (0..function_info.param_ctypes.len) |param_index| {
2614 const param_type = function_info.param_ctypes.at(param_index, ctype_pool);2615 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(", ");
2616 need_comma = true;2617 need_comma = true;
2617 const trailing =2618 const trailing =
2618 try renderTypePrefix(pass, ctype_pool, zcu, w, param_type, .suffix, qualifiers);2619 try renderTypePrefix(pass, ctype_pool, zcu, bw, param_type, .suffix, qualifiers);
2619 if (qualifiers.contains(.@"const")) try w.print("{}a{d}", .{ trailing, param_index });2620 if (qualifiers.contains(.@"const")) try bw.print("{f}a{d}", .{ trailing, param_index });
2620 try renderTypeSuffix(pass, ctype_pool, zcu, w, param_type, .suffix, .{});2621 try renderTypeSuffix(pass, ctype_pool, zcu, bw, param_type, .suffix, .{});
2621 }2622 }
2622 if (function_info.varargs) {2623 if (function_info.varargs) {
2623 if (need_comma) try w.writeAll(", ");2624 if (need_comma) try bw.writeAll(", ");
2624 need_comma = true;2625 need_comma = true;
2625 try w.writeAll("...");2626 try bw.writeAll("...");
2626 }2627 }
2627 if (!need_comma) try w.writeAll("void");2628 if (!need_comma) try bw.writeAll("void");
2628 try w.writeByte(')');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, .{});
2631 },2632 },
2632 }2633 }
2633}2634}
2634fn renderFields(2635fn renderFields(
2635 zcu: *Zcu,2636 zcu: *Zcu,
2636 writer: anytype,2637 bw: *std.io.BufferedWriter,
2637 ctype_pool: *const CType.Pool,2638 ctype_pool: *const CType.Pool,
2638 aggregate_info: CType.Info.Aggregate,2639 aggregate_info: CType.Info.Aggregate,
2639 indent: usize,2640 indent: usize,
2640) !void {2641) !void {
2641 try writer.writeAll("{\n");2642 try bw.writeAll("{\n");
2642 for (0..aggregate_info.fields.len) |field_index| {2643 for (0..aggregate_info.fields.len) |field_index| {
2643 const field_info = aggregate_info.fields.at(field_index, ctype_pool);2644 const field_info = aggregate_info.fields.at(field_index, ctype_pool);
2644 try writer.writeByteNTimes(' ', indent + 1);2645 try bw.splatByteAll(' ', indent + 1);
2645 switch (field_info.alignas.abiOrder()) {2646 switch (field_info.alignas.abiOrder()) {
2646 .lt => {2647 .lt => {
2647 std.debug.assert(aggregate_info.@"packed");2648 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({}) ", .{
2649 field_info.alignas.toByteUnits(),2650 field_info.alignas.toByteUnits(),
2650 });2651 });
2651 },2652 },
2652 .eq => if (aggregate_info.@"packed" and field_info.alignas.@"align" != .@"1")2653 .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()}),
2654 .gt => {2655 .gt => {
2655 std.debug.assert(field_info.alignas.@"align" != .@"1");2656 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()});
2657 },2658 },
2658 }2659 }
2659 const trailing = try renderTypePrefix(2660 const trailing = try renderTypePrefix(
2660 .flush,2661 .flush,
2661 ctype_pool,2662 ctype_pool,
2662 zcu,2663 zcu,
2663 writer,2664 bw,
2664 field_info.ctype,2665 field_info.ctype,
2665 .suffix,2666 .suffix,
2666 .{},2667 .{},
2667 );2668 );
2668 try writer.print("{}{ }", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool) });2669 try bw.print("{f}{f }", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool) });
2669 try renderTypeSuffix(.flush, ctype_pool, zcu, writer, field_info.ctype, .suffix, .{});2670 try renderTypeSuffix(.flush, ctype_pool, zcu, bw, field_info.ctype, .suffix, .{});
2670 try writer.writeAll(";\n");2671 try bw.writeAll(";\n");
2671 }2672 }
2672 try writer.writeByteNTimes(' ', indent);2673 try bw.splatByteAll(' ', indent);
2673 try writer.writeByte('}');2674 try bw.writeByte('}');
2674}2675}
26752676
2676pub fn genTypeDecl(2677pub fn genTypeDecl(
2677 zcu: *Zcu,2678 zcu: *Zcu,
2678 writer: anytype,2679 bw: *std.io.BufferedWriter,
2679 global_ctype_pool: *const CType.Pool,2680 global_ctype_pool: *const CType.Pool,
2680 global_ctype: CType,2681 global_ctype: CType,
2681 pass: DeclGen.Pass,2682 pass: DeclGen.Pass,
...@@ -2688,27 +2689,27 @@ pub fn genTypeDecl(...@@ -2688,27 +2689,27 @@ pub fn genTypeDecl(
2688 .aligned => |aligned_info| {2689 .aligned => |aligned_info| {
2689 if (!found_existing) {2690 if (!found_existing) {
2690 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));2691 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));
2691 try writer.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});2692 try bw.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2692 try writer.print("{}", .{try renderTypePrefix(2693 try bw.print("{f}", .{try renderTypePrefix(
2693 .flush,2694 .flush,
2694 global_ctype_pool,2695 global_ctype_pool,
2695 zcu,2696 zcu,
2696 writer,2697 bw,
2697 aligned_info.ctype,2698 aligned_info.ctype,
2698 .suffix,2699 .suffix,
2699 .{},2700 .{},
2700 )});2701 )});
2701 try renderAlignedTypeName(writer, global_ctype);2702 try renderAlignedTypeName(bw, global_ctype);
2702 try renderTypeSuffix(.flush, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{});2703 try renderTypeSuffix(.flush, global_ctype_pool, zcu, bw, aligned_info.ctype, .suffix, .{});
2703 try writer.writeAll(";\n");2704 try bw.writeAll(";\n");
2704 }2705 }
2705 switch (pass) {2706 switch (pass) {
2706 .nav, .uav => {2707 .nav, .uav => {
2707 try writer.writeAll("typedef ");2708 try bw.writeAll("typedef ");
2708 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2709 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2709 try writer.writeByte(' ');2710 try bw.writeByte(' ');
2710 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});2711 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, bw, decl_ctype, .suffix, .{});
2711 try writer.writeAll(";\n");2712 try bw.writeAll(";\n");
2712 },2713 },
2713 .flush => {},2714 .flush => {},
2714 }2715 }
...@@ -2716,24 +2717,24 @@ pub fn genTypeDecl(...@@ -2716,24 +2717,24 @@ pub fn genTypeDecl(
2716 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {2717 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2717 .anon => switch (pass) {2718 .anon => switch (pass) {
2718 .nav, .uav => {2719 .nav, .uav => {
2719 try writer.writeAll("typedef ");2720 try bw.writeAll("typedef ");
2720 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2721 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2721 try writer.writeByte(' ');2722 try bw.writeByte(' ');
2722 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});2723 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, bw, decl_ctype, .suffix, .{});
2723 try writer.writeAll(";\n");2724 try bw.writeAll(";\n");
2724 },2725 },
2725 .flush => {},2726 .flush => {},
2726 },2727 },
2727 .index => |index| if (!found_existing) {2728 .index => |index| if (!found_existing) {
2728 const ip = &zcu.intern_pool;2729 const ip = &zcu.intern_pool;
2729 const ty: Type = .fromInterned(index);2730 const ty: Type = .fromInterned(index);
2730 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2731 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, bw, global_ctype, .suffix, .{});
2731 try writer.writeByte(';');2732 try bw.writeByte(';');
2732 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);2733 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} */", .{
2734 ty.containerTypeName(ip).fmt(ip),2735 ty.containerTypeName(ip).fmt(ip),
2735 });2736 });
2736 try writer.writeByte('\n');2737 try bw.writeByte('\n');
2737 },2738 },
2738 },2739 },
2739 .aggregate => |aggregate_info| switch (aggregate_info.name) {2740 .aggregate => |aggregate_info| switch (aggregate_info.name) {
...@@ -2741,38 +2742,39 @@ pub fn genTypeDecl(...@@ -2741,38 +2742,39 @@ pub fn genTypeDecl(
2741 .fwd_decl => |fwd_decl| if (!found_existing) {2742 .fwd_decl => |fwd_decl| if (!found_existing) {
2742 try renderFwdDeclTypeName(2743 try renderFwdDeclTypeName(
2743 zcu,2744 zcu,
2744 writer,2745 bw,
2745 fwd_decl,2746 fwd_decl,
2746 fwd_decl.info(global_ctype_pool).fwd_decl,2747 fwd_decl.info(global_ctype_pool).fwd_decl,
2747 if (aggregate_info.@"packed") "zig_packed(" else "",2748 if (aggregate_info.@"packed") "zig_packed(" else "",
2748 );2749 );
2749 try writer.writeByte(' ');2750 try bw.writeByte(' ');
2750 try renderFields(zcu, writer, global_ctype_pool, aggregate_info, 0);2751 try renderFields(zcu, bw, global_ctype_pool, aggregate_info, 0);
2751 if (aggregate_info.@"packed") try writer.writeByte(')');2752 if (aggregate_info.@"packed") try bw.writeByte(')');
2752 try writer.writeAll(";\n");2753 try bw.writeAll(";\n");
2753 },2754 },
2754 },2755 },
2755 }2756 }
2756}2757}
27572758
2758pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {2759pub fn genGlobalAsm(zcu: *Zcu, bw: *std.io.BufferedWriter) !void {
2759 for (zcu.global_assembly.values()) |asm_source| {2760 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)});
2761 }2762 }
2762}2763}
27632764
2764pub fn genErrDecls(o: *Object) !void {2765pub fn genErrDecls(o: *Object) Error!void {
2765 const pt = o.dg.pt;2766 const pt = o.dg.pt;
2766 const zcu = pt.zcu;2767 const zcu = pt.zcu;
2767 const ip = &zcu.intern_pool;2768 const ip = &zcu.intern_pool;
2768 const writer = o.writer();2769 const bw = &o.code.buffered_writer;
27692770
2770 var max_name_len: usize = 0;2771 var max_name_len: usize = 0;
2771 // do not generate an invalid empty enum when the global error set is empty2772 // do not generate an invalid empty enum when the global error set is empty
2772 const names = ip.global_error_set.getNamesFromMainThread();2773 const names = ip.global_error_set.getNamesFromMainThread();
2773 if (names.len > 0) {2774 if (names.len > 0) {
2774 try writer.writeAll("enum {\n");2775 try bw.writeAll("enum {");
2775 o.indent_writer.pushIndent();2776 o.indent();
2777 try o.newline();
2776 for (names, 1..) |name_nts, value| {2778 for (names, 1..) |name_nts, value| {
2777 const name = name_nts.toSlice(ip);2779 const name = name_nts.toSlice(ip);
2778 max_name_len = @max(name.len, max_name_len);2780 max_name_len = @max(name.len, max_name_len);
...@@ -2780,11 +2782,13 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2780,11 +2782,13 @@ pub fn genErrDecls(o: *Object) !void {
2780 .ty = .anyerror_type,2782 .ty = .anyerror_type,
2781 .name = name_nts,2783 .name = name_nts,
2782 } });2784 } });
2783 try o.dg.renderValue(writer, Value.fromInterned(err_val), .Other);2785 try o.dg.renderValue(bw, Value.fromInterned(err_val), .Other);
2784 try writer.print(" = {d}u,\n", .{value});2786 try bw.print(" = {d}u,", .{value});
2787 try o.newline();
2785 }2788 }
2786 o.indent_writer.popIndent();2789 o.outdent();
2787 try writer.writeAll("};\n");2790 try bw.writeAll("};");
2791 try o.newline();
2788 }2792 }
2789 const array_identifier = "zig_errorName";2793 const array_identifier = "zig_errorName";
2790 const name_prefix = array_identifier ++ "_";2794 const name_prefix = array_identifier ++ "_";
...@@ -2807,18 +2811,19 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2807,18 +2811,19 @@ pub fn genErrDecls(o: *Object) !void {
2807 .storage = .{ .bytes = name.toString() },2811 .storage = .{ .bytes = name.toString() },
2808 } });2812 } });
28092813
2810 try writer.writeAll("static ");2814 try bw.writeAll("static ");
2811 try o.dg.renderTypeAndName(2815 try o.dg.renderTypeAndName(
2812 writer,2816 bw,
2813 name_ty,2817 name_ty,
2814 .{ .identifier = identifier },2818 .{ .identifier = identifier },
2815 Const,2819 Const,
2816 .none,2820 .none,
2817 .complete,2821 .complete,
2818 );2822 );
2819 try writer.writeAll(" = ");2823 try bw.writeAll(" = ");
2820 try o.dg.renderValue(writer, Value.fromInterned(name_val), .StaticInitializer);2824 try o.dg.renderValue(bw, Value.fromInterned(name_val), .StaticInitializer);
2821 try writer.writeAll(";\n");2825 try bw.writeByte(';');
2826 try o.newline();
2822 }2827 }
28232828
2824 const name_array_ty = try pt.arrayType(.{2829 const name_array_ty = try pt.arrayType(.{
...@@ -2826,33 +2831,34 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2826,33 +2831,34 @@ pub fn genErrDecls(o: *Object) !void {
2826 .child = .slice_const_u8_sentinel_0_type,2831 .child = .slice_const_u8_sentinel_0_type,
2827 });2832 });
28282833
2829 try writer.writeAll("static ");2834 try bw.writeAll("static ");
2830 try o.dg.renderTypeAndName(2835 try o.dg.renderTypeAndName(
2831 writer,2836 bw,
2832 name_array_ty,2837 name_array_ty,
2833 .{ .identifier = array_identifier },2838 .{ .identifier = array_identifier },
2834 Const,2839 Const,
2835 .none,2840 .none,
2836 .complete,2841 .complete,
2837 );2842 );
2838 try writer.writeAll(" = {");2843 try bw.writeAll(" = {");
2839 for (names, 1..) |name_nts, val| {2844 for (names, 1..) |name_nts, val| {
2840 const name = name_nts.toSlice(ip);2845 const name = name_nts.toSlice(ip);
2841 if (val > 1) try writer.writeAll(", ");2846 if (val > 1) try bw.writeAll(", ");
2842 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{2847 try bw.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{
2843 fmtIdent(name),2848 fmtIdent(name),
2844 try o.dg.fmtIntLiteral(try pt.intValue(.usize, name.len), .StaticInitializer),2849 try o.dg.fmtIntLiteral(try pt.intValue(.usize, name.len), .StaticInitializer),
2845 });2850 });
2846 }2851 }
2847 try writer.writeAll("};\n");2852 try bw.writeAll("};");
2853 try o.newline();
2848}2854}
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 {
2851 const pt = o.dg.pt;2857 const pt = o.dg.pt;
2852 const zcu = pt.zcu;2858 const zcu = pt.zcu;
2853 const ip = &zcu.intern_pool;2859 const ip = &zcu.intern_pool;
2854 const ctype_pool = &o.dg.ctype_pool;2860 const ctype_pool = &o.dg.ctype_pool;
2855 const w = o.writer();2861 const bw = &o.code.buffered_writer;
2856 const key = lazy_fn.key_ptr.*;2862 const key = lazy_fn.key_ptr.*;
2857 const val = lazy_fn.value_ptr;2863 const val = lazy_fn.value_ptr;
2858 switch (key) {2864 switch (key) {
...@@ -2860,11 +2866,16 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn...@@ -2860,11 +2866,16 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2860 const enum_ty: Type = .fromInterned(enum_ty_ip);2866 const enum_ty: Type = .fromInterned(enum_ty_ip);
2861 const name_slice_ty: Type = .slice_const_u8_sentinel_0;2867 const name_slice_ty: Type = .slice_const_u8_sentinel_0;
28622868
2863 try w.writeAll("static ");2869 try bw.writeAll("static ");
2864 try o.dg.renderType(w, name_slice_ty);2870 try o.dg.renderType(bw, name_slice_ty);
2865 try w.print(" {}(", .{val.fn_name.fmt(lazy_ctype_pool)});2871 try bw.print(" {f}(", .{val.fn_name.fmt(lazy_ctype_pool)});
2866 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);2872 try o.dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
2867 try w.writeAll(") {\n switch (tag) {\n");2873 try bw.writeAll(") {");
2874 o.indent();
2875 try o.newline();
2876 try bw.writeAll("switch (tag) {");
2877 o.indent();
2878 try o.newline();
2868 const tag_names = enum_ty.enumFields(zcu);2879 const tag_names = enum_ty.enumFields(zcu);
2869 for (0..tag_names.len) |tag_index| {2880 for (0..tag_names.len) |tag_index| {
2870 const tag_name = tag_names.get(ip)[tag_index];2881 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...@@ -2881,26 +2892,35 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2881 .storage = .{ .bytes = tag_name.toString() },2892 .storage = .{ .bytes = tag_name.toString() },
2882 } });2893 } });
28832894
2884 try w.print(" case {}: {{\n static ", .{2895 try bw.print("case {f}: {{", .{
2885 try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other),2896 try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other),
2886 });2897 });
2887 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);2898 try o.newline();
2888 try w.writeAll(" = ");2899 try bw.writeAll("static ");
2889 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);2900 try o.dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
2890 try w.writeAll(";\n return (");2901 try bw.writeAll(" = ");
2891 try o.dg.renderType(w, name_slice_ty);2902 try o.dg.renderValue(bw, Value.fromInterned(name_val), .StaticInitializer);
2892 try w.print("){{{}, {}}};\n", .{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}}};", .{
2893 fmtIdent("name"),2908 fmtIdent("name"),
2894 try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other),2909 try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other),
2895 });2910 });
2911 try o.newline();
28962912
2897 try w.writeAll(" }\n");2913 try bw.writeByte('}');
2914 try o.newline();
2898 }2915 }
2899 try w.writeAll(" }\n while (");2916 try bw.writeByte('}');
2900 try o.dg.renderValue(w, Value.true, .Other);2917 try o.newline();
2901 try w.writeAll(") ");2918 try bw.writeAll("while (");
2902 _ = try airBreakpoint(w);2919 try o.dg.renderValue(bw, Value.true, .Other);
2903 try w.writeAll("}\n");2920 try bw.writeAll(") ");
2921 _ = try airBreakpoint(o, bw);
2922 try bw.writeByte('}');
2923 try o.newline();
2904 },2924 },
2905 .never_tail, .never_inline => |fn_nav_index| {2925 .never_tail, .never_inline => |fn_nav_index| {
2906 const fn_val = zcu.navValue(fn_nav_index);2926 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...@@ -2908,25 +2928,30 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn
2908 const fn_info = fn_ctype.info(ctype_pool).function;2928 const fn_info = fn_ctype.info(ctype_pool).function;
2909 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool);2929 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;
2912 try fwd.print("static zig_{s} ", .{@tagName(key)});2932 try fwd.print("static zig_{s} ", .{@tagName(key)});
2913 try o.dg.renderFunctionSignature(fwd, fn_val, ip.getNav(fn_nav_index).getAlignment(), .forward, .{2933 try o.dg.renderFunctionSignature(fwd, fn_val, ip.getNav(fn_nav_index).getAlignment(), .forward, .{
2914 .fmt_ctype_pool_string = fn_name,2934 .fmt_ctype_pool_string = fn_name,
2915 });2935 });
2916 try fwd.writeAll(";\n");2936 try fwd.writeAll(";\n");
29172937
2918 try w.print("zig_{s} ", .{@tagName(key)});2938 try bw.print("zig_{s} ", .{@tagName(key)});
2919 try o.dg.renderFunctionSignature(w, fn_val, .none, .complete, .{2939 try o.dg.renderFunctionSignature(bw, fn_val, .none, .complete, .{
2920 .fmt_ctype_pool_string = fn_name,2940 .fmt_ctype_pool_string = fn_name,
2921 });2941 });
2922 try w.writeAll(" {\n return ");2942 try bw.writeAll(" {");
2923 try o.dg.renderNavName(w, fn_nav_index);2943 try o.newline();
2924 try w.writeByte('(');2944 try bw.writeAll("return ");
2945 try o.dg.renderNavName(bw, fn_nav_index);
2946 try bw.writeByte('(');
2925 for (0..fn_info.param_ctypes.len) |arg| {2947 for (0..fn_info.param_ctypes.len) |arg| {
2926 if (arg > 0) try w.writeAll(", ");2948 if (arg > 0) try bw.writeAll(", ");
2927 try w.print("a{d}", .{arg});2949 try bw.print("a{d}", .{arg});
2928 }2950 }
2929 try w.writeAll(");\n}\n");2951 try bw.writeAll(");");
2952 try o.newline();
2953 try bw.writeByte('}');
2954 try o.newline();
2930 },2955 },
2931 }2956 }
2932}2957}
...@@ -3015,10 +3040,7 @@ fn genFunc(f: *Function) !void {...@@ -3015,10 +3040,7 @@ fn genFunc(f: *Function) !void {
3015 const nav_val = zcu.navValue(nav_index);3040 const nav_val = zcu.navValue(nav_index);
3016 const nav = ip.getNav(nav_index);3041 const nav = ip.getNav(nav_index);
30173042
3018 o.code_header = std.ArrayList(u8).init(gpa);3043 const fwd = &o.dg.fwd_decl.buffered_writer;
3019 defer o.code_header.deinit();
3020
3021 const fwd = o.dg.fwdDeclWriter();
3022 try fwd.writeAll("static ");3044 try fwd.writeAll("static ");
3023 try o.dg.renderFunctionSignature(3045 try o.dg.renderFunctionSignature(
3024 fwd,3046 fwd,
...@@ -3029,29 +3051,23 @@ fn genFunc(f: *Function) !void {...@@ -3029,29 +3051,23 @@ fn genFunc(f: *Function) !void {
3029 );3051 );
3030 try fwd.writeAll(";\n");3052 try fwd.writeAll(";\n");
30313053
3054 const ch = &o.code_header.buffered_writer;
3032 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s|3055 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)});
3034 try o.dg.renderFunctionSignature(3057 try o.dg.renderFunctionSignature(
3035 o.writer(),3058 ch,
3036 nav_val,3059 nav_val,
3037 .none,3060 .none,
3038 .complete,3061 .complete,
3039 .{ .nav = nav_index },3062 .{ .nav = nav_index },
3040 );3063 );
3041 try o.writer().writeByte(' ');3064 try ch.writeAll(" {\n ");
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;
30493065
3050 f.free_locals_map.clearRetainingCapacity();3066 f.free_locals_map.clearRetainingCapacity();
30513067
3052 const main_body = f.air.getMainBody();3068 const main_body = f.air.getMainBody();
3053 try genBodyResolveState(f, undefined, &.{}, main_body, false);3069 try genBodyResolveState(f, undefined, &.{}, main_body, false);
3054 try o.indent_writer.insertNewline();3070 try o.newline();
3055 if (o.dg.expected_block) |_|3071 if (o.dg.expected_block) |_|
3056 return f.fail("runtime code not allowed in naked function", .{});3072 return f.fail("runtime code not allowed in naked function", .{});
30573073
...@@ -3082,24 +3098,16 @@ fn genFunc(f: *Function) !void {...@@ -3082,24 +3098,16 @@ fn genFunc(f: *Function) !void {
3082 };3098 };
3083 free_locals.sort(SortContext{ .keys = free_locals.keys() });3099 free_locals.sort(SortContext{ .keys = free_locals.keys() });
30843100
3085 const w = o.codeHeaderWriter();
3086 for (free_locals.values()) |list| {3101 for (free_locals.values()) |list| {
3087 for (list.keys()) |local_index| {3102 for (list.keys()) |local_index| {
3088 const local = f.locals.items[local_index];3103 const local = f.locals.items[local_index];
3089 try o.dg.renderCTypeAndName(w, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);3104 try o.dg.renderCTypeAndName(ch, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);
3090 try w.writeAll(";\n ");3105 try ch.writeAll(";\n ");
3091 }3106 }
3092 }3107 }
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 }
3100}3108}
31013109
3102pub fn genDecl(o: *Object) !void {3110pub fn genDecl(o: *Object) Error!void {
3103 const tracy = trace(@src());3111 const tracy = trace(@src());
3104 defer tracy.end();3112 defer tracy.end();
31053113
...@@ -3119,7 +3127,7 @@ pub fn genDecl(o: *Object) !void {...@@ -3119,7 +3127,7 @@ pub fn genDecl(o: *Object) !void {
3119 .visibility = @"extern".visibility,3127 .visibility = @"extern".visibility,
3120 });3128 });
31213129
3122 const fwd = o.dg.fwdDeclWriter();3130 const fwd = &o.dg.fwd_decl.buffered_writer;
3123 try fwd.writeAll("zig_extern ");3131 try fwd.writeAll("zig_extern ");
3124 try o.dg.renderFunctionSignature(3132 try o.dg.renderFunctionSignature(
3125 fwd,3133 fwd,
...@@ -3140,22 +3148,22 @@ pub fn genDecl(o: *Object) !void {...@@ -3140,22 +3148,22 @@ pub fn genDecl(o: *Object) !void {
3140 .linkage = .internal,3148 .linkage = .internal,
3141 .visibility = .default,3149 .visibility = .default,
3142 });3150 });
3143 const w = o.writer();3151 const bw = &o.code.buffered_writer;
3144 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");3152 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try bw.writeAll("zig_threadlocal ");
3145 if (nav.status.fully_resolved.@"linksection".toSlice(&zcu.intern_pool)) |s|3153 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)});
3147 try o.dg.renderTypeAndName(3155 try o.dg.renderTypeAndName(
3148 w,3156 bw,
3149 nav_ty,3157 nav_ty,
3150 .{ .nav = o.dg.pass.nav },3158 .{ .nav = o.dg.pass.nav },
3151 .{},3159 .{},
3152 nav.status.fully_resolved.alignment,3160 nav.status.fully_resolved.alignment,
3153 .complete,3161 .complete,
3154 );3162 );
3155 try w.writeAll(" = ");3163 try bw.writeAll(" = ");
3156 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);3164 try o.dg.renderValue(bw, Value.fromInterned(variable.init), .StaticInitializer);
3157 try w.writeByte(';');3165 try bw.writeByte(';');
3158 try o.indent_writer.insertNewline();3166 try o.newline();
3159 },3167 },
3160 else => try genDeclValue(3168 else => try genDeclValue(
3161 o,3169 o,
...@@ -3173,28 +3181,29 @@ pub fn genDeclValue(...@@ -3173,28 +3181,29 @@ pub fn genDeclValue(
3173 decl_c_value: CValue,3181 decl_c_value: CValue,
3174 alignment: Alignment,3182 alignment: Alignment,
3175 @"linksection": InternPool.OptionalNullTerminatedString,3183 @"linksection": InternPool.OptionalNullTerminatedString,
3176) !void {3184) Error!void {
3177 const zcu = o.dg.pt.zcu;3185 const zcu = o.dg.pt.zcu;
3178 const ty = val.typeOf(zcu);3186 const ty = val.typeOf(zcu);
31793187
3180 const fwd = o.dg.fwdDeclWriter();3188 const fwd = &o.dg.fwd_decl.buffered_writer;
3181 try fwd.writeAll("static ");3189 try fwd.writeAll("static ");
3182 try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete);3190 try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete);
3183 try fwd.writeAll(";\n");3191 try fwd.writeAll(";\n");
31843192
3185 const w = o.writer();3193 const bw = &o.code.buffered_writer;
3186 if (@"linksection".toSlice(&zcu.intern_pool)) |s|3194 if (@"linksection".toSlice(&zcu.intern_pool)) |s|
3187 try w.print("zig_linksection({s}) ", .{fmtStringLiteral(s, null)});3195 try bw.print("zig_linksection({fs}) ", .{fmtStringLiteral(s, null)});
3188 try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);3196 try o.dg.renderTypeAndName(bw, ty, decl_c_value, Const, alignment, .complete);
3189 try w.writeAll(" = ");3197 try bw.writeAll(" = ");
3190 try o.dg.renderValue(w, val, .StaticInitializer);3198 try o.dg.renderValue(bw, val, .StaticInitializer);
3191 try w.writeAll(";\n");3199 try bw.writeByte(';');
3200 try o.newline();
3192}3201}
31933202
3194pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {3203pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {
3195 const zcu = dg.pt.zcu;3204 const zcu = dg.pt.zcu;
3196 const ip = &zcu.intern_pool;3205 const ip = &zcu.intern_pool;
3197 const fwd = dg.fwdDeclWriter();3206 const fwd = &dg.fwd_decl.buffered_writer;
31983207
3199 const main_name = export_indices[0].ptr(zcu).opts.name;3208 const main_name = export_indices[0].ptr(zcu).opts.name;
3200 try fwd.writeAll("#define ");3209 try fwd.writeAll("#define ");
...@@ -3203,7 +3212,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3203,7 +3212,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3203 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),3212 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),
3204 }3213 }
3205 try fwd.writeByte(' ');3214 try fwd.writeByte(' ');
3206 try fwd.print("{ }", .{fmtIdent(main_name.toSlice(ip))});3215 try fwd.print("{f }", .{fmtIdent(main_name.toSlice(ip))});
3207 try fwd.writeByte('\n');3216 try fwd.writeByte('\n');
32083217
3209 const exported_val = exported.getValue(zcu);3218 const exported_val = exported.getValue(zcu);
...@@ -3233,7 +3242,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3233,7 +3242,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3233 const @"export" = export_index.ptr(zcu);3242 const @"export" = export_index.ptr(zcu);
3234 try fwd.writeAll("zig_extern ");3243 try fwd.writeAll("zig_extern ");
3235 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage ");3244 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}) ", .{
3237 fmtStringLiteral(s, null),3246 fmtStringLiteral(s, null),
3238 });3247 });
3239 const extern_name = @"export".opts.name.toSlice(ip);3248 const extern_name = @"export".opts.name.toSlice(ip);
...@@ -3248,17 +3257,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3248,17 +3257,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3248 .complete,3257 .complete,
3249 );3258 );
3250 if (is_mangled and is_export) {3259 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})", .{
3252 fmtIdent(extern_name),3261 fmtIdent(extern_name),
3253 fmtStringLiteral(extern_name, null),3262 fmtStringLiteral(extern_name, null),
3254 fmtStringLiteral(main_name.toSlice(ip), null),3263 fmtStringLiteral(main_name.toSlice(ip), null),
3255 });3264 });
3256 } else if (is_mangled) {3265 } else if (is_mangled) {
3257 try fwd.print(" zig_mangled({ }, {s})", .{3266 try fwd.print(" zig_mangled({f }, {fs})", .{
3258 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),3267 fmtIdent(extern_name), fmtStringLiteral(extern_name, null),
3259 });3268 });
3260 } else if (is_export) {3269 } else if (is_export) {
3261 try fwd.print(" zig_export({s}, {s})", .{3270 try fwd.print(" zig_export({fs}, {fs})", .{
3262 fmtStringLiteral(main_name.toSlice(ip), null),3271 fmtStringLiteral(main_name.toSlice(ip), null),
3263 fmtStringLiteral(extern_name, null),3272 fmtStringLiteral(extern_name, null),
3264 });3273 });
...@@ -3271,16 +3280,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3271,16 +3280,17 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3271/// `value_map` and `free_locals_map` are undefined after the generation, and new locals may not3280/// `value_map` and `free_locals_map` are undefined after the generation, and new locals may not
3272/// have been added to `free_locals_map`. For a version of this function that restores this state,3281/// have been added to `free_locals_map`. For a version of this function that restores this state,
3273/// see `genBodyResolveState`.3282/// see `genBodyResolveState`.
3274fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {3283fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
3275 const writer = f.object.writer();3284 const bw = &f.object.code.buffered_writer;
3276 if (body.len == 0) {3285 if (body.len == 0) {
3277 try writer.writeAll("{}");3286 try bw.writeAll("{}");
3278 } else {3287 } else {
3279 try writer.writeAll("{\n");3288 try bw.writeAll("{");
3280 f.object.indent_writer.pushIndent();3289 f.object.indent();
3290 try f.object.newline();
3281 try genBodyInner(f, body);3291 try genBodyInner(f, body);
3282 f.object.indent_writer.popIndent();3292 f.object.outdent();
3283 try writer.writeByte('}');3293 try bw.writeByte('}');
3284 }3294 }
3285}3295}
32863296
...@@ -3290,10 +3300,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -3290,10 +3300,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
3290/// `leading_deaths` have their deaths processed before the body is generated.3300/// `leading_deaths` have their deaths processed before the body is generated.
3291/// A scope is introduced (using braces) only if `inner` is `false`.3301/// A scope is introduced (using braces) only if `inner` is `false`.
3292/// If `leading_deaths` is empty, `inst` may be `undefined`.3302/// 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 {
3294 if (body.len == 0) {3304 if (body.len == 0) {
3295 // Don't go to the expense of cloning everything!3305 // 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("{}");
3297 return;3307 return;
3298 }3308 }
32993309
...@@ -3339,7 +3349,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con...@@ -3339,7 +3349,7 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
3339 }3349 }
3340}3350}
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 {
3343 const zcu = f.object.dg.pt.zcu;3353 const zcu = f.object.dg.pt.zcu;
3344 const ip = &zcu.intern_pool;3354 const ip = &zcu.intern_pool;
3345 const air_tags = f.air.instructions.items(.tag);3355 const air_tags = f.air.instructions.items(.tag);
...@@ -3357,7 +3367,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3357,7 +3367,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
33573367
3358 .arg => try airArg(f, inst),3368 .arg => try airArg(f, inst),
33593369
3360 .breakpoint => try airBreakpoint(f.object.writer()),3370 .breakpoint => try airBreakpoint(&f.object, &f.object.code.buffered_writer),
3361 .ret_addr => try airRetAddr(f, inst),3371 .ret_addr => try airRetAddr(f, inst),
3362 .frame_addr => try airFrameAddress(f, inst),3372 .frame_addr => try airFrameAddress(f, inst),
33633373
...@@ -3610,7 +3620,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,...@@ -3610,7 +3620,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
3610 .ret => return airRet(f, inst, false),3620 .ret => return airRet(f, inst, false),
3611 .ret_safe => return airRet(f, inst, false), // TODO3621 .ret_safe => return airRet(f, inst, false), // TODO
3612 .ret_load => return airRet(f, inst, true),3622 .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),
3614 .unreach => return airUnreach(f),3624 .unreach => return airUnreach(f),
36153625
3616 // Instructions which may be `noreturn`.3626 // Instructions which may be `noreturn`.
...@@ -3654,16 +3664,16 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3654,16 +3664,16 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3654 const operand = try f.resolveInst(ty_op.operand);3664 const operand = try f.resolveInst(ty_op.operand);
3655 try reap(f, inst, &.{ty_op.operand});3665 try reap(f, inst, &.{ty_op.operand});
36563666
3657 const writer = f.object.writer();3667 const bw = &f.object.code.buffered_writer;
3658 const local = try f.allocLocal(inst, inst_ty);3668 const local = try f.allocLocal(inst, inst_ty);
3659 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3669 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3660 try f.writeCValue(writer, local, .Other);3670 try f.writeCValue(bw, local, .Other);
3661 try a.assign(f, writer);3671 try a.assign(f, bw);
3662 if (is_ptr) {3672 if (is_ptr) {
3663 try writer.writeByte('&');3673 try bw.writeByte('&');
3664 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });3674 try f.writeCValueDerefMember(bw, operand, .{ .identifier = field_name });
3665 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });3675 } else try f.writeCValueMember(bw, operand, .{ .identifier = field_name });
3666 try a.end(f, writer);3676 try a.end(f, bw);
3667 return local;3677 return local;
3668}3678}
36693679
...@@ -3680,16 +3690,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3680,16 +3690,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3680 const index = try f.resolveInst(bin_op.rhs);3690 const index = try f.resolveInst(bin_op.rhs);
3681 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3691 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;
3684 const local = try f.allocLocal(inst, inst_ty);3694 const local = try f.allocLocal(inst, inst_ty);
3685 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3695 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3686 try f.writeCValue(writer, local, .Other);3696 try f.writeCValue(bw, local, .Other);
3687 try a.assign(f, writer);3697 try a.assign(f, bw);
3688 try f.writeCValue(writer, ptr, .Other);3698 try f.writeCValue(bw, ptr, .Other);
3689 try writer.writeByte('[');3699 try bw.writeByte('[');
3690 try f.writeCValue(writer, index, .Other);3700 try f.writeCValue(bw, index, .Other);
3691 try writer.writeByte(']');3701 try bw.writeByte(']');
3692 try a.end(f, writer);3702 try a.end(f, bw);
3693 return local;3703 return local;
3694}3704}
36953705
...@@ -3707,25 +3717,25 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3707,25 +3717,25 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3707 const index = try f.resolveInst(bin_op.rhs);3717 const index = try f.resolveInst(bin_op.rhs);
3708 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3718 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;
3711 const local = try f.allocLocal(inst, inst_ty);3721 const local = try f.allocLocal(inst, inst_ty);
3712 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3722 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3713 try f.writeCValue(writer, local, .Other);3723 try f.writeCValue(bw, local, .Other);
3714 try a.assign(f, writer);3724 try a.assign(f, bw);
3715 try writer.writeByte('(');3725 try bw.writeByte('(');
3716 try f.renderType(writer, inst_ty);3726 try f.renderType(bw, inst_ty);
3717 try writer.writeByte(')');3727 try bw.writeByte(')');
3718 if (elem_has_bits) try writer.writeByte('&');3728 if (elem_has_bits) try bw.writeByte('&');
3719 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {3729 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {
3720 // It's a pointer to an array, so we need to de-reference.3730 // It's a pointer to an array, so we need to de-reference.
3721 try f.writeCValueDeref(writer, ptr);3731 try f.writeCValueDeref(bw, ptr);
3722 } else try f.writeCValue(writer, ptr, .Other);3732 } else try f.writeCValue(bw, ptr, .Other);
3723 if (elem_has_bits) {3733 if (elem_has_bits) {
3724 try writer.writeByte('[');3734 try bw.writeByte('[');
3725 try f.writeCValue(writer, index, .Other);3735 try f.writeCValue(bw, index, .Other);
3726 try writer.writeByte(']');3736 try bw.writeByte(']');
3727 }3737 }
3728 try a.end(f, writer);3738 try a.end(f, bw);
3729 return local;3739 return local;
3730}3740}
37313741
...@@ -3742,16 +3752,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3742,16 +3752,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3742 const index = try f.resolveInst(bin_op.rhs);3752 const index = try f.resolveInst(bin_op.rhs);
3743 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3753 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;
3746 const local = try f.allocLocal(inst, inst_ty);3756 const local = try f.allocLocal(inst, inst_ty);
3747 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3757 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3748 try f.writeCValue(writer, local, .Other);3758 try f.writeCValue(bw, local, .Other);
3749 try a.assign(f, writer);3759 try a.assign(f, bw);
3750 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });3760 try f.writeCValueMember(bw, slice, .{ .identifier = "ptr" });
3751 try writer.writeByte('[');3761 try bw.writeByte('[');
3752 try f.writeCValue(writer, index, .Other);3762 try f.writeCValue(bw, index, .Other);
3753 try writer.writeByte(']');3763 try bw.writeByte(']');
3754 try a.end(f, writer);3764 try a.end(f, bw);
3755 return local;3765 return local;
3756}3766}
37573767
...@@ -3770,19 +3780,19 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3770,19 +3780,19 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3770 const index = try f.resolveInst(bin_op.rhs);3780 const index = try f.resolveInst(bin_op.rhs);
3771 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3781 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;
3774 const local = try f.allocLocal(inst, inst_ty);3784 const local = try f.allocLocal(inst, inst_ty);
3775 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3785 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3776 try f.writeCValue(writer, local, .Other);3786 try f.writeCValue(bw, local, .Other);
3777 try a.assign(f, writer);3787 try a.assign(f, bw);
3778 if (elem_has_bits) try writer.writeByte('&');3788 if (elem_has_bits) try bw.writeByte('&');
3779 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });3789 try f.writeCValueMember(bw, slice, .{ .identifier = "ptr" });
3780 if (elem_has_bits) {3790 if (elem_has_bits) {
3781 try writer.writeByte('[');3791 try bw.writeByte('[');
3782 try f.writeCValue(writer, index, .Other);3792 try f.writeCValue(bw, index, .Other);
3783 try writer.writeByte(']');3793 try bw.writeByte(']');
3784 }3794 }
3785 try a.end(f, writer);3795 try a.end(f, bw);
3786 return local;3796 return local;
3787}3797}
37883798
...@@ -3799,16 +3809,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3799,16 +3809,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3799 const index = try f.resolveInst(bin_op.rhs);3809 const index = try f.resolveInst(bin_op.rhs);
3800 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3810 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;
3803 const local = try f.allocLocal(inst, inst_ty);3813 const local = try f.allocLocal(inst, inst_ty);
3804 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3814 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
3805 try f.writeCValue(writer, local, .Other);3815 try f.writeCValue(bw, local, .Other);
3806 try a.assign(f, writer);3816 try a.assign(f, bw);
3807 try f.writeCValue(writer, array, .Other);3817 try f.writeCValue(bw, array, .Other);
3808 try writer.writeByte('[');3818 try bw.writeByte('[');
3809 try f.writeCValue(writer, index, .Other);3819 try f.writeCValue(bw, index, .Other);
3810 try writer.writeByte(']');3820 try bw.writeByte(']');
3811 try a.end(f, writer);3821 try a.end(f, bw);
3812 return local;3822 return local;
3813}3823}
38143824
...@@ -3862,12 +3872,13 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3862,12 +3872,13 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3862 .{ .arg_array = i };3872 .{ .arg_array = i };
38633873
3864 if (f.liveness.isUnused(inst)) {3874 if (f.liveness.isUnused(inst)) {
3865 const writer = f.object.writer();3875 const bw = &f.object.code.buffered_writer;
3866 try writer.writeByte('(');3876 try bw.writeByte('(');
3867 try f.renderType(writer, .void);3877 try f.renderType(bw, .void);
3868 try writer.writeByte(')');3878 try bw.writeByte(')');
3869 try f.writeCValue(writer, result, .Other);3879 try f.writeCValue(bw, result, .Other);
3870 try writer.writeAll(";\n");3880 try bw.writeByte(';');
3881 try f.object.newline();
3871 return .none;3882 return .none;
3872 }3883 }
38733884
...@@ -3900,21 +3911,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3900,21 +3911,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3900 const is_array = lowersToArray(src_ty, pt);3911 const is_array = lowersToArray(src_ty, pt);
3901 const need_memcpy = !is_aligned or is_array;3912 const need_memcpy = !is_aligned or is_array;
39023913
3903 const writer = f.object.writer();3914 const bw = &f.object.code.buffered_writer;
3904 const local = try f.allocLocal(inst, src_ty);3915 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
3907 if (need_memcpy) {3918 if (need_memcpy) {
3908 try writer.writeAll("memcpy(");3919 try bw.writeAll("memcpy(");
3909 if (!is_array) try writer.writeByte('&');3920 if (!is_array) try bw.writeByte('&');
3910 try f.writeCValue(writer, local, .Other);3921 try f.writeCValue(bw, local, .Other);
3911 try v.elem(f, writer);3922 try v.elem(f, bw);
3912 try writer.writeAll(", (const char *)");3923 try bw.writeAll(", (const char *)");
3913 try f.writeCValue(writer, operand, .Other);3924 try f.writeCValue(bw, operand, .Other);
3914 try v.elem(f, writer);3925 try v.elem(f, bw);
3915 try writer.writeAll(", sizeof(");3926 try bw.writeAll(", sizeof(");
3916 try f.renderType(writer, src_ty);3927 try f.renderType(bw, src_ty);
3917 try writer.writeAll("))");3928 try bw.writeAll("))");
3918 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {3929 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3919 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;3930 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
3920 const host_ty = try pt.intType(.unsigned, host_bits);3931 const host_ty = try pt.intType(.unsigned, host_bits);
...@@ -3924,40 +3935,41 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3924,40 +3935,41 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39243935
3925 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));3936 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));
39263937
3927 try f.writeCValue(writer, local, .Other);3938 try f.writeCValue(bw, local, .Other);
3928 try v.elem(f, writer);3939 try v.elem(f, bw);
3929 try writer.writeAll(" = (");3940 try bw.writeAll(" = (");
3930 try f.renderType(writer, src_ty);3941 try f.renderType(bw, src_ty);
3931 try writer.writeAll(")zig_wrap_");3942 try bw.writeAll(")zig_wrap_");
3932 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);3943 try f.object.dg.renderTypeForBuiltinFnName(bw, field_ty);
3933 try writer.writeAll("((");3944 try bw.writeAll("((");
3934 try f.renderType(writer, field_ty);3945 try f.renderType(bw, field_ty);
3935 try writer.writeByte(')');3946 try bw.writeByte(')');
3936 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;3947 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
3937 if (cant_cast) {3948 if (cant_cast) {
3938 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});3949 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3939 try writer.writeAll("zig_lo_");3950 try bw.writeAll("zig_lo_");
3940 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3951 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
3941 try writer.writeByte('(');3952 try bw.writeByte('(');
3942 }3953 }
3943 try writer.writeAll("zig_shr_");3954 try bw.writeAll("zig_shr_");
3944 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3955 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
3945 try writer.writeByte('(');3956 try bw.writeByte('(');
3946 try f.writeCValueDeref(writer, operand);3957 try f.writeCValueDeref(bw, operand);
3947 try v.elem(f, writer);3958 try v.elem(f, bw);
3948 try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_val)});3959 try bw.print(", {f})", .{try f.fmtIntLiteral(bit_offset_val)});
3949 if (cant_cast) try writer.writeByte(')');3960 if (cant_cast) try bw.writeByte(')');
3950 try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits);3961 try f.object.dg.renderBuiltinInfo(bw, field_ty, .bits);
3951 try writer.writeByte(')');3962 try bw.writeByte(')');
3952 } else {3963 } else {
3953 try f.writeCValue(writer, local, .Other);3964 try f.writeCValue(bw, local, .Other);
3954 try v.elem(f, writer);3965 try v.elem(f, bw);
3955 try writer.writeAll(" = ");3966 try bw.writeAll(" = ");
3956 try f.writeCValueDeref(writer, operand);3967 try f.writeCValueDeref(bw, operand);
3957 try v.elem(f, writer);3968 try v.elem(f, bw);
3958 }3969 }
3959 try writer.writeAll(";\n");3970 try bw.writeByte(';');
3960 try v.end(f, inst, writer);3971 try f.object.newline();
3972 try v.end(f, inst, bw);
39613973
3962 return local;3974 return local;
3963}3975}
...@@ -3966,7 +3978,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -3966,7 +3978,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3966 const pt = f.object.dg.pt;3978 const pt = f.object.dg.pt;
3967 const zcu = pt.zcu;3979 const zcu = pt.zcu;
3968 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;3980 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;
3970 const op_inst = un_op.toIndex();3982 const op_inst = un_op.toIndex();
3971 const op_ty = f.typeOf(un_op);3983 const op_ty = f.typeOf(un_op);
3972 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;3984 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 {...@@ -3985,33 +3997,38 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3985 .ctype = ret_ctype,3997 .ctype = ret_ctype,
3986 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),3998 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
3987 });3999 });
3988 try writer.writeAll("memcpy(");4000 try bw.writeAll("memcpy(");
3989 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });4001 try f.writeCValueMember(bw, array_local, .{ .identifier = "array" });
3990 try writer.writeAll(", ");4002 try bw.writeAll(", ");
3991 if (deref)4003 if (deref)
3992 try f.writeCValueDeref(writer, operand)4004 try f.writeCValueDeref(bw, operand)
3993 else4005 else
3994 try f.writeCValue(writer, operand, .FunctionArgument);4006 try f.writeCValue(bw, operand, .FunctionArgument);
3995 deref = false;4007 deref = false;
3996 try writer.writeAll(", sizeof(");4008 try bw.writeAll(", sizeof(");
3997 try f.renderType(writer, ret_ty);4009 try f.renderType(bw, ret_ty);
3998 try writer.writeAll("));\n");4010 try bw.writeAll("));");
4011 try f.object.newline();
3999 break :ret_val array_local;4012 break :ret_val array_local;
4000 } else operand;4013 } else operand;
40014014
4002 try writer.writeAll("return ");4015 try bw.writeAll("return ");
4003 if (deref)4016 if (deref)
4004 try f.writeCValueDeref(writer, ret_val)4017 try f.writeCValueDeref(bw, ret_val)
4005 else4018 else
4006 try f.writeCValue(writer, ret_val, .Other);4019 try f.writeCValue(bw, ret_val, .Other);
4007 try writer.writeAll(";\n");4020 try bw.writeByte(';');
4021 try f.object.newline();
4008 if (is_array) {4022 if (is_array) {
4009 try freeLocal(f, inst, ret_val.new_local, null);4023 try freeLocal(f, inst, ret_val.new_local, null);
4010 }4024 }
4011 } else {4025 } else {
4012 try reap(f, inst, &.{un_op});4026 try reap(f, inst, &.{un_op});
4013 // Not even allowed to return void in a naked function.4027 // 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 }
4015 }4032 }
4016}4033}
40174034
...@@ -4030,16 +4047,16 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4030,16 +4047,16 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
40304047
4031 if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);4048 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;
4034 const local = try f.allocLocal(inst, inst_ty);4051 const local = try f.allocLocal(inst, inst_ty);
4035 const v = try Vectorize.start(f, inst, writer, operand_ty);4052 const v = try Vectorize.start(f, inst, bw, operand_ty);
4036 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));4053 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
4037 try f.writeCValue(writer, local, .Other);4054 try f.writeCValue(bw, local, .Other);
4038 try v.elem(f, writer);4055 try v.elem(f, bw);
4039 try a.assign(f, writer);4056 try a.assign(f, bw);
4040 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);4057 try f.renderIntCast(bw, inst_scalar_ty, operand, v, scalar_ty, .Other);
4041 try a.end(f, writer);4058 try a.end(f, bw);
4042 try v.end(f, inst, writer);4059 try v.end(f, inst, bw);
4043 return local;4060 return local;
4044}4061}
40454062
...@@ -4066,34 +4083,34 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4066,34 +4083,34 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4066 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);4083 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
4067 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);4084 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;
4070 const local = try f.allocLocal(inst, inst_ty);4087 const local = try f.allocLocal(inst, inst_ty);
4071 const v = try Vectorize.start(f, inst, writer, operand_ty);4088 const v = try Vectorize.start(f, inst, bw, operand_ty);
4072 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));4089 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_scalar_ty, .complete));
4073 try f.writeCValue(writer, local, .Other);4090 try f.writeCValue(bw, local, .Other);
4074 try v.elem(f, writer);4091 try v.elem(f, bw);
4075 try a.assign(f, writer);4092 try a.assign(f, bw);
4076 if (need_cast) {4093 if (need_cast) {
4077 try writer.writeByte('(');4094 try bw.writeByte('(');
4078 try f.renderType(writer, inst_scalar_ty);4095 try f.renderType(bw, inst_scalar_ty);
4079 try writer.writeByte(')');4096 try bw.writeByte(')');
4080 }4097 }
4081 if (need_lo) {4098 if (need_lo) {
4082 try writer.writeAll("zig_lo_");4099 try bw.writeAll("zig_lo_");
4083 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4100 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4084 try writer.writeByte('(');4101 try bw.writeByte('(');
4085 }4102 }
4086 if (!need_mask) {4103 if (!need_mask) {
4087 try f.writeCValue(writer, operand, .Other);4104 try f.writeCValue(bw, operand, .Other);
4088 try v.elem(f, writer);4105 try v.elem(f, bw);
4089 } else switch (dest_int_info.signedness) {4106 } else switch (dest_int_info.signedness) {
4090 .unsigned => {4107 .unsigned => {
4091 try writer.writeAll("zig_and_");4108 try bw.writeAll("zig_and_");
4092 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4109 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4093 try writer.writeByte('(');4110 try bw.writeByte('(');
4094 try f.writeCValue(writer, operand, .FunctionArgument);4111 try f.writeCValue(bw, operand, .FunctionArgument);
4095 try v.elem(f, writer);4112 try v.elem(f, bw);
4096 try writer.print(", {x})", .{4113 try bw.print(", {fx})", .{
4097 try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),4114 try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
4098 });4115 });
4099 },4116 },
...@@ -4102,30 +4119,30 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4102,30 +4119,30 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4102 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});4119 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
4103 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);4120 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
41044121
4105 try writer.writeAll("zig_shr_");4122 try bw.writeAll("zig_shr_");
4106 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4123 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4107 if (c_bits == 128) {4124 if (c_bits == 128) {
4108 try writer.print("(zig_bitCast_i{d}(", .{c_bits});4125 try bw.print("(zig_bitCast_i{d}(", .{c_bits});
4109 } else {4126 } else {
4110 try writer.print("((int{d}_t)", .{c_bits});4127 try bw.print("((int{d}_t)", .{c_bits});
4111 }4128 }
4112 try writer.print("zig_shl_u{d}(", .{c_bits});4129 try bw.print("zig_shl_u{d}(", .{c_bits});
4113 if (c_bits == 128) {4130 if (c_bits == 128) {
4114 try writer.print("zig_bitCast_u{d}(", .{c_bits});4131 try bw.print("zig_bitCast_u{d}(", .{c_bits});
4115 } else {4132 } else {
4116 try writer.print("(uint{d}_t)", .{c_bits});4133 try bw.print("(uint{d}_t)", .{c_bits});
4117 }4134 }
4118 try f.writeCValue(writer, operand, .FunctionArgument);4135 try f.writeCValue(bw, operand, .FunctionArgument);
4119 try v.elem(f, writer);4136 try v.elem(f, bw);
4120 if (c_bits == 128) try writer.writeByte(')');4137 if (c_bits == 128) try bw.writeByte(')');
4121 try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});4138 try bw.print(", {f})", .{try f.fmtIntLiteral(shift_val)});
4122 if (c_bits == 128) try writer.writeByte(')');4139 if (c_bits == 128) try bw.writeByte(')');
4123 try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)});4140 try bw.print(", {f})", .{try f.fmtIntLiteral(shift_val)});
4124 },4141 },
4125 }4142 }
4126 if (need_lo) try writer.writeByte(')');4143 if (need_lo) try bw.writeByte(')');
4127 try a.end(f, writer);4144 try a.end(f, bw);
4128 try v.end(f, inst, writer);4145 try v.end(f, inst, bw);
4129 return local;4146 return local;
4130}4147}
41314148
...@@ -4144,15 +4161,16 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4144,15 +4161,16 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41444161
4145 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndefDeep(zcu) else false;4162 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;
4147 if (val_is_undef) {4165 if (val_is_undef) {
4148 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4166 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
4149 if (safety and ptr_info.packed_offset.host_size == 0) {4167 if (safety and ptr_info.packed_offset.host_size == 0) {
4150 const writer = f.object.writer();4168 try bw.writeAll("memset(");
4151 try writer.writeAll("memset(");4169 try f.writeCValue(bw, ptr_val, .FunctionArgument);
4152 try f.writeCValue(writer, ptr_val, .FunctionArgument);4170 try bw.writeAll(", 0xaa, sizeof(");
4153 try writer.writeAll(", 0xaa, sizeof(");4171 try f.renderType(bw, .fromInterned(ptr_info.child));
4154 try f.renderType(writer, .fromInterned(ptr_info.child));4172 try bw.writeAll("));");
4155 try writer.writeAll("));\n");4173 try f.object.newline();
4156 }4174 }
4157 return .none;4175 return .none;
4158 }4176 }
...@@ -4168,7 +4186,6 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4168,7 +4186,6 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4168 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4186 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41694187
4170 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);4188 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);
4171 const writer = f.object.writer();
4172 if (need_memcpy) {4189 if (need_memcpy) {
4173 // For this memcpy to safely work we need the rhs to have the same4190 // For this memcpy to safely work we need the rhs to have the same
4174 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).4191 // 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 {...@@ -4179,28 +4196,30 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4179 // TODO this should be done by manually initializing elements of the dest array4196 // TODO this should be done by manually initializing elements of the dest array
4180 const array_src = if (src_val == .constant) blk: {4197 const array_src = if (src_val == .constant) blk: {
4181 const new_local = try f.allocLocal(inst, src_ty);4198 const new_local = try f.allocLocal(inst, src_ty);
4182 try f.writeCValue(writer, new_local, .Other);4199 try f.writeCValue(bw, new_local, .Other);
4183 try writer.writeAll(" = ");4200 try bw.writeAll(" = ");
4184 try f.writeCValue(writer, src_val, .Other);4201 try f.writeCValue(bw, src_val, .Other);
4185 try writer.writeAll(";\n");4202 try bw.writeByte(';');
4203 try f.object.newline();
41864204
4187 break :blk new_local;4205 break :blk new_local;
4188 } else src_val;4206 } else src_val;
41894207
4190 const v = try Vectorize.start(f, inst, writer, ptr_ty);4208 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4191 try writer.writeAll("memcpy((char *)");4209 try bw.writeAll("memcpy((char *)");
4192 try f.writeCValue(writer, ptr_val, .FunctionArgument);4210 try f.writeCValue(bw, ptr_val, .FunctionArgument);
4193 try v.elem(f, writer);4211 try v.elem(f, bw);
4194 try writer.writeAll(", ");4212 try bw.writeAll(", ");
4195 if (!is_array) try writer.writeByte('&');4213 if (!is_array) try bw.writeByte('&');
4196 try f.writeCValue(writer, array_src, .FunctionArgument);4214 try f.writeCValue(bw, array_src, .FunctionArgument);
4197 try v.elem(f, writer);4215 try v.elem(f, bw);
4198 try writer.writeAll(", sizeof(");4216 try bw.writeAll(", sizeof(");
4199 try f.renderType(writer, src_ty);4217 try f.renderType(bw, src_ty);
4200 try writer.writeAll("))");4218 try bw.writeAll("))");
4201 try f.freeCValue(inst, array_src);4219 try f.freeCValue(inst, array_src);
4202 try writer.writeAll(";\n");4220 try bw.writeByte(';');
4203 try v.end(f, inst, writer);4221 try f.object.newline();
4222 try v.end(f, inst, bw);
4204 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {4223 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
4205 const host_bits = ptr_info.packed_offset.host_size * 8;4224 const host_bits = ptr_info.packed_offset.host_size * 8;
4206 const host_ty = try pt.intType(.unsigned, host_bits);4225 const host_ty = try pt.intType(.unsigned, host_bits);
...@@ -4223,44 +4242,44 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4223,44 +4242,44 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
42234242
4224 const mask_val = try pt.intValue_big(host_ty, mask.toConst());4243 const mask_val = try pt.intValue_big(host_ty, mask.toConst());
42254244
4226 const v = try Vectorize.start(f, inst, writer, ptr_ty);4245 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4227 const a = try Assignment.start(f, writer, src_scalar_ctype);4246 const a = try Assignment.start(f, bw, src_scalar_ctype);
4228 try f.writeCValueDeref(writer, ptr_val);4247 try f.writeCValueDeref(bw, ptr_val);
4229 try v.elem(f, writer);4248 try v.elem(f, bw);
4230 try a.assign(f, writer);4249 try a.assign(f, bw);
4231 try writer.writeAll("zig_or_");4250 try bw.writeAll("zig_or_");
4232 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4251 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4233 try writer.writeAll("(zig_and_");4252 try bw.writeAll("(zig_and_");
4234 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4253 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4235 try writer.writeByte('(');4254 try bw.writeByte('(');
4236 try f.writeCValueDeref(writer, ptr_val);4255 try f.writeCValueDeref(bw, ptr_val);
4237 try v.elem(f, writer);4256 try v.elem(f, bw);
4238 try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});4257 try bw.print(", {fx}), zig_shl_", .{try f.fmtIntLiteral(mask_val)});
4239 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4258 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4240 try writer.writeByte('(');4259 try bw.writeByte('(');
4241 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;4260 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
4242 if (cant_cast) {4261 if (cant_cast) {
4243 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});4262 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
4244 try writer.writeAll("zig_make_");4263 try bw.writeAll("zig_make_");
4245 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4264 try f.object.dg.renderTypeForBuiltinFnName(bw, host_ty);
4246 try writer.writeAll("(0, ");4265 try bw.writeAll("(0, ");
4247 } else {4266 } else {
4248 try writer.writeByte('(');4267 try bw.writeByte('(');
4249 try f.renderType(writer, host_ty);4268 try f.renderType(bw, host_ty);
4250 try writer.writeByte(')');4269 try bw.writeByte(')');
4251 }4270 }
42524271
4253 if (src_ty.isPtrAtRuntime(zcu)) {4272 if (src_ty.isPtrAtRuntime(zcu)) {
4254 try writer.writeByte('(');4273 try bw.writeByte('(');
4255 try f.renderType(writer, .usize);4274 try f.renderType(bw, .usize);
4256 try writer.writeByte(')');4275 try bw.writeByte(')');
4257 }4276 }
4258 try f.writeCValue(writer, src_val, .Other);4277 try f.writeCValue(bw, src_val, .Other);
4259 try v.elem(f, writer);4278 try v.elem(f, bw);
4260 if (cant_cast) try writer.writeByte(')');4279 if (cant_cast) try bw.writeByte(')');
4261 try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_val)});4280 try bw.print(", {f}))", .{try f.fmtIntLiteral(bit_offset_val)});
4262 try a.end(f, writer);4281 try a.end(f, bw);
4263 try v.end(f, inst, writer);4282 try v.end(f, inst, bw);
4264 } else {4283 } else {
4265 switch (ptr_val) {4284 switch (ptr_val) {
4266 .local_ref => |ptr_local_index| switch (src_val) {4285 .local_ref => |ptr_local_index| switch (src_val) {
...@@ -4270,15 +4289,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4270,15 +4289,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4270 },4289 },
4271 else => {},4290 else => {},
4272 }4291 }
4273 const v = try Vectorize.start(f, inst, writer, ptr_ty);4292 const v = try Vectorize.start(f, inst, bw, ptr_ty);
4274 const a = try Assignment.start(f, writer, src_scalar_ctype);4293 const a = try Assignment.start(f, bw, src_scalar_ctype);
4275 try f.writeCValueDeref(writer, ptr_val);4294 try f.writeCValueDeref(bw, ptr_val);
4276 try v.elem(f, writer);4295 try v.elem(f, bw);
4277 try a.assign(f, writer);4296 try a.assign(f, bw);
4278 try f.writeCValue(writer, src_val, .Other);4297 try f.writeCValue(bw, src_val, .Other);
4279 try v.elem(f, writer);4298 try v.elem(f, bw);
4280 try a.end(f, writer);4299 try a.end(f, bw);
4281 try v.end(f, inst, writer);4300 try v.end(f, inst, bw);
4282 }4301 }
4283 return .none;4302 return .none;
4284}4303}
...@@ -4297,27 +4316,27 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:...@@ -4297,27 +4316,27 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
4297 const operand_ty = f.typeOf(bin_op.lhs);4316 const operand_ty = f.typeOf(bin_op.lhs);
4298 const scalar_ty = operand_ty.scalarType(zcu);4317 const scalar_ty = operand_ty.scalarType(zcu);
42994318
4300 const w = f.object.writer();4319 const bw = &f.object.code.buffered_writer;
4301 const local = try f.allocLocal(inst, inst_ty);4320 const local = try f.allocLocal(inst, inst_ty);
4302 const v = try Vectorize.start(f, inst, w, operand_ty);4321 const v = try Vectorize.start(f, inst, bw, operand_ty);
4303 try f.writeCValueMember(w, local, .{ .field = 1 });4322 try f.writeCValueMember(bw, local, .{ .field = 1 });
4304 try v.elem(f, w);4323 try v.elem(f, bw);
4305 try w.writeAll(" = zig_");4324 try bw.writeAll(" = zig_");
4306 try w.writeAll(operation);4325 try bw.writeAll(operation);
4307 try w.writeAll("o_");4326 try bw.writeAll("o_");
4308 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);4327 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
4309 try w.writeAll("(&");4328 try bw.writeAll("(&");
4310 try f.writeCValueMember(w, local, .{ .field = 0 });4329 try f.writeCValueMember(bw, local, .{ .field = 0 });
4311 try v.elem(f, w);4330 try v.elem(f, bw);
4312 try w.writeAll(", ");4331 try bw.writeAll(", ");
4313 try f.writeCValue(w, lhs, .FunctionArgument);4332 try f.writeCValue(bw, lhs, .FunctionArgument);
4314 try v.elem(f, w);4333 try v.elem(f, bw);
4315 try w.writeAll(", ");4334 try bw.writeAll(", ");
4316 try f.writeCValue(w, rhs, .FunctionArgument);4335 try f.writeCValue(bw, rhs, .FunctionArgument);
4317 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);4336 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, bw);
4318 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);4337 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
4319 try w.writeAll(");\n");4338 try bw.writeAll(");\n");
4320 try v.end(f, inst, w);4339 try v.end(f, inst, bw);
43214340
4322 return local;4341 return local;
4323}4342}
...@@ -4335,17 +4354,18 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4335,17 +4354,18 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
43354354
4336 const inst_ty = f.typeOfIndex(inst);4355 const inst_ty = f.typeOfIndex(inst);
43374356
4338 const writer = f.object.writer();4357 const bw = &f.object.code.buffered_writer;
4339 const local = try f.allocLocal(inst, inst_ty);4358 const local = try f.allocLocal(inst, inst_ty);
4340 const v = try Vectorize.start(f, inst, writer, operand_ty);4359 const v = try Vectorize.start(f, inst, bw, operand_ty);
4341 try f.writeCValue(writer, local, .Other);4360 try f.writeCValue(bw, local, .Other);
4342 try v.elem(f, writer);4361 try v.elem(f, bw);
4343 try writer.writeAll(" = ");4362 try bw.writeAll(" = ");
4344 try writer.writeByte('!');4363 try bw.writeByte('!');
4345 try f.writeCValue(writer, op, .Other);4364 try f.writeCValue(bw, op, .Other);
4346 try v.elem(f, writer);4365 try v.elem(f, bw);
4347 try writer.writeAll(";\n");4366 try bw.writeByte(';');
4348 try v.end(f, inst, writer);4367 try f.object.newline();
4368 try v.end(f, inst, bw);
43494369
4350 return local;4370 return local;
4351}4371}
...@@ -4371,21 +4391,22 @@ fn airBinOp(...@@ -4371,21 +4391,22 @@ fn airBinOp(
43714391
4372 const inst_ty = f.typeOfIndex(inst);4392 const inst_ty = f.typeOfIndex(inst);
43734393
4374 const writer = f.object.writer();4394 const bw = &f.object.code.buffered_writer;
4375 const local = try f.allocLocal(inst, inst_ty);4395 const local = try f.allocLocal(inst, inst_ty);
4376 const v = try Vectorize.start(f, inst, writer, operand_ty);4396 const v = try Vectorize.start(f, inst, bw, operand_ty);
4377 try f.writeCValue(writer, local, .Other);4397 try f.writeCValue(bw, local, .Other);
4378 try v.elem(f, writer);4398 try v.elem(f, bw);
4379 try writer.writeAll(" = ");4399 try bw.writeAll(" = ");
4380 try f.writeCValue(writer, lhs, .Other);4400 try f.writeCValue(bw, lhs, .Other);
4381 try v.elem(f, writer);4401 try v.elem(f, bw);
4382 try writer.writeByte(' ');4402 try bw.writeByte(' ');
4383 try writer.writeAll(operator);4403 try bw.writeAll(operator);
4384 try writer.writeByte(' ');4404 try bw.writeByte(' ');
4385 try f.writeCValue(writer, rhs, .Other);4405 try f.writeCValue(bw, rhs, .Other);
4386 try v.elem(f, writer);4406 try v.elem(f, bw);
4387 try writer.writeAll(";\n");4407 try bw.writeByte(';');
4388 try v.end(f, inst, writer);4408 try f.object.newline();
4409 try v.end(f, inst, bw);
43894410
4390 return local;4411 return local;
4391}4412}
...@@ -4421,27 +4442,27 @@ fn airCmpOp(...@@ -4421,27 +4442,27 @@ fn airCmpOp(
44214442
4422 const rhs_ty = f.typeOf(data.rhs);4443 const rhs_ty = f.typeOf(data.rhs);
4423 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);4444 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;
4425 const local = try f.allocLocal(inst, inst_ty);4446 const local = try f.allocLocal(inst, inst_ty);
4426 const v = try Vectorize.start(f, inst, writer, lhs_ty);4447 const v = try Vectorize.start(f, inst, bw, lhs_ty);
4427 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));4448 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
4428 try f.writeCValue(writer, local, .Other);4449 try f.writeCValue(bw, local, .Other);
4429 try v.elem(f, writer);4450 try v.elem(f, bw);
4430 try a.assign(f, writer);4451 try a.assign(f, bw);
4431 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {4452 if (lhs != .undef and lhs.eql(rhs)) try bw.writeAll(switch (operator) {
4432 .lt, .neq, .gt => "false",4453 .lt, .neq, .gt => "false",
4433 .lte, .eq, .gte => "true",4454 .lte, .eq, .gte => "true",
4434 }) else {4455 }) else {
4435 if (need_cast) try writer.writeAll("(void*)");4456 if (need_cast) try bw.writeAll("(void*)");
4436 try f.writeCValue(writer, lhs, .Other);4457 try f.writeCValue(bw, lhs, .Other);
4437 try v.elem(f, writer);4458 try v.elem(f, bw);
4438 try writer.writeAll(compareOperatorC(operator));4459 try bw.writeAll(compareOperatorC(operator));
4439 if (need_cast) try writer.writeAll("(void*)");4460 if (need_cast) try bw.writeAll("(void*)");
4440 try f.writeCValue(writer, rhs, .Other);4461 try f.writeCValue(bw, rhs, .Other);
4441 try v.elem(f, writer);4462 try v.elem(f, bw);
4442 }4463 }
4443 try a.end(f, writer);4464 try a.end(f, bw);
4444 try v.end(f, inst, writer);4465 try v.end(f, inst, bw);
44454466
4446 return local;4467 return local;
4447}4468}
...@@ -4474,41 +4495,41 @@ fn airEquality(...@@ -4474,41 +4495,41 @@ fn airEquality(
4474 const rhs = try f.resolveInst(bin_op.rhs);4495 const rhs = try f.resolveInst(bin_op.rhs);
4475 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4496 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;
4478 const local = try f.allocLocal(inst, .bool);4499 const local = try f.allocLocal(inst, .bool);
4479 const a = try Assignment.start(f, writer, .bool);4500 const a = try Assignment.start(f, bw, .bool);
4480 try f.writeCValue(writer, local, .Other);4501 try f.writeCValue(bw, local, .Other);
4481 try a.assign(f, writer);4502 try a.assign(f, bw);
44824503
4483 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);4504 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) {
4485 .lt, .lte, .gte, .gt => unreachable,4506 .lt, .lte, .gte, .gt => unreachable,
4486 .neq => "false",4507 .neq => "false",
4487 .eq => "true",4508 .eq => "true",
4488 }) else switch (operand_ctype.info(ctype_pool)) {4509 }) else switch (operand_ctype.info(ctype_pool)) {
4489 .basic, .pointer => {4510 .basic, .pointer => {
4490 try f.writeCValue(writer, lhs, .Other);4511 try f.writeCValue(bw, lhs, .Other);
4491 try writer.writeAll(compareOperatorC(operator));4512 try bw.writeAll(compareOperatorC(operator));
4492 try f.writeCValue(writer, rhs, .Other);4513 try f.writeCValue(bw, rhs, .Other);
4493 },4514 },
4494 .aligned, .array, .vector, .fwd_decl, .function => unreachable,4515 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
4495 .aggregate => |aggregate| if (aggregate.fields.len == 2 and4516 .aggregate => |aggregate| if (aggregate.fields.len == 2 and
4496 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or4517 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
4497 aggregate.fields.at(1, ctype_pool).name.index == .is_null))4518 aggregate.fields.at(1, ctype_pool).name.index == .is_null))
4498 {4519 {
4499 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });4520 try f.writeCValueMember(bw, lhs, .{ .identifier = "is_null" });
4500 try writer.writeAll(" || ");4521 try bw.writeAll(" || ");
4501 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });4522 try f.writeCValueMember(bw, rhs, .{ .identifier = "is_null" });
4502 try writer.writeAll(" ? ");4523 try bw.writeAll(" ? ");
4503 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });4524 try f.writeCValueMember(bw, lhs, .{ .identifier = "is_null" });
4504 try writer.writeAll(compareOperatorC(operator));4525 try bw.writeAll(compareOperatorC(operator));
4505 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });4526 try f.writeCValueMember(bw, rhs, .{ .identifier = "is_null" });
4506 try writer.writeAll(" : ");4527 try bw.writeAll(" : ");
4507 try f.writeCValueMember(writer, lhs, .{ .identifier = "payload" });4528 try f.writeCValueMember(bw, lhs, .{ .identifier = "payload" });
4508 try writer.writeAll(compareOperatorC(operator));4529 try bw.writeAll(compareOperatorC(operator));
4509 try f.writeCValueMember(writer, rhs, .{ .identifier = "payload" });4530 try f.writeCValueMember(bw, rhs, .{ .identifier = "payload" });
4510 } else for (0..aggregate.fields.len) |field_index| {4531 } 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) {
4512 .lt, .lte, .gte, .gt => unreachable,4533 .lt, .lte, .gte, .gt => unreachable,
4513 .eq => " && ",4534 .eq => " && ",
4514 .neq => " || ",4535 .neq => " || ",
...@@ -4516,12 +4537,12 @@ fn airEquality(...@@ -4516,12 +4537,12 @@ fn airEquality(
4516 const field_name: CValue = .{4537 const field_name: CValue = .{
4517 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,4538 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,
4518 };4539 };
4519 try f.writeCValueMember(writer, lhs, field_name);4540 try f.writeCValueMember(bw, lhs, field_name);
4520 try writer.writeAll(compareOperatorC(operator));4541 try bw.writeAll(compareOperatorC(operator));
4521 try f.writeCValueMember(writer, rhs, field_name);4542 try f.writeCValueMember(bw, rhs, field_name);
4522 },4543 },
4523 }4544 }
4524 try a.end(f, writer);4545 try a.end(f, bw);
45254546
4526 return local;4547 return local;
4527}4548}
...@@ -4532,12 +4553,13 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4532,12 +4553,13 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
4532 const operand = try f.resolveInst(un_op);4553 const operand = try f.resolveInst(un_op);
4533 try reap(f, inst, &.{un_op});4554 try reap(f, inst, &.{un_op});
45344555
4535 const writer = f.object.writer();4556 const bw = &f.object.code.buffered_writer;
4536 const local = try f.allocLocal(inst, .bool);4557 const local = try f.allocLocal(inst, .bool);
4537 try f.writeCValue(writer, local, .Other);4558 try f.writeCValue(bw, local, .Other);
4538 try writer.writeAll(" = ");4559 try bw.writeAll(" = ");
4539 try f.writeCValue(writer, operand, .Other);4560 try f.writeCValue(bw, operand, .Other);
4540 try writer.print(" < sizeof({ }) / sizeof(*{0 });\n", .{fmtIdent("zig_errorName")});4561 try bw.print(" < sizeof({f }) / sizeof(*{0f });", .{fmtIdent("zig_errorName")});
4562 try f.object.newline();
4541 return local;4563 return local;
4542}4564}
45434565
...@@ -4558,30 +4580,30 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -4558,30 +4580,30 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4558 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);4580 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
45594581
4560 const local = try f.allocLocal(inst, inst_ty);4582 const local = try f.allocLocal(inst, inst_ty);
4561 const writer = f.object.writer();4583 const bw = &f.object.code.buffered_writer;
4562 const v = try Vectorize.start(f, inst, writer, inst_ty);4584 const v = try Vectorize.start(f, inst, bw, inst_ty);
4563 const a = try Assignment.start(f, writer, inst_scalar_ctype);4585 const a = try Assignment.start(f, bw, inst_scalar_ctype);
4564 try f.writeCValue(writer, local, .Other);4586 try f.writeCValue(bw, local, .Other);
4565 try v.elem(f, writer);4587 try v.elem(f, bw);
4566 try a.assign(f, writer);4588 try a.assign(f, bw);
4567 // We must convert to and from integer types to prevent UB if the operation4589 // We must convert to and from integer types to prevent UB if the operation
4568 // results in a NULL pointer, or if LHS is NULL. The operation is only UB4590 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
4569 // if the result is NULL and then dereferenced.4591 // if the result is NULL and then dereferenced.
4570 try writer.writeByte('(');4592 try bw.writeByte('(');
4571 try f.renderCType(writer, inst_scalar_ctype);4593 try f.renderCType(bw, inst_scalar_ctype);
4572 try writer.writeAll(")(((uintptr_t)");4594 try bw.writeAll(")(((uintptr_t)");
4573 try f.writeCValue(writer, lhs, .Other);4595 try f.writeCValue(bw, lhs, .Other);
4574 try v.elem(f, writer);4596 try v.elem(f, bw);
4575 try writer.writeAll(") ");4597 try bw.writeAll(") ");
4576 try writer.writeByte(operator);4598 try bw.writeByte(operator);
4577 try writer.writeAll(" (");4599 try bw.writeAll(" (");
4578 try f.writeCValue(writer, rhs, .Other);4600 try f.writeCValue(bw, rhs, .Other);
4579 try v.elem(f, writer);4601 try v.elem(f, bw);
4580 try writer.writeAll("*sizeof(");4602 try bw.writeAll("*sizeof(");
4581 try f.renderType(writer, elem_ty);4603 try f.renderType(bw, elem_ty);
4582 try writer.writeAll(")))");4604 try bw.writeAll(")))");
4583 try a.end(f, writer);4605 try a.end(f, bw);
4584 try v.end(f, inst, writer);4606 try v.end(f, inst, bw);
4585 return local;4607 return local;
4586}4608}
45874609
...@@ -4600,28 +4622,29 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4600,28 +4622,29 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4600 const rhs = try f.resolveInst(bin_op.rhs);4622 const rhs = try f.resolveInst(bin_op.rhs);
4601 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4623 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;
4604 const local = try f.allocLocal(inst, inst_ty);4626 const local = try f.allocLocal(inst, inst_ty);
4605 const v = try Vectorize.start(f, inst, writer, inst_ty);4627 const v = try Vectorize.start(f, inst, bw, inst_ty);
4606 try f.writeCValue(writer, local, .Other);4628 try f.writeCValue(bw, local, .Other);
4607 try v.elem(f, writer);4629 try v.elem(f, bw);
4608 // (lhs <> rhs) ? lhs : rhs4630 // (lhs <> rhs) ? lhs : rhs
4609 try writer.writeAll(" = (");4631 try bw.writeAll(" = (");
4610 try f.writeCValue(writer, lhs, .Other);4632 try f.writeCValue(bw, lhs, .Other);
4611 try v.elem(f, writer);4633 try v.elem(f, bw);
4612 try writer.writeByte(' ');4634 try bw.writeByte(' ');
4613 try writer.writeByte(operator);4635 try bw.writeByte(operator);
4614 try writer.writeByte(' ');4636 try bw.writeByte(' ');
4615 try f.writeCValue(writer, rhs, .Other);4637 try f.writeCValue(bw, rhs, .Other);
4616 try v.elem(f, writer);4638 try v.elem(f, bw);
4617 try writer.writeAll(") ? ");4639 try bw.writeAll(") ? ");
4618 try f.writeCValue(writer, lhs, .Other);4640 try f.writeCValue(bw, lhs, .Other);
4619 try v.elem(f, writer);4641 try v.elem(f, bw);
4620 try writer.writeAll(" : ");4642 try bw.writeAll(" : ");
4621 try f.writeCValue(writer, rhs, .Other);4643 try f.writeCValue(bw, rhs, .Other);
4622 try v.elem(f, writer);4644 try v.elem(f, bw);
4623 try writer.writeAll(";\n");4645 try bw.writeByte(';');
4624 try v.end(f, inst, writer);4646 try f.object.newline();
4647 try v.end(f, inst, bw);
46254648
4626 return local;4649 return local;
4627}4650}
...@@ -4639,21 +4662,21 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4639,21 +4662,21 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4639 const inst_ty = f.typeOfIndex(inst);4662 const inst_ty = f.typeOfIndex(inst);
4640 const ptr_ty = inst_ty.slicePtrFieldType(zcu);4663 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
46414664
4642 const writer = f.object.writer();4665 const bw = &f.object.code.buffered_writer;
4643 const local = try f.allocLocal(inst, inst_ty);4666 const local = try f.allocLocal(inst, inst_ty);
4644 {4667 {
4645 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));4668 const a = try Assignment.start(f, bw, try f.ctypeFromType(ptr_ty, .complete));
4646 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });4669 try f.writeCValueMember(bw, local, .{ .identifier = "ptr" });
4647 try a.assign(f, writer);4670 try a.assign(f, bw);
4648 try f.writeCValue(writer, ptr, .Other);4671 try f.writeCValue(bw, ptr, .Other);
4649 try a.end(f, writer);4672 try a.end(f, bw);
4650 }4673 }
4651 {4674 {
4652 const a = try Assignment.start(f, writer, .usize);4675 const a = try Assignment.start(f, bw, .usize);
4653 try f.writeCValueMember(writer, local, .{ .identifier = "len" });4676 try f.writeCValueMember(bw, local, .{ .identifier = "len" });
4654 try a.assign(f, writer);4677 try a.assign(f, bw);
4655 try f.writeCValue(writer, len, .Other);4678 try f.writeCValue(bw, len, .Other);
4656 try a.end(f, writer);4679 try a.end(f, bw);
4657 }4680 }
4658 return local;4681 return local;
4659}4682}
...@@ -4670,7 +4693,7 @@ fn airCall(...@@ -4670,7 +4693,7 @@ fn airCall(
4670 if (f.object.dg.is_naked_fn) return .none;4693 if (f.object.dg.is_naked_fn) return .none;
46714694
4672 const gpa = f.object.dg.gpa;4695 const gpa = f.object.dg.gpa;
4673 const writer = f.object.writer();4696 const bw = &f.object.code.buffered_writer;
46744697
4675 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4698 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4676 const extra = f.air.extraData(Air.Call, pl_op.payload);4699 const extra = f.air.extraData(Air.Call, pl_op.payload);
...@@ -4691,13 +4714,14 @@ fn airCall(...@@ -4691,13 +4714,14 @@ fn airCall(
4691 .ctype = arg_ctype,4714 .ctype = arg_ctype,
4692 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),4715 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),
4693 });4716 });
4694 try writer.writeAll("memcpy(");4717 try bw.writeAll("memcpy(");
4695 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });4718 try f.writeCValueMember(bw, array_local, .{ .identifier = "array" });
4696 try writer.writeAll(", ");4719 try bw.writeAll(", ");
4697 try f.writeCValue(writer, resolved_arg.*, .FunctionArgument);4720 try f.writeCValue(bw, resolved_arg.*, .FunctionArgument);
4698 try writer.writeAll(", sizeof(");4721 try bw.writeAll(", sizeof(");
4699 try f.renderCType(writer, arg_ctype);4722 try f.renderCType(bw, arg_ctype);
4700 try writer.writeAll("));\n");4723 try bw.writeAll("));");
4724 try f.object.newline();
4701 resolved_arg.* = array_local;4725 resolved_arg.* = array_local;
4702 }4726 }
4703 }4727 }
...@@ -4725,22 +4749,22 @@ fn airCall(...@@ -4725,22 +4749,22 @@ fn airCall(
47254749
4726 const result_local = result: {4750 const result_local = result: {
4727 if (modifier == .always_tail) {4751 if (modifier == .always_tail) {
4728 try writer.writeAll("zig_always_tail return ");4752 try bw.writeAll("zig_always_tail return ");
4729 break :result .none;4753 break :result .none;
4730 } else if (ret_ctype.index == .void) {4754 } else if (ret_ctype.index == .void) {
4731 break :result .none;4755 break :result .none;
4732 } else if (f.liveness.isUnused(inst)) {4756 } else if (f.liveness.isUnused(inst)) {
4733 try writer.writeByte('(');4757 try bw.writeByte('(');
4734 try f.renderCType(writer, .void);4758 try f.renderCType(bw, .void);
4735 try writer.writeByte(')');4759 try bw.writeByte(')');
4736 break :result .none;4760 break :result .none;
4737 } else {4761 } else {
4738 const local = try f.allocAlignedLocal(inst, .{4762 const local = try f.allocAlignedLocal(inst, .{
4739 .ctype = ret_ctype,4763 .ctype = ret_ctype,
4740 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),4764 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
4741 });4765 });
4742 try f.writeCValue(writer, local, .Other);4766 try f.writeCValue(bw, local, .Other);
4743 try writer.writeAll(" = ");4767 try bw.writeAll(" = ");
4744 break :result local;4768 break :result local;
4745 }4769 }
4746 };4770 };
...@@ -4760,17 +4784,17 @@ fn airCall(...@@ -4760,17 +4784,17 @@ fn airCall(
4760 else => break :known,4784 else => break :known,
4761 };4785 };
4762 if (need_cast) {4786 if (need_cast) {
4763 try writer.writeAll("((");4787 try bw.writeAll("((");
4764 try f.renderType(writer, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));4788 try f.renderType(bw, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));
4765 try writer.writeByte(')');4789 try bw.writeByte(')');
4766 if (!callee_is_ptr) try writer.writeByte('&');4790 if (!callee_is_ptr) try bw.writeByte('&');
4767 }4791 }
4768 switch (modifier) {4792 switch (modifier) {
4769 .auto, .always_tail => try f.object.dg.renderNavName(writer, fn_nav),4793 .auto, .always_tail => try f.object.dg.renderNavName(bw, fn_nav),
4770 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),4794 inline .never_tail, .never_inline => |m| try bw.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
4771 else => unreachable,4795 else => unreachable,
4772 }4796 }
4773 if (need_cast) try writer.writeByte(')');4797 if (need_cast) try bw.writeByte(')');
4774 break :callee;4798 break :callee;
4775 }4799 }
4776 switch (modifier) {4800 switch (modifier) {
...@@ -4780,32 +4804,34 @@ fn airCall(...@@ -4780,32 +4804,34 @@ fn airCall(
4780 else => unreachable,4804 else => unreachable,
4781 }4805 }
4782 // Fall back to function pointer call.4806 // Fall back to function pointer call.
4783 try f.writeCValue(writer, callee, .Other);4807 try f.writeCValue(bw, callee, .Other);
4784 }4808 }
47854809
4786 try writer.writeByte('(');4810 try bw.writeByte('(');
4787 var need_comma = false;4811 var need_comma = false;
4788 for (resolved_args) |resolved_arg| {4812 for (resolved_args) |resolved_arg| {
4789 if (resolved_arg == .none) continue;4813 if (resolved_arg == .none) continue;
4790 if (need_comma) try writer.writeAll(", ");4814 if (need_comma) try bw.writeAll(", ");
4791 need_comma = true;4815 need_comma = true;
4792 try f.writeCValue(writer, resolved_arg, .FunctionArgument);4816 try f.writeCValue(bw, resolved_arg, .FunctionArgument);
4793 try f.freeCValue(inst, resolved_arg);4817 try f.freeCValue(inst, resolved_arg);
4794 }4818 }
4795 try writer.writeAll(");\n");4819 try bw.writeAll(");");
4820 try f.object.newline();
47964821
4797 const result = result: {4822 const result = result: {
4798 if (result_local == .none or !lowersToArray(ret_ty, pt))4823 if (result_local == .none or !lowersToArray(ret_ty, pt))
4799 break :result result_local;4824 break :result result_local;
48004825
4801 const array_local = try f.allocLocal(inst, ret_ty);4826 const array_local = try f.allocLocal(inst, ret_ty);
4802 try writer.writeAll("memcpy(");4827 try bw.writeAll("memcpy(");
4803 try f.writeCValue(writer, array_local, .FunctionArgument);4828 try f.writeCValue(bw, array_local, .FunctionArgument);
4804 try writer.writeAll(", ");4829 try bw.writeAll(", ");
4805 try f.writeCValueMember(writer, result_local, .{ .identifier = "array" });4830 try f.writeCValueMember(bw, result_local, .{ .identifier = "array" });
4806 try writer.writeAll(", sizeof(");4831 try bw.writeAll(", sizeof(");
4807 try f.renderType(writer, ret_ty);4832 try f.renderType(bw, ret_ty);
4808 try writer.writeAll("));\n");4833 try bw.writeAll("));");
4834 try f.object.newline();
4809 try freeLocal(f, inst, result_local.new_local, null);4835 try freeLocal(f, inst, result_local.new_local, null);
4810 break :result array_local;4836 break :result array_local;
4811 };4837 };
...@@ -4815,7 +4841,7 @@ fn airCall(...@@ -4815,7 +4841,7 @@ fn airCall(
48154841
4816fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {4842fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4817 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;4843 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;
4819 // TODO re-evaluate whether to emit these or not. If we naively emit4845 // TODO re-evaluate whether to emit these or not. If we naively emit
4820 // these directives, the output file will report bogus line numbers because4846 // these directives, the output file will report bogus line numbers because
4821 // every newline after the #line directive adds one to the line.4847 // every newline after the #line directive adds one to the line.
...@@ -4823,13 +4849,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4823,13 +4849,16 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4823 // If we wanted to go this route, we would need to go all the way and not output4849 // If we wanted to go this route, we would need to go all the way and not output
4824 // newlines until the next dbg_stmt occurs.4850 // newlines until the next dbg_stmt occurs.
4825 // Perhaps an additional compilation option is in order?4851 // Perhaps an additional compilation option is in order?
4826 //try writer.print("#line {d}\n", .{dbg_stmt.line + 1});4852 //try bw.print("#line {d}", .{dbg_stmt.line + 1});
4827 try writer.print("/* file:{d}:{d} */\n", .{ dbg_stmt.line + 1, dbg_stmt.column + 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();
4828 return .none;4856 return .none;
4829}4857}
48304858
4831fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {4859fn 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();
4833 return .none;4862 return .none;
4834}4863}
48354864
...@@ -4841,7 +4870,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4841,7 +4870,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4841 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4870 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4842 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);4871 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);
4843 const writer = f.object.writer();4872 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)});
4845 return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]));4874 return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]));
4846}4875}
48474876
...@@ -4855,8 +4884,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4855,8 +4884,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4855 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4884 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
48564885
4857 try reap(f, inst, &.{pl_op.operand});4886 try reap(f, inst, &.{pl_op.operand});
4858 const writer = f.object.writer();4887 const bw = &f.object.code.buffered_writer;
4859 try writer.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) });4888 try bw.print("/* {s}:{s} */", .{ @tagName(tag), name.toSlice(f.air) });
4889 try f.object.newline();
4860 return .none;4890 return .none;
4861}4891}
48624892
...@@ -4873,7 +4903,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4873,7 +4903,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
48734903
4874 const block_id = f.next_block_index;4904 const block_id = f.next_block_index;
4875 f.next_block_index += 1;4905 f.next_block_index += 1;
4876 const writer = f.object.writer();4906 const bw = &f.object.code.buffered_writer;
48774907
4878 const inst_ty = f.typeOfIndex(inst);4908 const inst_ty = f.typeOfIndex(inst);
4879 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))4909 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)...@@ -4895,7 +4925,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
4895 try die(f, inst, death.toRef());4925 try die(f, inst, death.toRef());
4896 }4926 }
48974927
4898 try f.object.indent_writer.insertNewline();4928 try f.object.newline();
48994929
4900 // noreturn blocks have no `br` instructions reaching them, so we don't want a label4930 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4901 if (f.object.dg.is_naked_fn) {4931 if (f.object.dg.is_naked_fn) {
...@@ -4906,7 +4936,8 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4906,7 +4936,8 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
4906 }4936 }
4907 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {4937 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
4908 // label must be followed by an expression, include an empty one.4938 // 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();
4910 }4941 }
49114942
4912 return result;4943 return result;
...@@ -4943,31 +4974,31 @@ fn lowerTry(...@@ -4943,31 +4974,31 @@ fn lowerTry(
4943 const err_union = try f.resolveInst(operand);4974 const err_union = try f.resolveInst(operand);
4944 const inst_ty = f.typeOfIndex(inst);4975 const inst_ty = f.typeOfIndex(inst);
4945 const liveness_condbr = f.liveness.getCondBr(inst);4976 const liveness_condbr = f.liveness.getCondBr(inst);
4946 const writer = f.object.writer();4977 const bw = &f.object.code.buffered_writer;
4947 const payload_ty = err_union_ty.errorUnionPayload(zcu);4978 const payload_ty = err_union_ty.errorUnionPayload(zcu);
4948 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);4979 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
49494980
4950 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {4981 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4951 try writer.writeAll("if (");4982 try bw.writeAll("if (");
4952 if (!payload_has_bits) {4983 if (!payload_has_bits) {
4953 if (is_ptr)4984 if (is_ptr)
4954 try f.writeCValueDeref(writer, err_union)4985 try f.writeCValueDeref(bw, err_union)
4955 else4986 else
4956 try f.writeCValue(writer, err_union, .Other);4987 try f.writeCValue(bw, err_union, .Other);
4957 } else {4988 } else {
4958 // Reap the operand so that it can be reused inside genBody.4989 // Reap the operand so that it can be reused inside genBody.
4959 // Remember we must avoid calling reap() twice for the same operand4990 // Remember we must avoid calling reap() twice for the same operand
4960 // in this function.4991 // in this function.
4961 try reap(f, inst, &.{operand});4992 try reap(f, inst, &.{operand});
4962 if (is_ptr)4993 if (is_ptr)
4963 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })4994 try f.writeCValueDerefMember(bw, err_union, .{ .identifier = "error" })
4964 else4995 else
4965 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });4996 try f.writeCValueMember(bw, err_union, .{ .identifier = "error" });
4966 }4997 }
4967 try writer.writeAll(") ");4998 try bw.writeAll(") ");
49684999
4969 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);5000 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);
4970 try f.object.indent_writer.insertNewline();5001 try f.object.newline();
4971 if (f.object.dg.expected_block) |_|5002 if (f.object.dg.expected_block) |_|
4972 return f.fail("runtime code not allowed in naked function", .{});5003 return f.fail("runtime code not allowed in naked function", .{});
4973 }5004 }
...@@ -4990,14 +5021,14 @@ fn lowerTry(...@@ -4990,14 +5021,14 @@ fn lowerTry(
4990 if (f.liveness.isUnused(inst)) return .none;5021 if (f.liveness.isUnused(inst)) return .none;
49915022
4992 const local = try f.allocLocal(inst, inst_ty);5023 const local = try f.allocLocal(inst, inst_ty);
4993 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));5024 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
4994 try f.writeCValue(writer, local, .Other);5025 try f.writeCValue(bw, local, .Other);
4995 try a.assign(f, writer);5026 try a.assign(f, bw);
4996 if (is_ptr) {5027 if (is_ptr) {
4997 try writer.writeByte('&');5028 try bw.writeByte('&');
4998 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });5029 try f.writeCValueDerefMember(bw, err_union, .{ .identifier = "payload" });
4999 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });5030 } else try f.writeCValueMember(bw, err_union, .{ .identifier = "payload" });
5000 try a.end(f, writer);5031 try a.end(f, bw);
5001 return local;5032 return local;
5002}5033}
50035034
...@@ -5005,7 +5036,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5005,7 +5036,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
5005 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;5036 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
5006 const block = f.blocks.get(branch.block_inst).?;5037 const block = f.blocks.get(branch.block_inst).?;
5007 const result = block.result;5038 const result = block.result;
5008 const writer = f.object.writer();5039 const bw = &f.object.code.buffered_writer;
50095040
5010 if (f.object.dg.is_naked_fn) {5041 if (f.object.dg.is_naked_fn) {
5011 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});5042 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 {...@@ -5019,27 +5050,28 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
5019 const operand = try f.resolveInst(branch.operand);5050 const operand = try f.resolveInst(branch.operand);
5020 try reap(f, inst, &.{branch.operand});5051 try reap(f, inst, &.{branch.operand});
50215052
5022 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));5053 const a = try Assignment.start(f, bw, try f.ctypeFromType(operand_ty, .complete));
5023 try f.writeCValue(writer, result, .Other);5054 try f.writeCValue(bw, result, .Other);
5024 try a.assign(f, writer);5055 try a.assign(f, bw);
5025 try f.writeCValue(writer, operand, .Other);5056 try f.writeCValue(bw, operand, .Other);
5026 try a.end(f, writer);5057 try a.end(f, bw);
5027 }5058 }
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();
5030}5062}
50315063
5032fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {5064fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {
5033 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;5065 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
5034 const writer = f.object.writer();5066 try f.object.code.buffered_writer.print("goto zig_loop_{d};", .{@intFromEnum(repeat.loop_inst)});
5035 try writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});5067 try f.object.newline();
5036}5068}
50375069
5038fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {5070fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
5039 const pt = f.object.dg.pt;5071 const pt = f.object.dg.pt;
5040 const zcu = pt.zcu;5072 const zcu = pt.zcu;
5041 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;5073 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
5044 if (try f.air.value(br.operand, pt)) |cond_val| {5076 if (try f.air.value(br.operand, pt)) |cond_val| {
5045 // Comptime-known dispatch. Iterate the cases to find the correct5077 // Comptime-known dispatch. Iterate the cases to find the correct
...@@ -5061,18 +5093,20 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {...@@ -5061,18 +5093,20 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
5061 }5093 }
5062 }5094 }
5063 } else switch_br.cases_len;5095 } 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();
5065 return;5098 return;
5066 }5099 }
50675100
5068 // Runtime-known dispatch. Set the switch condition, and branch back.5101 // Runtime-known dispatch. Set the switch condition, and branch back.
5069 const cond = try f.resolveInst(br.operand);5102 const cond = try f.resolveInst(br.operand);
5070 const cond_local = f.loop_switch_conds.get(br.block_inst).?;5103 const cond_local = f.loop_switch_conds.get(br.block_inst).?;
5071 try f.writeCValue(writer, .{ .local = cond_local }, .Other);5104 try f.writeCValue(bw, .{ .local = cond_local }, .Other);
5072 try writer.writeAll(" = ");5105 try bw.writeAll(" = ");
5073 try f.writeCValue(writer, cond, .Other);5106 try f.writeCValue(bw, cond, .Other);
5074 try writer.writeAll(";\n");5107 try bw.writeByte(';');
5075 try writer.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});5108 try f.object.newline();
5109 try bw.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});
5076}5110}
50775111
5078fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {5112fn 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...@@ -5092,7 +5126,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5092 const zcu = pt.zcu;5126 const zcu = pt.zcu;
5093 const target = &f.object.dg.mod.resolved_target.result;5127 const target = &f.object.dg.mod.resolved_target.result;
5094 const ctype_pool = &f.object.dg.ctype_pool;5128 const ctype_pool = &f.object.dg.ctype_pool;
5095 const writer = f.object.writer();5129 const bw = &f.object.code.buffered_writer;
50965130
5097 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {5131 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
5098 const src_info = dest_ty.intInfo(zcu);5132 const src_info = dest_ty.intInfo(zcu);
...@@ -5103,35 +5137,44 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5103,35 +5137,44 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
51035137
5104 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {5138 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {
5105 const local = try f.allocLocal(null, dest_ty);5139 const local = try f.allocLocal(null, dest_ty);
5106 try f.writeCValue(writer, local, .Other);5140 try f.writeCValue(bw, local, .Other);
5107 try writer.writeAll(" = (");5141 try bw.writeAll(" = (");
5108 try f.renderType(writer, dest_ty);5142 try f.renderType(bw, dest_ty);
5109 try writer.writeByte(')');5143 try bw.writeByte(')');
5110 try f.writeCValue(writer, operand, .Other);5144 try f.writeCValue(bw, operand, .Other);
5111 try writer.writeAll(";\n");5145 try bw.writeByte(';');
5146 try f.object.newline();
5112 return local;5147 return local;
5113 }5148 }
51145149
5115 const operand_lval = if (operand == .constant) blk: {5150 const operand_lval = if (operand == .constant) blk: {
5116 const operand_local = try f.allocLocal(null, operand_ty);5151 const operand_local = try f.allocLocal(null, operand_ty);
5117 try f.writeCValue(writer, operand_local, .Other);5152 try f.writeCValue(bw, operand_local, .Other);
5118 try writer.writeAll(" = ");5153 if (operand_ty.isAbiInt(zcu)) {
5119 try f.writeCValue(writer, operand, .Other);5154 try bw.writeAll(" = ");
5120 try writer.writeAll(";\n");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();
5121 break :blk operand_local;5163 break :blk operand_local;
5122 } else operand;5164 } else operand;
51235165
5124 const local = try f.allocLocal(null, dest_ty);5166 const local = try f.allocLocal(null, dest_ty);
5125 try writer.writeAll("memcpy(&");5167 try bw.writeAll("memcpy(&");
5126 try f.writeCValue(writer, local, .Other);5168 try f.writeCValue(bw, local, .Other);
5127 try writer.writeAll(", &");5169 try bw.writeAll(", &");
5128 try f.writeCValue(writer, operand_lval, .Other);5170 try f.writeCValue(bw, operand_lval, .Other);
5129 try writer.writeAll(", sizeof(");5171 try bw.writeAll(", sizeof(");
5130 try f.renderType(5172 try f.renderType(
5131 writer,5173 bw,
5132 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,5174 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,
5133 );5175 );
5134 try writer.writeAll("));\n");5176 try bw.writeAll("));");
5177 try f.object.newline();
51355178
5136 // Ensure padding bits have the expected value.5179 // Ensure padding bits have the expected value.
5137 if (dest_ty.isAbiInt(zcu)) {5180 if (dest_ty.isAbiInt(zcu)) {
...@@ -5141,11 +5184,11 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5141,11 +5184,11 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5141 var wrap_ctype: ?CType = null;5184 var wrap_ctype: ?CType = null;
5142 var need_bitcasts = false;5185 var need_bitcasts = false;
51435186
5144 try f.writeCValue(writer, local, .Other);5187 try f.writeCValue(bw, local, .Other);
5145 switch (dest_ctype.info(ctype_pool)) {5188 switch (dest_ctype.info(ctype_pool)) {
5146 else => {},5189 else => {},
5147 .array => |array_info| {5190 .array => |array_info| {
5148 try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) {5191 try bw.print("[{d}]", .{switch (target.cpu.arch.endian()) {
5149 .little => array_info.len - 1,5192 .little => array_info.len - 1,
5150 .big => 0,5193 .big => 0,
5151 }});5194 }});
...@@ -5156,92 +5199,99 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5156,92 +5199,99 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5156 bits += 1;5199 bits += 1;
5157 },5200 },
5158 }5201 }
5159 try writer.writeAll(" = ");5202 try bw.writeAll(" = ");
5160 if (need_bitcasts) {5203 if (need_bitcasts) {
5161 try writer.writeAll("zig_bitCast_");5204 try bw.writeAll("zig_bitCast_");
5162 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?.toUnsigned());5205 try f.object.dg.renderCTypeForBuiltinFnName(bw, wrap_ctype.?.toUnsigned());
5163 try writer.writeByte('(');5206 try bw.writeByte('(');
5164 }5207 }
5165 try writer.writeAll("zig_wrap_");5208 try bw.writeAll("zig_wrap_");
5166 const info_ty = try pt.intType(dest_info.signedness, bits);5209 const info_ty = try pt.intType(dest_info.signedness, bits);
5167 if (wrap_ctype) |ctype|5210 if (wrap_ctype) |ctype|
5168 try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype)5211 try f.object.dg.renderCTypeForBuiltinFnName(bw, ctype)
5169 else5212 else
5170 try f.object.dg.renderTypeForBuiltinFnName(writer, info_ty);5213 try f.object.dg.renderTypeForBuiltinFnName(bw, info_ty);
5171 try writer.writeByte('(');5214 try bw.writeByte('(');
5172 if (need_bitcasts) {5215 if (need_bitcasts) {
5173 try writer.writeAll("zig_bitCast_");5216 try bw.writeAll("zig_bitCast_");
5174 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?);5217 try f.object.dg.renderCTypeForBuiltinFnName(bw, wrap_ctype.?);
5175 try writer.writeByte('(');5218 try bw.writeByte('(');
5176 }5219 }
5177 try f.writeCValue(writer, local, .Other);5220 try f.writeCValue(bw, local, .Other);
5178 switch (dest_ctype.info(ctype_pool)) {5221 switch (dest_ctype.info(ctype_pool)) {
5179 else => {},5222 else => {},
5180 .array => |array_info| try writer.print("[{d}]", .{5223 .array => |array_info| try bw.print("[{d}]", .{
5181 switch (target.cpu.arch.endian()) {5224 switch (target.cpu.arch.endian()) {
5182 .little => array_info.len - 1,5225 .little => array_info.len - 1,
5183 .big => 0,5226 .big => 0,
5184 },5227 },
5185 }),5228 }),
5186 }5229 }
5187 if (need_bitcasts) try writer.writeByte(')');5230 if (need_bitcasts) try bw.writeByte(')');
5188 try f.object.dg.renderBuiltinInfo(writer, info_ty, .bits);5231 try f.object.dg.renderBuiltinInfo(bw, info_ty, .bits);
5189 if (need_bitcasts) try writer.writeByte(')');5232 if (need_bitcasts) try bw.writeByte(')');
5190 try writer.writeAll(");\n");5233 try bw.writeAll(");");
5234 try f.object.newline();
5191 }5235 }
51925236
5193 try f.freeCValue(null, operand_lval);5237 try f.freeCValue(null, operand_lval);
5194 return local;5238 return local;
5195}5239}
51965240
5197fn airTrap(f: *Function, writer: anytype) !void {5241fn airTrap(f: *Function, bw: *std.io.BufferedWriter) !void {
5198 // Not even allowed to call trap in a naked function.5242 // Not even allowed to call trap in a naked function.
5199 if (f.object.dg.is_naked_fn) return;5243 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();
5201}5246}
52025247
5203fn airBreakpoint(writer: anytype) !CValue {5248fn airBreakpoint(o: *Object, bw: *std.io.BufferedWriter) !CValue {
5204 try writer.writeAll("zig_breakpoint();\n");5249 try bw.writeAll("zig_breakpoint();");
5250 try o.newline();
5205 return .none;5251 return .none;
5206}5252}
52075253
5208fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {5254fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
5209 const writer = f.object.writer();5255 const bw = &f.object.code.buffered_writer;
5210 const local = try f.allocLocal(inst, .usize);5256 const local = try f.allocLocal(inst, .usize);
5211 try f.writeCValue(writer, local, .Other);5257 try f.writeCValue(bw, local, .Other);
5212 try writer.writeAll(" = (");5258 try bw.writeAll(" = (");
5213 try f.renderType(writer, .usize);5259 try f.renderType(bw, .usize);
5214 try writer.writeAll(")zig_return_address();\n");5260 try bw.writeAll(")zig_return_address();");
5261 try f.object.newline();
5215 return local;5262 return local;
5216}5263}
52175264
5218fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {5265fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
5219 const writer = f.object.writer();5266 const bw = &f.object.code.buffered_writer;
5220 const local = try f.allocLocal(inst, .usize);5267 const local = try f.allocLocal(inst, .usize);
5221 try f.writeCValue(writer, local, .Other);5268 try f.writeCValue(bw, local, .Other);
5222 try writer.writeAll(" = (");5269 try bw.writeAll(" = (");
5223 try f.renderType(writer, .usize);5270 try f.renderType(bw, .usize);
5224 try writer.writeAll(")zig_frame_address();\n");5271 try bw.writeAll(")zig_frame_address();");
5272 try f.object.newline();
5225 return local;5273 return local;
5226}5274}
52275275
5228fn airUnreach(f: *Function) !void {5276fn airUnreach(f: *Function) !void {
5229 // Not even allowed to call unreachable in a naked function.5277 // Not even allowed to call unreachable in a naked function.
5230 if (f.object.dg.is_naked_fn) return;5278 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();
5232}5281}
52335282
5234fn airLoop(f: *Function, inst: Air.Inst.Index) !void {5283fn airLoop(f: *Function, inst: Air.Inst.Index) !void {
5235 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5284 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5236 const loop = f.air.extraData(Air.Block, ty_pl.payload);5285 const loop = f.air.extraData(Air.Block, ty_pl.payload);
5237 const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[loop.end..][0..loop.data.body_len]);5286 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
5240 // `repeat` instructions matching this loop will branch to5289 // `repeat` instructions matching this loop will branch to
5241 // this label. Since we need a label for arbitrary `repeat`5290 // this label. Since we need a label for arbitrary `repeat`
5242 // anyway, there's actually no need to use a "real" looping5291 // anyway, there's actually no need to use a "real" looping
5243 // construct at all!5292 // 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();
5245 try genBodyInner(f, body); // no need to restore state, we're noreturn5295 try genBodyInner(f, body); // no need to restore state, we're noreturn
5246}5296}
52475297
...@@ -5253,14 +5303,14 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5253,14 +5303,14 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
5253 const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]);5303 const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]);
5254 const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);5304 const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);
5255 const liveness_condbr = f.liveness.getCondBr(inst);5305 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 (");5308 try bw.writeAll("if (");
5259 try f.writeCValue(writer, cond, .Other);5309 try f.writeCValue(bw, cond, .Other);
5260 try writer.writeAll(") ");5310 try bw.writeAll(") ");
52615311
5262 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);5312 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
5263 try writer.writeByte('\n');5313 try f.object.newline();
5264 if (else_body.len > 0) if (f.object.dg.expected_block) |_|5314 if (else_body.len > 0) if (f.object.dg.expected_block) |_|
5265 return f.fail("runtime code not allowed in naked function", .{});5315 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...@@ -5286,7 +5336,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5286 const init_condition = try f.resolveInst(switch_br.operand);5336 const init_condition = try f.resolveInst(switch_br.operand);
5287 try reap(f, inst, &.{switch_br.operand});5337 try reap(f, inst, &.{switch_br.operand});
5288 const condition_ty = f.typeOf(switch_br.operand);5338 const condition_ty = f.typeOf(switch_br.operand);
5289 const writer = f.object.writer();5339 const bw = &f.object.code.buffered_writer;
52905340
5291 // For dispatches, we will create a local alloc to contain the condition value.5341 // For dispatches, we will create a local alloc to contain the condition value.
5292 // This may not result in optimal codegen for switch loops, but it minimizes the5342 // 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...@@ -5294,7 +5344,8 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5294 const condition = if (is_dispatch_loop) cond: {5344 const condition = if (is_dispatch_loop) cond: {
5295 const new_local = try f.allocLocal(inst, condition_ty);5345 const new_local = try f.allocLocal(inst, condition_ty);
5296 try f.copyCValue(try f.ctypeFromType(condition_ty, .complete), new_local, init_condition);5346 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();
5298 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);5349 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);
5299 break :cond new_local;5350 break :cond new_local;
5300 } else init_condition;5351 } else init_condition;
...@@ -5303,7 +5354,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5303,7 +5354,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5303 assert(f.loop_switch_conds.remove(inst));5354 assert(f.loop_switch_conds.remove(inst));
5304 };5355 };
53055356
5306 try writer.writeAll("switch (");5357 try bw.writeAll("switch (");
53075358
5308 const lowered_condition_ty: Type = if (condition_ty.toIntern() == .bool_type)5359 const lowered_condition_ty: Type = if (condition_ty.toIntern() == .bool_type)
5309 .u15360 .u1
...@@ -5312,13 +5363,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5312,13 +5363,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5312 else5363 else
5313 condition_ty;5364 condition_ty;
5314 if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {5365 if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {
5315 try writer.writeByte('(');5366 try bw.writeByte('(');
5316 try f.renderType(writer, lowered_condition_ty);5367 try f.renderType(bw, lowered_condition_ty);
5317 try writer.writeByte(')');5368 try bw.writeByte(')');
5318 }5369 }
5319 try f.writeCValue(writer, condition, .Other);5370 try f.writeCValue(bw, condition, .Other);
5320 try writer.writeAll(") {");5371 try bw.writeAll(") {");
5321 f.object.indent_writer.pushIndent();5372 f.object.indent();
53225373
5323 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);5374 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);
5324 defer gpa.free(liveness.deaths);5375 defer gpa.free(liveness.deaths);
...@@ -5331,35 +5382,36 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5331,35 +5382,36 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5331 continue;5382 continue;
5332 }5383 }
5333 for (case.items) |item| {5384 for (case.items) |item| {
5334 try f.object.indent_writer.insertNewline();5385 try f.object.newline();
5335 try writer.writeAll("case ");5386 try bw.writeAll("case ");
5336 const item_value = try f.air.value(item, pt);5387 const item_value = try f.air.value(item, pt);
5337 // If `item_value` is a pointer with a known integer address, print the address5388 // If `item_value` is a pointer with a known integer address, print the address
5338 // with no cast to avoid a warning.5389 // with no cast to avoid a warning.
5339 write_val: {5390 write_val: {
5340 if (condition_ty.isPtrAtRuntime(zcu)) {5391 if (condition_ty.isPtrAtRuntime(zcu)) {
5341 if (item_value.?.getUnsignedInt(zcu)) |item_int| {5392 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))});
5343 break :write_val;5394 break :write_val;
5344 }5395 }
5345 }5396 }
5346 if (condition_ty.isPtrAtRuntime(zcu)) {5397 if (condition_ty.isPtrAtRuntime(zcu)) {
5347 try writer.writeByte('(');5398 try bw.writeByte('(');
5348 try f.renderType(writer, .usize);5399 try f.renderType(bw, .usize);
5349 try writer.writeByte(')');5400 try bw.writeByte(')');
5350 }5401 }
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);
5352 }5403 }
5353 try writer.writeByte(':');5404 try bw.writeByte(':');
5354 }5405 }
5355 try writer.writeAll(" {\n");5406 try bw.writeAll(" {");
5356 f.object.indent_writer.pushIndent();5407 f.object.indent();
5408 try f.object.newline();
5357 if (is_dispatch_loop) {5409 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 });
5359 }5411 }
5360 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);5412 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5361 f.object.indent_writer.popIndent();5413 f.object.outdent();
5362 try writer.writeByte('}');5414 try bw.writeByte('}');
5363 if (f.object.dg.expected_block) |_|5415 if (f.object.dg.expected_block) |_|
5364 return f.fail("runtime code not allowed in naked function", .{});5416 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...@@ -5367,9 +5419,9 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5367 }5419 }
53685420
5369 const else_body = it.elseBody();5421 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: ");
5373 if (any_range_cases) {5425 if (any_range_cases) {
5374 // We will iterate the cases again to handle those with ranges, and generate5426 // We will iterate the cases again to handle those with ranges, and generate
5375 // code using conditions rather than switch cases for such cases.5427 // 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...@@ -5377,40 +5429,41 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5377 while (it.next()) |case| {5429 while (it.next()) |case| {
5378 if (case.ranges.len == 0) continue; // handled above5430 if (case.ranges.len == 0) continue; // handled above
53795431
5380 try writer.writeAll("if (");5432 try bw.writeAll("if (");
5381 for (case.items, 0..) |item, item_i| {5433 for (case.items, 0..) |item, item_i| {
5382 if (item_i != 0) try writer.writeAll(" || ");5434 if (item_i != 0) try bw.writeAll(" || ");
5383 try f.writeCValue(writer, condition, .Other);5435 try f.writeCValue(bw, condition, .Other);
5384 try writer.writeAll(" == ");5436 try bw.writeAll(" == ");
5385 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);5437 try f.object.dg.renderValue(bw, (try f.air.value(item, pt)).?, .Other);
5386 }5438 }
5387 for (case.ranges, 0..) |range, range_i| {5439 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(" || ");
5389 // "(x >= lower && x <= upper)"5441 // "(x >= lower && x <= upper)"
5390 try writer.writeByte('(');5442 try bw.writeByte('(');
5391 try f.writeCValue(writer, condition, .Other);5443 try f.writeCValue(bw, condition, .Other);
5392 try writer.writeAll(" >= ");5444 try bw.writeAll(" >= ");
5393 try f.object.dg.renderValue(writer, (try f.air.value(range[0], pt)).?, .Other);5445 try f.object.dg.renderValue(bw, (try f.air.value(range[0], pt)).?, .Other);
5394 try writer.writeAll(" && ");5446 try bw.writeAll(" && ");
5395 try f.writeCValue(writer, condition, .Other);5447 try f.writeCValue(bw, condition, .Other);
5396 try writer.writeAll(" <= ");5448 try bw.writeAll(" <= ");
5397 try f.object.dg.renderValue(writer, (try f.air.value(range[1], pt)).?, .Other);5449 try f.object.dg.renderValue(bw, (try f.air.value(range[1], pt)).?, .Other);
5398 try writer.writeByte(')');5450 try bw.writeByte(')');
5399 }5451 }
5400 try writer.writeAll(") {\n");5452 try bw.writeAll(") {");
5401 f.object.indent_writer.pushIndent();5453 f.object.indent();
5454 try f.object.newline();
5402 if (is_dispatch_loop) {5455 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 });
5404 }5457 }
5405 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);5458 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5406 f.object.indent_writer.popIndent();5459 f.object.outdent();
5407 try writer.writeByte('}');5460 try bw.writeByte('}');
5408 if (f.object.dg.expected_block) |_|5461 if (f.object.dg.expected_block) |_|
5409 return f.fail("runtime code not allowed in naked function", .{});5462 return f.fail("runtime code not allowed in naked function", .{});
5410 }5463 }
5411 }5464 }
5412 if (is_dispatch_loop) {5465 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 });
5414 }5467 }
5415 if (else_body.len > 0) {5468 if (else_body.len > 0) {
5416 // Note that this must be the last case, so we do not need to use `genBodyResolveState` since5469 // 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...@@ -5422,12 +5475,13 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5422 if (f.object.dg.expected_block) |_|5475 if (f.object.dg.expected_block) |_|
5423 return f.fail("runtime code not allowed in naked function", .{});5476 return f.fail("runtime code not allowed in naked function", .{});
5424 } else {5477 } else {
5425 try writer.writeAll("zig_unreachable();");5478 try bw.writeAll("zig_unreachable();");
5426 }5479 }
5427 try f.object.indent_writer.insertNewline();5480 try f.object.newline();
54285481
5429 f.object.indent_writer.popIndent();5482 f.object.outdent();
5430 try writer.writeAll("}\n");5483 try bw.writeByte('}');
5484 try f.object.newline();
5431}5485}
54325486
5433fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {5487fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
...@@ -5465,7 +5519,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5465,7 +5519,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5465 extra_i += inputs.len;5519 extra_i += inputs.len;
54665520
5467 const result = result: {5521 const result = result: {
5468 const writer = f.object.writer();5522 const bw = &f.object.code.buffered_writer;
5469 const inst_ty = f.typeOfIndex(inst);5523 const inst_ty = f.typeOfIndex(inst);
5470 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {5524 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
5471 const inst_local = try f.allocLocalValue(.{5525 const inst_local = try f.allocLocalValue(.{
...@@ -5473,10 +5527,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5473,10 +5527,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5473 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),5527 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
5474 });5528 });
5475 if (f.wantSafety()) {5529 if (f.wantSafety()) {
5476 try f.writeCValue(writer, inst_local, .Other);5530 try f.writeCValue(bw, inst_local, .Other);
5477 try writer.writeAll(" = ");5531 try bw.writeAll(" = ");
5478 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);5532 try f.writeCValue(bw, .{ .undef = inst_ty }, .Other);
5479 try writer.writeAll(";\n");5533 try bw.writeByte(';');
5534 try f.object.newline();
5480 }5535 }
5481 break :local inst_local;5536 break :local inst_local;
5482 } else .none;5537 } else .none;
...@@ -5500,21 +5555,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5500,21 +5555,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5500 const is_reg = constraint[1] == '{';5555 const is_reg = constraint[1] == '{';
5501 if (is_reg) {5556 if (is_reg) {
5502 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);5557 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
5503 try writer.writeAll("register ");5558 try bw.writeAll("register ");
5504 const output_local = try f.allocLocalValue(.{5559 const output_local = try f.allocLocalValue(.{
5505 .ctype = try f.ctypeFromType(output_ty, .complete),5560 .ctype = try f.ctypeFromType(output_ty, .complete),
5506 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),5561 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
5507 });5562 });
5508 try f.allocs.put(gpa, output_local.new_local, false);5563 try f.allocs.put(gpa, output_local.new_local, false);
5509 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);5564 try f.object.dg.renderTypeAndName(bw, output_ty, output_local, .{}, .none, .complete);
5510 try writer.writeAll(" __asm(\"");5565 try bw.writeAll(" __asm(\"");
5511 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);5566 try bw.writeAll(constraint["={".len .. constraint.len - "}".len]);
5512 try writer.writeAll("\")");5567 try bw.writeAll("\")");
5513 if (f.wantSafety()) {5568 if (f.wantSafety()) {
5514 try writer.writeAll(" = ");5569 try bw.writeAll(" = ");
5515 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);5570 try f.writeCValue(bw, .{ .undef = output_ty }, .Other);
5516 }5571 }
5517 try writer.writeAll(";\n");5572 try bw.writeByte(';');
5573 try f.object.newline();
5518 }5574 }
5519 }5575 }
5520 for (inputs) |input| {5576 for (inputs) |input| {
...@@ -5535,21 +5591,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5535,21 +5591,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5535 const input_val = try f.resolveInst(input);5591 const input_val = try f.resolveInst(input);
5536 if (asmInputNeedsLocal(f, constraint, input_val)) {5592 if (asmInputNeedsLocal(f, constraint, input_val)) {
5537 const input_ty = f.typeOf(input);5593 const input_ty = f.typeOf(input);
5538 if (is_reg) try writer.writeAll("register ");5594 if (is_reg) try bw.writeAll("register ");
5539 const input_local = try f.allocLocalValue(.{5595 const input_local = try f.allocLocalValue(.{
5540 .ctype = try f.ctypeFromType(input_ty, .complete),5596 .ctype = try f.ctypeFromType(input_ty, .complete),
5541 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),5597 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
5542 });5598 });
5543 try f.allocs.put(gpa, input_local.new_local, false);5599 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);
5545 if (is_reg) {5601 if (is_reg) {
5546 try writer.writeAll(" __asm(\"");5602 try bw.writeAll(" __asm(\"");
5547 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);5603 try bw.writeAll(constraint["{".len .. constraint.len - "}".len]);
5548 try writer.writeAll("\")");5604 try bw.writeAll("\")");
5549 }5605 }
5550 try writer.writeAll(" = ");5606 try bw.writeAll(" = ");
5551 try f.writeCValue(writer, input_val, .Other);5607 try f.writeCValue(bw, input_val, .Other);
5552 try writer.writeAll(";\n");5608 try bw.writeByte(';');
5609 try f.object.newline();
5553 }5610 }
5554 }5611 }
5555 for (0..clobbers_len) |_| {5612 for (0..clobbers_len) |_| {
...@@ -5609,14 +5666,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5609,14 +5666,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5609 }5666 }
5610 }5667 }
56115668
5612 try writer.writeAll("__asm");5669 try bw.writeAll("__asm");
5613 if (is_volatile) try writer.writeAll(" volatile");5670 if (is_volatile) try bw.writeAll(" volatile");
5614 try writer.print("({s}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});5671 try bw.print("({fs}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});
5615 }5672 }
56165673
5617 extra_i = constraints_extra_begin;5674 extra_i = constraints_extra_begin;
5618 var locals_index = locals_begin;5675 var locals_index = locals_begin;
5619 try writer.writeByte(':');5676 try bw.writeByte(':');
5620 for (outputs, 0..) |output, index| {5677 for (outputs, 0..) |output, index| {
5621 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);5678 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
5622 const constraint = mem.sliceTo(extra_bytes, 0);5679 const constraint = mem.sliceTo(extra_bytes, 0);
...@@ -5625,22 +5682,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5625,22 +5682,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5625 // for the string, we still use the next u32 for the null terminator.5682 // for the string, we still use the next u32 for the null terminator.
5626 extra_i += (constraint.len + name.len + (2 + 3)) / 4;5683 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56275684
5628 if (index > 0) try writer.writeByte(',');5685 if (index > 0) try bw.writeByte(',');
5629 try writer.writeByte(' ');5686 try bw.writeByte(' ');
5630 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});5687 if (!mem.eql(u8, name, "_")) try bw.print("[{s}]", .{name});
5631 const is_reg = constraint[1] == '{';5688 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)});
5633 if (is_reg) {5690 if (is_reg) {
5634 try f.writeCValue(writer, .{ .local = locals_index }, .Other);5691 try f.writeCValue(bw, .{ .local = locals_index }, .Other);
5635 locals_index += 1;5692 locals_index += 1;
5636 } else if (output == .none) {5693 } else if (output == .none) {
5637 try f.writeCValue(writer, inst_local, .FunctionArgument);5694 try f.writeCValue(bw, inst_local, .FunctionArgument);
5638 } else {5695 } else {
5639 try f.writeCValueDeref(writer, try f.resolveInst(output));5696 try f.writeCValueDeref(bw, try f.resolveInst(output));
5640 }5697 }
5641 try writer.writeByte(')');5698 try bw.writeByte(')');
5642 }5699 }
5643 try writer.writeByte(':');5700 try bw.writeByte(':');
5644 for (inputs, 0..) |input, index| {5701 for (inputs, 0..) |input, index| {
5645 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);5702 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
5646 const constraint = mem.sliceTo(extra_bytes, 0);5703 const constraint = mem.sliceTo(extra_bytes, 0);
...@@ -5649,21 +5706,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5649,21 +5706,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5649 // for the string, we still use the next u32 for the null terminator.5706 // for the string, we still use the next u32 for the null terminator.
5650 extra_i += (constraint.len + name.len + (2 + 3)) / 4;5707 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56515708
5652 if (index > 0) try writer.writeByte(',');5709 if (index > 0) try bw.writeByte(',');
5653 try writer.writeByte(' ');5710 try bw.writeByte(' ');
5654 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});5711 if (!mem.eql(u8, name, "_")) try bw.print("[{s}]", .{name});
56555712
5656 const is_reg = constraint[0] == '{';5713 const is_reg = constraint[0] == '{';
5657 const input_val = try f.resolveInst(input);5714 const input_val = try f.resolveInst(input);
5658 try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});5715 try bw.print("{fs}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
5659 try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {5716 try f.writeCValue(bw, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
5660 const input_local_idx = locals_index;5717 const input_local_idx = locals_index;
5661 locals_index += 1;5718 locals_index += 1;
5662 break :local .{ .local = input_local_idx };5719 break :local .{ .local = input_local_idx };
5663 } else input_val, .Other);5720 } else input_val, .Other);
5664 try writer.writeByte(')');5721 try bw.writeByte(')');
5665 }5722 }
5666 try writer.writeByte(':');5723 try bw.writeByte(':');
5667 for (0..clobbers_len) |clobber_i| {5724 for (0..clobbers_len) |clobber_i| {
5668 const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0);5725 const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0);
5669 // This equation accounts for the fact that even if we have exactly 4 bytes5726 // 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 {...@@ -5672,10 +5729,11 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56725729
5673 if (clobber.len == 0) continue;5730 if (clobber.len == 0) continue;
56745731
5675 if (clobber_i > 0) try writer.writeByte(',');5732 if (clobber_i > 0) try bw.writeByte(',');
5676 try writer.print(" {s}", .{fmtStringLiteral(clobber, null)});5733 try bw.print(" {fs}", .{fmtStringLiteral(clobber, null)});
5677 }5734 }
5678 try writer.writeAll(");\n");5735 try bw.writeAll(");");
5736 try f.object.newline();
56795737
5680 extra_i = constraints_extra_begin;5738 extra_i = constraints_extra_begin;
5681 locals_index = locals_begin;5739 locals_index = locals_begin;
...@@ -5689,14 +5747,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5689,14 +5747,15 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56895747
5690 const is_reg = constraint[1] == '{';5748 const is_reg = constraint[1] == '{';
5691 if (is_reg) {5749 if (is_reg) {
5692 try f.writeCValueDeref(writer, if (output == .none)5750 try f.writeCValueDeref(bw, if (output == .none)
5693 .{ .local_ref = inst_local.new_local }5751 .{ .local_ref = inst_local.new_local }
5694 else5752 else
5695 try f.resolveInst(output));5753 try f.resolveInst(output));
5696 try writer.writeAll(" = ");5754 try bw.writeAll(" = ");
5697 try f.writeCValue(writer, .{ .local = locals_index }, .Other);5755 try f.writeCValue(bw, .{ .local = locals_index }, .Other);
5698 locals_index += 1;5756 locals_index += 1;
5699 try writer.writeAll(";\n");5757 try bw.writeByte(';');
5758 try f.object.newline();
5700 }5759 }
5701 }5760 }
57025761
...@@ -5726,14 +5785,14 @@ fn airIsNull(...@@ -5726,14 +5785,14 @@ fn airIsNull(
5726 const ctype_pool = &f.object.dg.ctype_pool;5785 const ctype_pool = &f.object.dg.ctype_pool;
5727 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5786 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;
5730 const operand = try f.resolveInst(un_op);5789 const operand = try f.resolveInst(un_op);
5731 try reap(f, inst, &.{un_op});5790 try reap(f, inst, &.{un_op});
57325791
5733 const local = try f.allocLocal(inst, .bool);5792 const local = try f.allocLocal(inst, .bool);
5734 const a = try Assignment.start(f, writer, .bool);5793 const a = try Assignment.start(f, bw, .bool);
5735 try f.writeCValue(writer, local, .Other);5794 try f.writeCValue(bw, local, .Other);
5736 try a.assign(f, writer);5795 try a.assign(f, bw);
57375796
5738 const operand_ty = f.typeOf(un_op);5797 const operand_ty = f.typeOf(un_op);
5739 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;5798 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
...@@ -5741,9 +5800,9 @@ fn airIsNull(...@@ -5741,9 +5800,9 @@ fn airIsNull(
5741 const rhs = switch (opt_ctype.info(ctype_pool)) {5800 const rhs = switch (opt_ctype.info(ctype_pool)) {
5742 .basic, .pointer => rhs: {5801 .basic, .pointer => rhs: {
5743 if (is_ptr)5802 if (is_ptr)
5744 try f.writeCValueDeref(writer, operand)5803 try f.writeCValueDeref(bw, operand)
5745 else5804 else
5746 try f.writeCValue(writer, operand, .Other);5805 try f.writeCValue(bw, operand, .Other);
5747 break :rhs if (opt_ctype.isBool())5806 break :rhs if (opt_ctype.isBool())
5748 "true"5807 "true"
5749 else if (opt_ctype.isInteger())5808 else if (opt_ctype.isInteger())
...@@ -5755,24 +5814,24 @@ fn airIsNull(...@@ -5755,24 +5814,24 @@ fn airIsNull(
5755 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {5814 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5756 .is_null, .payload => rhs: {5815 .is_null, .payload => rhs: {
5757 if (is_ptr)5816 if (is_ptr)
5758 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" })5817 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "is_null" })
5759 else5818 else
5760 try f.writeCValueMember(writer, operand, .{ .identifier = "is_null" });5819 try f.writeCValueMember(bw, operand, .{ .identifier = "is_null" });
5761 break :rhs "true";5820 break :rhs "true";
5762 },5821 },
5763 .ptr, .len => rhs: {5822 .ptr, .len => rhs: {
5764 if (is_ptr)5823 if (is_ptr)
5765 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "ptr" })5824 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "ptr" })
5766 else5825 else
5767 try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });5826 try f.writeCValueMember(bw, operand, .{ .identifier = "ptr" });
5768 break :rhs "NULL";5827 break :rhs "NULL";
5769 },5828 },
5770 else => unreachable,5829 else => unreachable,
5771 },5830 },
5772 };5831 };
5773 try writer.writeAll(compareOperatorC(operator));5832 try bw.writeAll(compareOperatorC(operator));
5774 try writer.writeAll(rhs);5833 try bw.writeAll(rhs);
5775 try a.end(f, writer);5834 try a.end(f, bw);
5776 return local;5835 return local;
5777}5836}
57785837
...@@ -5794,16 +5853,16 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue...@@ -5794,16 +5853,16 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue
5794 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5853 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5795 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {5854 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5796 .is_null, .payload => {5855 .is_null, .payload => {
5797 const writer = f.object.writer();5856 const bw = &f.object.code.buffered_writer;
5798 const local = try f.allocLocal(inst, inst_ty);5857 const local = try f.allocLocal(inst, inst_ty);
5799 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));5858 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
5800 try f.writeCValue(writer, local, .Other);5859 try f.writeCValue(bw, local, .Other);
5801 try a.assign(f, writer);5860 try a.assign(f, bw);
5802 if (is_ptr) {5861 if (is_ptr) {
5803 try writer.writeByte('&');5862 try bw.writeByte('&');
5804 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });5863 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
5805 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });5864 } else try f.writeCValueMember(bw, operand, .{ .identifier = "payload" });
5806 try a.end(f, writer);5865 try a.end(f, bw);
5807 return local;5866 return local;
5808 },5867 },
5809 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),5868 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
...@@ -5816,7 +5875,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5816,7 +5875,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5816 const pt = f.object.dg.pt;5875 const pt = f.object.dg.pt;
5817 const zcu = pt.zcu;5876 const zcu = pt.zcu;
5818 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5877 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;
5820 const operand = try f.resolveInst(ty_op.operand);5879 const operand = try f.resolveInst(ty_op.operand);
5821 try reap(f, inst, &.{ty_op.operand});5880 try reap(f, inst, &.{ty_op.operand});
5822 const operand_ty = f.typeOf(ty_op.operand);5881 const operand_ty = f.typeOf(ty_op.operand);
...@@ -5825,40 +5884,40 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5825,40 +5884,40 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5825 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);5884 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);
5826 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {5885 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {
5827 .basic => {5886 .basic => {
5828 const a = try Assignment.start(f, writer, opt_ctype);5887 const a = try Assignment.start(f, bw, opt_ctype);
5829 try f.writeCValueDeref(writer, operand);5888 try f.writeCValueDeref(bw, operand);
5830 try a.assign(f, writer);5889 try a.assign(f, bw);
5831 try f.object.dg.renderValue(writer, Value.false, .Other);5890 try f.object.dg.renderValue(bw, Value.false, .Other);
5832 try a.end(f, writer);5891 try a.end(f, bw);
5833 return .none;5892 return .none;
5834 },5893 },
5835 .pointer => {5894 .pointer => {
5836 if (f.liveness.isUnused(inst)) return .none;5895 if (f.liveness.isUnused(inst)) return .none;
5837 const local = try f.allocLocal(inst, inst_ty);5896 const local = try f.allocLocal(inst, inst_ty);
5838 const a = try Assignment.start(f, writer, opt_ctype);5897 const a = try Assignment.start(f, bw, opt_ctype);
5839 try f.writeCValue(writer, local, .Other);5898 try f.writeCValue(bw, local, .Other);
5840 try a.assign(f, writer);5899 try a.assign(f, bw);
5841 try f.writeCValue(writer, operand, .Other);5900 try f.writeCValue(bw, operand, .Other);
5842 try a.end(f, writer);5901 try a.end(f, bw);
5843 return local;5902 return local;
5844 },5903 },
5845 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5904 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5846 .aggregate => {5905 .aggregate => {
5847 {5906 {
5848 const a = try Assignment.start(f, writer, opt_ctype);5907 const a = try Assignment.start(f, bw, opt_ctype);
5849 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" });5908 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "is_null" });
5850 try a.assign(f, writer);5909 try a.assign(f, bw);
5851 try f.object.dg.renderValue(writer, Value.false, .Other);5910 try f.object.dg.renderValue(bw, Value.false, .Other);
5852 try a.end(f, writer);5911 try a.end(f, bw);
5853 }5912 }
5854 if (f.liveness.isUnused(inst)) return .none;5913 if (f.liveness.isUnused(inst)) return .none;
5855 const local = try f.allocLocal(inst, inst_ty);5914 const local = try f.allocLocal(inst, inst_ty);
5856 const a = try Assignment.start(f, writer, opt_ctype);5915 const a = try Assignment.start(f, bw, opt_ctype);
5857 try f.writeCValue(writer, local, .Other);5916 try f.writeCValue(bw, local, .Other);
5858 try a.assign(f, writer);5917 try a.assign(f, bw);
5859 try writer.writeByte('&');5918 try bw.writeByte('&');
5860 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });5919 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
5861 try a.end(f, writer);5920 try a.end(f, bw);
5862 return local;5921 return local;
5863 },5922 },
5864 }5923 }
...@@ -5966,42 +6025,43 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5966,42 +6025,43 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5966 const field_ptr_val = try f.resolveInst(extra.field_ptr);6025 const field_ptr_val = try f.resolveInst(extra.field_ptr);
5967 try reap(f, inst, &.{extra.field_ptr});6026 try reap(f, inst, &.{extra.field_ptr});
59686027
5969 const writer = f.object.writer();6028 const bw = &f.object.code.buffered_writer;
5970 const local = try f.allocLocal(inst, container_ptr_ty);6029 const local = try f.allocLocal(inst, container_ptr_ty);
5971 try f.writeCValue(writer, local, .Other);6030 try f.writeCValue(bw, local, .Other);
5972 try writer.writeAll(" = (");6031 try bw.writeAll(" = (");
5973 try f.renderType(writer, container_ptr_ty);6032 try f.renderType(bw, container_ptr_ty);
5974 try writer.writeByte(')');6033 try bw.writeByte(')');
59756034
5976 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) {6035 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),
5978 .field => |field| {6037 .field => |field| {
5979 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6038 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59806039
5981 try writer.writeAll("((");6040 try bw.writeAll("((");
5982 try f.renderType(writer, u8_ptr_ty);6041 try f.renderType(bw, u8_ptr_ty);
5983 try writer.writeByte(')');6042 try bw.writeByte(')');
5984 try f.writeCValue(writer, field_ptr_val, .Other);6043 try f.writeCValue(bw, field_ptr_val, .Other);
5985 try writer.writeAll(" - offsetof(");6044 try bw.writeAll(" - offsetof(");
5986 try f.renderType(writer, container_ty);6045 try f.renderType(bw, container_ty);
5987 try writer.writeAll(", ");6046 try bw.writeAll(", ");
5988 try f.writeCValue(writer, field, .Other);6047 try f.writeCValue(bw, field, .Other);
5989 try writer.writeAll("))");6048 try bw.writeAll("))");
5990 },6049 },
5991 .byte_offset => |byte_offset| {6050 .byte_offset => |byte_offset| {
5992 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6051 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59936052
5994 try writer.writeAll("((");6053 try bw.writeAll("((");
5995 try f.renderType(writer, u8_ptr_ty);6054 try f.renderType(bw, u8_ptr_ty);
5996 try writer.writeByte(')');6055 try bw.writeByte(')');
5997 try f.writeCValue(writer, field_ptr_val, .Other);6056 try f.writeCValue(bw, field_ptr_val, .Other);
5998 try writer.print(" - {})", .{6057 try bw.print(" - {f})", .{
5999 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),6058 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),
6000 });6059 });
6001 },6060 },
6002 }6061 }
60036062
6004 try writer.writeAll(";\n");6063 try bw.writeByte(';');
6064 try f.object.newline();
6005 return local;6065 return local;
6006}6066}
60076067
...@@ -6020,33 +6080,34 @@ fn fieldPtr(...@@ -6020,33 +6080,34 @@ fn fieldPtr(
6020 // Ensure complete type definition is visible before accessing fields.6080 // Ensure complete type definition is visible before accessing fields.
6021 _ = try f.ctypeFromType(container_ty, .complete);6081 _ = try f.ctypeFromType(container_ty, .complete);
60226082
6023 const writer = f.object.writer();6083 const bw = &f.object.code.buffered_writer;
6024 const local = try f.allocLocal(inst, field_ptr_ty);6084 const local = try f.allocLocal(inst, field_ptr_ty);
6025 try f.writeCValue(writer, local, .Other);6085 try f.writeCValue(bw, local, .Other);
6026 try writer.writeAll(" = (");6086 try bw.writeAll(" = (");
6027 try f.renderType(writer, field_ptr_ty);6087 try f.renderType(bw, field_ptr_ty);
6028 try writer.writeByte(')');6088 try bw.writeByte(')');
60296089
6030 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) {6090 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),
6032 .field => |field| {6092 .field => |field| {
6033 try writer.writeByte('&');6093 try bw.writeByte('&');
6034 try f.writeCValueDerefMember(writer, container_ptr_val, field);6094 try f.writeCValueDerefMember(bw, container_ptr_val, field);
6035 },6095 },
6036 .byte_offset => |byte_offset| {6096 .byte_offset => |byte_offset| {
6037 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6097 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
60386098
6039 try writer.writeAll("((");6099 try bw.writeAll("((");
6040 try f.renderType(writer, u8_ptr_ty);6100 try f.renderType(bw, u8_ptr_ty);
6041 try writer.writeByte(')');6101 try bw.writeByte(')');
6042 try f.writeCValue(writer, container_ptr_val, .Other);6102 try f.writeCValue(bw, container_ptr_val, .Other);
6043 try writer.print(" + {})", .{6103 try bw.print(" + {f})", .{
6044 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),6104 try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)),
6045 });6105 });
6046 },6106 },
6047 }6107 }
60486108
6049 try writer.writeAll(";\n");6109 try bw.writeByte(';');
6110 try f.object.newline();
6050 return local;6111 return local;
6051}6112}
60526113
...@@ -6066,7 +6127,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6066,7 +6127,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6066 const struct_byval = try f.resolveInst(extra.struct_operand);6127 const struct_byval = try f.resolveInst(extra.struct_operand);
6067 try reap(f, inst, &.{extra.struct_operand});6128 try reap(f, inst, &.{extra.struct_operand});
6068 const struct_ty = f.typeOf(extra.struct_operand);6129 const struct_ty = f.typeOf(extra.struct_operand);
6069 const writer = f.object.writer();6130 const bw = &f.object.code.buffered_writer;
60706131
6071 // Ensure complete type definition is visible before accessing fields.6132 // Ensure complete type definition is visible before accessing fields.
6072 _ = try f.ctypeFromType(struct_ty, .complete);6133 _ = try f.ctypeFromType(struct_ty, .complete);
...@@ -6093,42 +6154,44 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6093,42 +6154,44 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6093 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));6154 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));
60946155
6095 const temp_local = try f.allocLocal(inst, field_int_ty);6156 const temp_local = try f.allocLocal(inst, field_int_ty);
6096 try f.writeCValue(writer, temp_local, .Other);6157 try f.writeCValue(bw, temp_local, .Other);
6097 try writer.writeAll(" = zig_wrap_");6158 try bw.writeAll(" = zig_wrap_");
6098 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);6159 try f.object.dg.renderTypeForBuiltinFnName(bw, field_int_ty);
6099 try writer.writeAll("((");6160 try bw.writeAll("((");
6100 try f.renderType(writer, field_int_ty);6161 try f.renderType(bw, field_int_ty);
6101 try writer.writeByte(')');6162 try bw.writeByte(')');
6102 const cant_cast = int_info.bits > 64;6163 const cant_cast = int_info.bits > 64;
6103 if (cant_cast) {6164 if (cant_cast) {
6104 if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});6165 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_");6166 try bw.writeAll("zig_lo_");
6106 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);6167 try f.object.dg.renderTypeForBuiltinFnName(bw, struct_ty);
6107 try writer.writeByte('(');6168 try bw.writeByte('(');
6108 }6169 }
6109 if (bit_offset > 0) {6170 if (bit_offset > 0) {
6110 try writer.writeAll("zig_shr_");6171 try bw.writeAll("zig_shr_");
6111 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);6172 try f.object.dg.renderTypeForBuiltinFnName(bw, struct_ty);
6112 try writer.writeByte('(');6173 try bw.writeByte('(');
6113 }6174 }
6114 try f.writeCValue(writer, struct_byval, .Other);6175 try f.writeCValue(bw, struct_byval, .Other);
6115 if (bit_offset > 0) try writer.print(", {})", .{6176 if (bit_offset > 0) try bw.print(", {f})", .{
6116 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),6177 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
6117 });6178 });
6118 if (cant_cast) try writer.writeByte(')');6179 if (cant_cast) try bw.writeByte(')');
6119 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);6180 try f.object.dg.renderBuiltinInfo(bw, field_int_ty, .bits);
6120 try writer.writeAll(");\n");6181 try bw.writeAll(");");
6182 try f.object.newline();
6121 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;6183 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;
61226184
6123 const local = try f.allocLocal(inst, inst_ty);6185 const local = try f.allocLocal(inst, inst_ty);
6124 if (local.new_local != temp_local.new_local) {6186 if (local.new_local != temp_local.new_local) {
6125 try writer.writeAll("memcpy(");6187 try bw.writeAll("memcpy(");
6126 try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);6188 try f.writeCValue(bw, .{ .local_ref = local.new_local }, .FunctionArgument);
6127 try writer.writeAll(", ");6189 try bw.writeAll(", ");
6128 try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);6190 try f.writeCValue(bw, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
6129 try writer.writeAll(", sizeof(");6191 try bw.writeAll(", sizeof(");
6130 try f.renderType(writer, inst_ty);6192 try f.renderType(bw, inst_ty);
6131 try writer.writeAll("));\n");6193 try bw.writeAll("));");
6194 try f.object.newline();
6132 }6195 }
6133 try freeLocal(f, inst, temp_local.new_local, null);6196 try freeLocal(f, inst, temp_local.new_local, null);
6134 return local;6197 return local;
...@@ -6149,10 +6212,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6149,10 +6212,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6149 .@"packed" => {6212 .@"packed" => {
6150 const operand_lval = if (struct_byval == .constant) blk: {6213 const operand_lval = if (struct_byval == .constant) blk: {
6151 const operand_local = try f.allocLocal(inst, struct_ty);6214 const operand_local = try f.allocLocal(inst, struct_ty);
6152 try f.writeCValue(writer, operand_local, .Other);6215 try f.writeCValue(bw, operand_local, .Other);
6153 try writer.writeAll(" = ");6216 try bw.writeAll(" = ");
6154 try f.writeCValue(writer, struct_byval, .Other);6217 try f.writeCValue(bw, struct_byval, .Other);
6155 try writer.writeAll(";\n");6218 try bw.writeByte(';');
6219 try f.object.newline();
6156 break :blk operand_local;6220 break :blk operand_local;
6157 } else struct_byval;6221 } else struct_byval;
6158 const local = try f.allocLocal(inst, inst_ty);6222 const local = try f.allocLocal(inst, inst_ty);
...@@ -6163,13 +6227,14 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6163,13 +6227,14 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6163 },6227 },
6164 else => true,6228 else => true,
6165 }) {6229 }) {
6166 try writer.writeAll("memcpy(&");6230 try bw.writeAll("memcpy(&");
6167 try f.writeCValue(writer, local, .Other);6231 try f.writeCValue(bw, local, .Other);
6168 try writer.writeAll(", &");6232 try bw.writeAll(", &");
6169 try f.writeCValue(writer, operand_lval, .Other);6233 try f.writeCValue(bw, operand_lval, .Other);
6170 try writer.writeAll(", sizeof(");6234 try bw.writeAll(", sizeof(");
6171 try f.renderType(writer, inst_ty);6235 try f.renderType(bw, inst_ty);
6172 try writer.writeAll("));\n");6236 try bw.writeAll("));");
6237 try f.object.newline();
6173 }6238 }
6174 try f.freeCValue(inst, operand_lval);6239 try f.freeCValue(inst, operand_lval);
6175 return local;6240 return local;
...@@ -6180,11 +6245,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6180,11 +6245,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6180 };6245 };
61816246
6182 const local = try f.allocLocal(inst, inst_ty);6247 const local = try f.allocLocal(inst, inst_ty);
6183 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6248 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6184 try f.writeCValue(writer, local, .Other);6249 try f.writeCValue(bw, local, .Other);
6185 try a.assign(f, writer);6250 try a.assign(f, bw);
6186 try f.writeCValueMember(writer, struct_byval, field_name);6251 try f.writeCValueMember(bw, struct_byval, field_name);
6187 try a.end(f, writer);6252 try a.end(f, bw);
6188 return local;6253 return local;
6189}6254}
61906255
...@@ -6211,21 +6276,22 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6211,21 +6276,22 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6211 return local;6276 return local;
6212 }6277 }
62136278
6214 const writer = f.object.writer();6279 const bw = &f.object.code.buffered_writer;
6215 try f.writeCValue(writer, local, .Other);6280 try f.writeCValue(bw, local, .Other);
6216 try writer.writeAll(" = ");6281 try bw.writeAll(" = ");
62176282
6218 if (!payload_ty.hasRuntimeBits(zcu))6283 if (!payload_ty.hasRuntimeBits(zcu))
6219 try f.writeCValue(writer, operand, .Other)6284 try f.writeCValue(bw, operand, .Other)
6220 else if (error_ty.errorSetIsEmpty(zcu))6285 else if (error_ty.errorSetIsEmpty(zcu))
6221 try writer.print("{}", .{6286 try bw.print("{f}", .{
6222 try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)),6287 try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)),
6223 })6288 })
6224 else if (operand_is_ptr)6289 else if (operand_is_ptr)
6225 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })6290 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" })
6226 else6291 else
6227 try f.writeCValueMember(writer, operand, .{ .identifier = "error" });6292 try f.writeCValueMember(bw, operand, .{ .identifier = "error" });
6228 try writer.writeAll(";\n");6293 try bw.writeByte(';');
6294 try f.object.newline();
6229 return local;6295 return local;
6230}6296}
62316297
...@@ -6240,29 +6306,30 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -6240,29 +6306,30 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
6240 const operand_ty = f.typeOf(ty_op.operand);6306 const operand_ty = f.typeOf(ty_op.operand);
6241 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;6307 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;
6244 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {6310 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
6245 if (!is_ptr) return .none;6311 if (!is_ptr) return .none;
62466312
6247 const local = try f.allocLocal(inst, inst_ty);6313 const local = try f.allocLocal(inst, inst_ty);
6248 try f.writeCValue(writer, local, .Other);6314 try f.writeCValue(bw, local, .Other);
6249 try writer.writeAll(" = (");6315 try bw.writeAll(" = (");
6250 try f.renderType(writer, inst_ty);6316 try f.renderType(bw, inst_ty);
6251 try writer.writeByte(')');6317 try bw.writeByte(')');
6252 try f.writeCValue(writer, operand, .Other);6318 try f.writeCValue(bw, operand, .Other);
6253 try writer.writeAll(";\n");6319 try bw.writeByte(';');
6320 try f.object.newline();
6254 return local;6321 return local;
6255 }6322 }
62566323
6257 const local = try f.allocLocal(inst, inst_ty);6324 const local = try f.allocLocal(inst, inst_ty);
6258 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6325 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6259 try f.writeCValue(writer, local, .Other);6326 try f.writeCValue(bw, local, .Other);
6260 try a.assign(f, writer);6327 try a.assign(f, bw);
6261 if (is_ptr) {6328 if (is_ptr) {
6262 try writer.writeByte('&');6329 try bw.writeByte('&');
6263 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });6330 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
6264 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });6331 } else try f.writeCValueMember(bw, operand, .{ .identifier = "payload" });
6265 try a.end(f, writer);6332 try a.end(f, bw);
6266 return local;6333 return local;
6267}6334}
62686335
...@@ -6281,21 +6348,21 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6281,21 +6348,21 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
6281 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {6348 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
6282 .is_null, .payload => {6349 .is_null, .payload => {
6283 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);6350 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;
6285 const local = try f.allocLocal(inst, inst_ty);6352 const local = try f.allocLocal(inst, inst_ty);
6286 {6353 {
6287 const a = try Assignment.start(f, writer, .bool);6354 const a = try Assignment.start(f, bw, .bool);
6288 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });6355 try f.writeCValueMember(bw, local, .{ .identifier = "is_null" });
6289 try a.assign(f, writer);6356 try a.assign(f, bw);
6290 try writer.writeAll("false");6357 try bw.writeAll("false");
6291 try a.end(f, writer);6358 try a.end(f, bw);
6292 }6359 }
6293 {6360 {
6294 const a = try Assignment.start(f, writer, operand_ctype);6361 const a = try Assignment.start(f, bw, operand_ctype);
6295 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6362 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6296 try a.assign(f, writer);6363 try a.assign(f, bw);
6297 try f.writeCValue(writer, operand, .Other);6364 try f.writeCValue(bw, operand, .Other);
6298 try a.end(f, writer);6365 try a.end(f, bw);
6299 }6366 }
6300 return local;6367 return local;
6301 },6368 },
...@@ -6317,7 +6384,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6317,7 +6384,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6317 const err = try f.resolveInst(ty_op.operand);6384 const err = try f.resolveInst(ty_op.operand);
6318 try reap(f, inst, &.{ty_op.operand});6385 try reap(f, inst, &.{ty_op.operand});
63196386
6320 const writer = f.object.writer();6387 const bw = &f.object.code.buffered_writer;
6321 const local = try f.allocLocal(inst, inst_ty);6388 const local = try f.allocLocal(inst, inst_ty);
63226389
6323 if (repr_is_err and err == .local and err.local == local.new_local) {6390 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 {...@@ -6326,21 +6393,21 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6326 }6393 }
63276394
6328 if (!repr_is_err) {6395 if (!repr_is_err) {
6329 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));6396 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
6330 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6397 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6331 try a.assign(f, writer);6398 try a.assign(f, bw);
6332 try f.object.dg.renderUndefValue(writer, payload_ty, .Other);6399 try f.object.dg.renderUndefValue(bw, payload_ty, .Other);
6333 try a.end(f, writer);6400 try a.end(f, bw);
6334 }6401 }
6335 {6402 {
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));
6337 if (repr_is_err)6404 if (repr_is_err)
6338 try f.writeCValue(writer, local, .Other)6405 try f.writeCValue(bw, local, .Other)
6339 else6406 else
6340 try f.writeCValueMember(writer, local, .{ .identifier = "error" });6407 try f.writeCValueMember(bw, local, .{ .identifier = "error" });
6341 try a.assign(f, writer);6408 try a.assign(f, bw);
6342 try f.writeCValue(writer, err, .Other);6409 try f.writeCValue(bw, err, .Other);
6343 try a.end(f, writer);6410 try a.end(f, bw);
6344 }6411 }
6345 return local;6412 return local;
6346}6413}
...@@ -6348,7 +6415,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6348,7 +6415,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6348fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {6415fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
6349 const pt = f.object.dg.pt;6416 const pt = f.object.dg.pt;
6350 const zcu = pt.zcu;6417 const zcu = pt.zcu;
6351 const writer = f.object.writer();6418 const bw = &f.object.code.buffered_writer;
6352 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6419 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6353 const inst_ty = f.typeOfIndex(inst);6420 const inst_ty = f.typeOfIndex(inst);
6354 const operand = try f.resolveInst(ty_op.operand);6421 const operand = try f.resolveInst(ty_op.operand);
...@@ -6362,31 +6429,31 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6362,31 +6429,31 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
63626429
6363 // First, set the non-error value.6430 // First, set the non-error value.
6364 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {6431 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
6365 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));6432 const a = try Assignment.start(f, bw, try f.ctypeFromType(operand_ty, .complete));
6366 try f.writeCValueDeref(writer, operand);6433 try f.writeCValueDeref(bw, operand);
6367 try a.assign(f, writer);6434 try a.assign(f, bw);
6368 try writer.print("{}", .{try f.fmtIntLiteral(no_err)});6435 try bw.print("{f}", .{try f.fmtIntLiteral(no_err)});
6369 try a.end(f, writer);6436 try a.end(f, bw);
6370 return .none;6437 return .none;
6371 }6438 }
6372 {6439 {
6373 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_int_ty, .complete));6440 const a = try Assignment.start(f, bw, try f.ctypeFromType(err_int_ty, .complete));
6374 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" });6441 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" });
6375 try a.assign(f, writer);6442 try a.assign(f, bw);
6376 try writer.print("{}", .{try f.fmtIntLiteral(no_err)});6443 try bw.print("{f}", .{try f.fmtIntLiteral(no_err)});
6377 try a.end(f, writer);6444 try a.end(f, bw);
6378 }6445 }
63796446
6380 // Then return the payload pointer (only if it is used)6447 // Then return the payload pointer (only if it is used)
6381 if (f.liveness.isUnused(inst)) return .none;6448 if (f.liveness.isUnused(inst)) return .none;
63826449
6383 const local = try f.allocLocal(inst, inst_ty);6450 const local = try f.allocLocal(inst, inst_ty);
6384 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6451 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
6385 try f.writeCValue(writer, local, .Other);6452 try f.writeCValue(bw, local, .Other);
6386 try a.assign(f, writer);6453 try a.assign(f, bw);
6387 try writer.writeByte('&');6454 try bw.writeByte('&');
6388 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });6455 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "payload" });
6389 try a.end(f, writer);6456 try a.end(f, bw);
6390 return local;6457 return local;
6391}6458}
63926459
...@@ -6417,24 +6484,24 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6417,24 +6484,24 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
6417 const err_ty = inst_ty.errorUnionSet(zcu);6484 const err_ty = inst_ty.errorUnionSet(zcu);
6418 try reap(f, inst, &.{ty_op.operand});6485 try reap(f, inst, &.{ty_op.operand});
64196486
6420 const writer = f.object.writer();6487 const bw = &f.object.code.buffered_writer;
6421 const local = try f.allocLocal(inst, inst_ty);6488 const local = try f.allocLocal(inst, inst_ty);
6422 if (!repr_is_err) {6489 if (!repr_is_err) {
6423 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));6490 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
6424 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6491 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6425 try a.assign(f, writer);6492 try a.assign(f, bw);
6426 try f.writeCValue(writer, payload, .Other);6493 try f.writeCValue(bw, payload, .Other);
6427 try a.end(f, writer);6494 try a.end(f, bw);
6428 }6495 }
6429 {6496 {
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));
6431 if (repr_is_err)6498 if (repr_is_err)
6432 try f.writeCValue(writer, local, .Other)6499 try f.writeCValue(bw, local, .Other)
6433 else6500 else
6434 try f.writeCValueMember(writer, local, .{ .identifier = "error" });6501 try f.writeCValueMember(bw, local, .{ .identifier = "error" });
6435 try a.assign(f, writer);6502 try a.assign(f, bw);
6436 try f.object.dg.renderValue(writer, try pt.intValue(try pt.errorIntType(), 0), .Other);6503 try f.object.dg.renderValue(bw, try pt.intValue(try pt.errorIntType(), 0), .Other);
6437 try a.end(f, writer);6504 try a.end(f, bw);
6438 }6505 }
6439 return local;6506 return local;
6440}6507}
...@@ -6444,7 +6511,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6444,7 +6511,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6444 const zcu = pt.zcu;6511 const zcu = pt.zcu;
6445 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6512 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;
6448 const operand = try f.resolveInst(un_op);6515 const operand = try f.resolveInst(un_op);
6449 try reap(f, inst, &.{un_op});6516 try reap(f, inst, &.{un_op});
6450 const operand_ty = f.typeOf(un_op);6517 const operand_ty = f.typeOf(un_op);
...@@ -6453,25 +6520,25 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6453,25 +6520,25 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6453 const payload_ty = err_union_ty.errorUnionPayload(zcu);6520 const payload_ty = err_union_ty.errorUnionPayload(zcu);
6454 const error_ty = err_union_ty.errorUnionSet(zcu);6521 const error_ty = err_union_ty.errorUnionSet(zcu);
64556522
6456 const a = try Assignment.start(f, writer, .bool);6523 const a = try Assignment.start(f, bw, .bool);
6457 try f.writeCValue(writer, local, .Other);6524 try f.writeCValue(bw, local, .Other);
6458 try a.assign(f, writer);6525 try a.assign(f, bw);
6459 const err_int_ty = try pt.errorIntType();6526 const err_int_ty = try pt.errorIntType();
6460 if (!error_ty.errorSetIsEmpty(zcu))6527 if (!error_ty.errorSetIsEmpty(zcu))
6461 if (payload_ty.hasRuntimeBits(zcu))6528 if (payload_ty.hasRuntimeBits(zcu))
6462 if (is_ptr)6529 if (is_ptr)
6463 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })6530 try f.writeCValueDerefMember(bw, operand, .{ .identifier = "error" })
6464 else6531 else
6465 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })6532 try f.writeCValueMember(bw, operand, .{ .identifier = "error" })
6466 else6533 else
6467 try f.writeCValue(writer, operand, .Other)6534 try f.writeCValue(bw, operand, .Other)
6468 else6535 else
6469 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);6536 try f.object.dg.renderValue(bw, try pt.intValue(err_int_ty, 0), .Other);
6470 try writer.writeByte(' ');6537 try bw.writeByte(' ');
6471 try writer.writeAll(operator);6538 try bw.writeAll(operator);
6472 try writer.writeByte(' ');6539 try bw.writeByte(' ');
6473 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);6540 try f.object.dg.renderValue(bw, try pt.intValue(err_int_ty, 0), .Other);
6474 try a.end(f, writer);6541 try a.end(f, bw);
6475 return local;6542 return local;
6476}6543}
64776544
...@@ -6485,45 +6552,45 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6485,45 +6552,45 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6485 try reap(f, inst, &.{ty_op.operand});6552 try reap(f, inst, &.{ty_op.operand});
6486 const inst_ty = f.typeOfIndex(inst);6553 const inst_ty = f.typeOfIndex(inst);
6487 const ptr_ty = inst_ty.slicePtrFieldType(zcu);6554 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
6488 const writer = f.object.writer();6555 const bw = &f.object.code.buffered_writer;
6489 const local = try f.allocLocal(inst, inst_ty);6556 const local = try f.allocLocal(inst, inst_ty);
6490 const operand_ty = f.typeOf(ty_op.operand);6557 const operand_ty = f.typeOf(ty_op.operand);
6491 const array_ty = operand_ty.childType(zcu);6558 const array_ty = operand_ty.childType(zcu);
64926559
6493 {6560 {
6494 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));6561 const a = try Assignment.start(f, bw, try f.ctypeFromType(ptr_ty, .complete));
6495 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });6562 try f.writeCValueMember(bw, local, .{ .identifier = "ptr" });
6496 try a.assign(f, writer);6563 try a.assign(f, bw);
6497 if (operand == .undef) {6564 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);
6499 } else {6566 } else {
6500 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);6567 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);
6501 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;6568 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
6502 const elem_ty = array_ty.childType(zcu);6569 const elem_ty = array_ty.childType(zcu);
6503 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);6570 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);
6504 if (!ptr_child_ctype.eql(elem_ctype)) {6571 if (!ptr_child_ctype.eql(elem_ctype)) {
6505 try writer.writeByte('(');6572 try bw.writeByte('(');
6506 try f.renderCType(writer, ptr_ctype);6573 try f.renderCType(bw, ptr_ctype);
6507 try writer.writeByte(')');6574 try bw.writeByte(')');
6508 }6575 }
6509 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);6576 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
6510 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;6577 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;
6511 if (operand_child_ctype.info(ctype_pool) == .array) {6578 if (operand_child_ctype.info(ctype_pool) == .array) {
6512 try writer.writeByte('&');6579 try bw.writeByte('&');
6513 try f.writeCValueDeref(writer, operand);6580 try f.writeCValueDeref(bw, operand);
6514 try writer.print("[{}]", .{try f.fmtIntLiteral(.zero_usize)});6581 try bw.print("[{f}]", .{try f.fmtIntLiteral(.zero_usize)});
6515 } else try f.writeCValue(writer, operand, .Other);6582 } else try f.writeCValue(bw, operand, .Other);
6516 }6583 }
6517 try a.end(f, writer);6584 try a.end(f, bw);
6518 }6585 }
6519 {6586 {
6520 const a = try Assignment.start(f, writer, .usize);6587 const a = try Assignment.start(f, bw, .usize);
6521 try f.writeCValueMember(writer, local, .{ .identifier = "len" });6588 try f.writeCValueMember(bw, local, .{ .identifier = "len" });
6522 try a.assign(f, writer);6589 try a.assign(f, bw);
6523 try writer.print("{}", .{6590 try bw.print("{f}", .{
6524 try f.fmtIntLiteral(try pt.intValue(.usize, array_ty.arrayLen(zcu))),6591 try f.fmtIntLiteral(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
6525 });6592 });
6526 try a.end(f, writer);6593 try a.end(f, bw);
6527 }6594 }
65286595
6529 return local;6596 return local;
...@@ -6550,32 +6617,32 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6550,32 +6617,32 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6550 else6617 else
6551 unreachable;6618 unreachable;
65526619
6553 const writer = f.object.writer();6620 const bw = &f.object.code.buffered_writer;
6554 const local = try f.allocLocal(inst, inst_ty);6621 const local = try f.allocLocal(inst, inst_ty);
6555 const v = try Vectorize.start(f, inst, writer, operand_ty);6622 const v = try Vectorize.start(f, inst, bw, operand_ty);
6556 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));6623 const a = try Assignment.start(f, bw, try f.ctypeFromType(scalar_ty, .complete));
6557 try f.writeCValue(writer, local, .Other);6624 try f.writeCValue(bw, local, .Other);
6558 try v.elem(f, writer);6625 try v.elem(f, bw);
6559 try a.assign(f, writer);6626 try a.assign(f, bw);
6560 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {6627 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6561 try writer.writeAll("zig_wrap_");6628 try bw.writeAll("zig_wrap_");
6562 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);6629 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_scalar_ty);
6563 try writer.writeByte('(');6630 try bw.writeByte('(');
6564 }6631 }
6565 try writer.writeAll("zig_");6632 try bw.writeAll("zig_");
6566 try writer.writeAll(operation);6633 try bw.writeAll(operation);
6567 try writer.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));6634 try bw.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
6568 try writer.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));6635 try bw.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
6569 try writer.writeByte('(');6636 try bw.writeByte('(');
6570 try f.writeCValue(writer, operand, .FunctionArgument);6637 try f.writeCValue(bw, operand, .FunctionArgument);
6571 try v.elem(f, writer);6638 try v.elem(f, bw);
6572 try writer.writeByte(')');6639 try bw.writeByte(')');
6573 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {6640 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6574 try f.object.dg.renderBuiltinInfo(writer, inst_scalar_ty, .bits);6641 try f.object.dg.renderBuiltinInfo(bw, inst_scalar_ty, .bits);
6575 try writer.writeByte(')');6642 try bw.writeByte(')');
6576 }6643 }
6577 try a.end(f, writer);6644 try a.end(f, bw);
6578 try v.end(f, inst, writer);6645 try v.end(f, inst, bw);
65796646
6580 return local;6647 return local;
6581}6648}
...@@ -6600,27 +6667,28 @@ fn airUnBuiltinCall(...@@ -6600,27 +6667,28 @@ fn airUnBuiltinCall(
6600 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6667 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6601 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6668 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;
6604 const local = try f.allocLocal(inst, inst_ty);6671 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);
6606 if (!ref_ret) {6673 if (!ref_ret) {
6607 try f.writeCValue(writer, local, .Other);6674 try f.writeCValue(bw, local, .Other);
6608 try v.elem(f, writer);6675 try v.elem(f, bw);
6609 try writer.writeAll(" = ");6676 try bw.writeAll(" = ");
6610 }6677 }
6611 try writer.print("zig_{s}_", .{operation});6678 try bw.print("zig_{s}_", .{operation});
6612 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6679 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6613 try writer.writeByte('(');6680 try bw.writeByte('(');
6614 if (ref_ret) {6681 if (ref_ret) {
6615 try f.writeCValue(writer, local, .FunctionArgument);6682 try f.writeCValue(bw, local, .FunctionArgument);
6616 try v.elem(f, writer);6683 try v.elem(f, bw);
6617 try writer.writeAll(", ");6684 try bw.writeAll(", ");
6618 }6685 }
6619 try f.writeCValue(writer, operand, .FunctionArgument);6686 try f.writeCValue(bw, operand, .FunctionArgument);
6620 try v.elem(f, writer);6687 try v.elem(f, bw);
6621 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6688 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6622 try writer.writeAll(");\n");6689 try bw.writeAll(");");
6623 try v.end(f, inst, writer);6690 try f.object.newline();
6691 try v.end(f, inst, bw);
66246692
6625 return local;6693 return local;
6626}6694}
...@@ -6650,31 +6718,31 @@ fn airBinBuiltinCall(...@@ -6650,31 +6718,31 @@ fn airBinBuiltinCall(
6650 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6718 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6651 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6719 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;
6654 const local = try f.allocLocal(inst, inst_ty);6722 const local = try f.allocLocal(inst, inst_ty);
6655 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6723 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);
6657 if (!ref_ret) {6725 if (!ref_ret) {
6658 try f.writeCValue(writer, local, .Other);6726 try f.writeCValue(bw, local, .Other);
6659 try v.elem(f, writer);6727 try v.elem(f, bw);
6660 try writer.writeAll(" = ");6728 try bw.writeAll(" = ");
6661 }6729 }
6662 try writer.print("zig_{s}_", .{operation});6730 try bw.print("zig_{s}_", .{operation});
6663 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6731 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6664 try writer.writeByte('(');6732 try bw.writeByte('(');
6665 if (ref_ret) {6733 if (ref_ret) {
6666 try f.writeCValue(writer, local, .FunctionArgument);6734 try f.writeCValue(bw, local, .FunctionArgument);
6667 try v.elem(f, writer);6735 try v.elem(f, bw);
6668 try writer.writeAll(", ");6736 try bw.writeAll(", ");
6669 }6737 }
6670 try f.writeCValue(writer, lhs, .FunctionArgument);6738 try f.writeCValue(bw, lhs, .FunctionArgument);
6671 try v.elem(f, writer);6739 try v.elem(f, bw);
6672 try writer.writeAll(", ");6740 try bw.writeAll(", ");
6673 try f.writeCValue(writer, rhs, .FunctionArgument);6741 try f.writeCValue(bw, rhs, .FunctionArgument);
6674 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, writer);6742 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, bw);
6675 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6743 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6676 try writer.writeAll(");\n");6744 try bw.writeAll(");\n");
6677 try v.end(f, inst, writer);6745 try v.end(f, inst, bw);
66786746
6679 return local;6747 return local;
6680}6748}
...@@ -6701,38 +6769,39 @@ fn airCmpBuiltinCall(...@@ -6701,38 +6769,39 @@ fn airCmpBuiltinCall(
6701 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6769 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6702 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6770 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;
6705 const local = try f.allocLocal(inst, inst_ty);6773 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);
6707 if (!ref_ret) {6775 if (!ref_ret) {
6708 try f.writeCValue(writer, local, .Other);6776 try f.writeCValue(bw, local, .Other);
6709 try v.elem(f, writer);6777 try v.elem(f, bw);
6710 try writer.writeAll(" = ");6778 try bw.writeAll(" = ");
6711 }6779 }
6712 try writer.print("zig_{s}_", .{switch (operation) {6780 try bw.print("zig_{s}_", .{switch (operation) {
6713 else => @tagName(operation),6781 else => @tagName(operation),
6714 .operator => compareOperatorAbbrev(operator),6782 .operator => compareOperatorAbbrev(operator),
6715 }});6783 }});
6716 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6784 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
6717 try writer.writeByte('(');6785 try bw.writeByte('(');
6718 if (ref_ret) {6786 if (ref_ret) {
6719 try f.writeCValue(writer, local, .FunctionArgument);6787 try f.writeCValue(bw, local, .FunctionArgument);
6720 try v.elem(f, writer);6788 try v.elem(f, bw);
6721 try writer.writeAll(", ");6789 try bw.writeAll(", ");
6722 }6790 }
6723 try f.writeCValue(writer, lhs, .FunctionArgument);6791 try f.writeCValue(bw, lhs, .FunctionArgument);
6724 try v.elem(f, writer);6792 try v.elem(f, bw);
6725 try writer.writeAll(", ");6793 try bw.writeAll(", ");
6726 try f.writeCValue(writer, rhs, .FunctionArgument);6794 try f.writeCValue(bw, rhs, .FunctionArgument);
6727 try v.elem(f, writer);6795 try v.elem(f, bw);
6728 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6796 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, info);
6729 try writer.writeByte(')');6797 try bw.writeByte(')');
6730 if (!ref_ret) try writer.print("{s}{}", .{6798 if (!ref_ret) try bw.print("{s}{f}", .{
6731 compareOperatorC(operator),6799 compareOperatorC(operator),
6732 try f.fmtIntLiteral(try pt.intValue(.i32, 0)),6800 try f.fmtIntLiteral(try pt.intValue(.i32, 0)),
6733 });6801 });
6734 try writer.writeAll(";\n");6802 try bw.writeByte(';');
6735 try v.end(f, inst, writer);6803 try f.object.newline();
6804 try v.end(f, inst, bw);
67366805
6737 return local;6806 return local;
6738}6807}
...@@ -6750,7 +6819,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6750,7 +6819,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6750 const ty = ptr_ty.childType(zcu);6819 const ty = ptr_ty.childType(zcu);
6751 const ctype = try f.ctypeFromType(ty, .complete);6820 const ctype = try f.ctypeFromType(ty, .complete);
67526821
6753 const writer = f.object.writer();6822 const bw = &f.object.code.buffered_writer;
6754 const new_value_mat = try Materialize.start(f, inst, ty, new_value);6823 const new_value_mat = try Materialize.start(f, inst, ty, new_value);
6755 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });6824 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...@@ -6762,76 +6831,78 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6762 const local = try f.allocLocal(inst, inst_ty);6831 const local = try f.allocLocal(inst, inst_ty);
6763 if (inst_ty.isPtrLikeOptional(zcu)) {6832 if (inst_ty.isPtrLikeOptional(zcu)) {
6764 {6833 {
6765 const a = try Assignment.start(f, writer, ctype);6834 const a = try Assignment.start(f, bw, ctype);
6766 try f.writeCValue(writer, local, .Other);6835 try f.writeCValue(bw, local, .Other);
6767 try a.assign(f, writer);6836 try a.assign(f, bw);
6768 try f.writeCValue(writer, expected_value, .Other);6837 try f.writeCValue(bw, expected_value, .Other);
6769 try a.end(f, writer);6838 try a.end(f, bw);
6770 }6839 }
67716840
6772 try writer.writeAll("if (");6841 try bw.writeAll("if (");
6773 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});6842 try bw.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6774 try f.renderType(writer, ty);6843 try f.renderType(bw, ty);
6775 try writer.writeByte(')');6844 try bw.writeByte(')');
6776 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6845 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6777 try writer.writeAll(" *)");6846 try bw.writeAll(" *)");
6778 try f.writeCValue(writer, ptr, .Other);6847 try f.writeCValue(bw, ptr, .Other);
6779 try writer.writeAll(", ");6848 try bw.writeAll(", ");
6780 try f.writeCValue(writer, local, .FunctionArgument);6849 try f.writeCValue(bw, local, .FunctionArgument);
6781 try writer.writeAll(", ");6850 try bw.writeAll(", ");
6782 try new_value_mat.mat(f, writer);6851 try new_value_mat.mat(f, bw);
6783 try writer.writeAll(", ");6852 try bw.writeAll(", ");
6784 try writeMemoryOrder(writer, extra.successOrder());6853 try writeMemoryOrder(bw, extra.successOrder());
6785 try writer.writeAll(", ");6854 try bw.writeAll(", ");
6786 try writeMemoryOrder(writer, extra.failureOrder());6855 try writeMemoryOrder(bw, extra.failureOrder());
6787 try writer.writeAll(", ");6856 try bw.writeAll(", ");
6788 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6857 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6789 try writer.writeAll(", ");6858 try bw.writeAll(", ");
6790 try f.renderType(writer, repr_ty);6859 try f.renderType(bw, repr_ty);
6791 try writer.writeByte(')');6860 try bw.writeByte(')');
6792 try writer.writeAll(") {\n");6861 try bw.writeAll(") {");
6793 f.object.indent_writer.pushIndent();6862 f.object.indent();
6863 try f.object.newline();
6794 {6864 {
6795 const a = try Assignment.start(f, writer, ctype);6865 const a = try Assignment.start(f, bw, ctype);
6796 try f.writeCValue(writer, local, .Other);6866 try f.writeCValue(bw, local, .Other);
6797 try a.assign(f, writer);6867 try a.assign(f, bw);
6798 try writer.writeAll("NULL");6868 try bw.writeAll("NULL");
6799 try a.end(f, writer);6869 try a.end(f, bw);
6800 }6870 }
6801 f.object.indent_writer.popIndent();6871 f.object.outdent();
6802 try writer.writeAll("}\n");6872 try bw.writeByte('}');
6873 try f.object.newline();
6803 } else {6874 } else {
6804 {6875 {
6805 const a = try Assignment.start(f, writer, ctype);6876 const a = try Assignment.start(f, bw, ctype);
6806 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6877 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6807 try a.assign(f, writer);6878 try a.assign(f, bw);
6808 try f.writeCValue(writer, expected_value, .Other);6879 try f.writeCValue(bw, expected_value, .Other);
6809 try a.end(f, writer);6880 try a.end(f, bw);
6810 }6881 }
6811 {6882 {
6812 const a = try Assignment.start(f, writer, .bool);6883 const a = try Assignment.start(f, bw, .bool);
6813 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });6884 try f.writeCValueMember(bw, local, .{ .identifier = "is_null" });
6814 try a.assign(f, writer);6885 try a.assign(f, bw);
6815 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});6886 try bw.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6816 try f.renderType(writer, ty);6887 try f.renderType(bw, ty);
6817 try writer.writeByte(')');6888 try bw.writeByte(')');
6818 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6889 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6819 try writer.writeAll(" *)");6890 try bw.writeAll(" *)");
6820 try f.writeCValue(writer, ptr, .Other);6891 try f.writeCValue(bw, ptr, .Other);
6821 try writer.writeAll(", ");6892 try bw.writeAll(", ");
6822 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6893 try f.writeCValueMember(bw, local, .{ .identifier = "payload" });
6823 try writer.writeAll(", ");6894 try bw.writeAll(", ");
6824 try new_value_mat.mat(f, writer);6895 try new_value_mat.mat(f, bw);
6825 try writer.writeAll(", ");6896 try bw.writeAll(", ");
6826 try writeMemoryOrder(writer, extra.successOrder());6897 try writeMemoryOrder(bw, extra.successOrder());
6827 try writer.writeAll(", ");6898 try bw.writeAll(", ");
6828 try writeMemoryOrder(writer, extra.failureOrder());6899 try writeMemoryOrder(bw, extra.failureOrder());
6829 try writer.writeAll(", ");6900 try bw.writeAll(", ");
6830 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6901 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6831 try writer.writeAll(", ");6902 try bw.writeAll(", ");
6832 try f.renderType(writer, repr_ty);6903 try f.renderType(bw, repr_ty);
6833 try writer.writeByte(')');6904 try bw.writeByte(')');
6834 try a.end(f, writer);6905 try a.end(f, bw);
6835 }6906 }
6836 }6907 }
6837 try new_value_mat.end(f, inst);6908 try new_value_mat.end(f, inst);
...@@ -6855,7 +6926,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6855,7 +6926,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6855 const ptr = try f.resolveInst(pl_op.operand);6926 const ptr = try f.resolveInst(pl_op.operand);
6856 const operand = try f.resolveInst(extra.operand);6927 const operand = try f.resolveInst(extra.operand);
68576928
6858 const writer = f.object.writer();6929 const bw = &f.object.code.buffered_writer;
6859 const operand_mat = try Materialize.start(f, inst, ty, operand);6930 const operand_mat = try Materialize.start(f, inst, ty, operand);
6860 try reap(f, inst, &.{ pl_op.operand, extra.operand });6931 try reap(f, inst, &.{ pl_op.operand, extra.operand });
68616932
...@@ -6865,31 +6936,32 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6865,31 +6936,32 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6865 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;6936 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;
68666937
6867 const local = try f.allocLocal(inst, inst_ty);6938 const local = try f.allocLocal(inst, inst_ty);
6868 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});6939 try bw.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6869 if (is_float) try writer.writeAll("_float") else if (is_128) try writer.writeAll("_int128");6940 if (is_float) try bw.writeAll("_float") else if (is_128) try bw.writeAll("_int128");
6870 try writer.writeByte('(');6941 try bw.writeByte('(');
6871 try f.writeCValue(writer, local, .Other);6942 try f.writeCValue(bw, local, .Other);
6872 try writer.writeAll(", (");6943 try bw.writeAll(", (");
6873 const use_atomic = switch (extra.op()) {6944 const use_atomic = switch (extra.op()) {
6874 else => true,6945 else => true,
6875 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.6946 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.
6876 .Nand, .Min, .Max => is_float or is_128,6947 .Nand, .Min, .Max => is_float or is_128,
6877 };6948 };
6878 if (use_atomic) try writer.writeAll("zig_atomic(");6949 if (use_atomic) try bw.writeAll("zig_atomic(");
6879 try f.renderType(writer, ty);6950 try f.renderType(bw, ty);
6880 if (use_atomic) try writer.writeByte(')');6951 if (use_atomic) try bw.writeByte(')');
6881 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6952 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6882 try writer.writeAll(" *)");6953 try bw.writeAll(" *)");
6883 try f.writeCValue(writer, ptr, .Other);6954 try f.writeCValue(bw, ptr, .Other);
6884 try writer.writeAll(", ");6955 try bw.writeAll(", ");
6885 try operand_mat.mat(f, writer);6956 try operand_mat.mat(f, bw);
6886 try writer.writeAll(", ");6957 try bw.writeAll(", ");
6887 try writeMemoryOrder(writer, extra.ordering());6958 try writeMemoryOrder(bw, extra.ordering());
6888 try writer.writeAll(", ");6959 try bw.writeAll(", ");
6889 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6960 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6890 try writer.writeAll(", ");6961 try bw.writeAll(", ");
6891 try f.renderType(writer, repr_ty);6962 try f.renderType(bw, repr_ty);
6892 try writer.writeAll(");\n");6963 try bw.writeAll(");");
6964 try f.object.newline();
6893 try operand_mat.end(f, inst);6965 try operand_mat.end(f, inst);
68946966
6895 if (f.liveness.isUnused(inst)) {6967 if (f.liveness.isUnused(inst)) {
...@@ -6915,24 +6987,25 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6915,24 +6987,25 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6915 ty;6987 ty;
69166988
6917 const inst_ty = f.typeOfIndex(inst);6989 const inst_ty = f.typeOfIndex(inst);
6918 const writer = f.object.writer();6990 const bw = &f.object.code.buffered_writer;
6919 const local = try f.allocLocal(inst, inst_ty);6991 const local = try f.allocLocal(inst, inst_ty);
69206992
6921 try writer.writeAll("zig_atomic_load(");6993 try bw.writeAll("zig_atomic_load(");
6922 try f.writeCValue(writer, local, .Other);6994 try f.writeCValue(bw, local, .Other);
6923 try writer.writeAll(", (zig_atomic(");6995 try bw.writeAll(", (zig_atomic(");
6924 try f.renderType(writer, ty);6996 try f.renderType(bw, ty);
6925 try writer.writeByte(')');6997 try bw.writeByte(')');
6926 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6998 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6927 try writer.writeAll(" *)");6999 try bw.writeAll(" *)");
6928 try f.writeCValue(writer, ptr, .Other);7000 try f.writeCValue(bw, ptr, .Other);
6929 try writer.writeAll(", ");7001 try bw.writeAll(", ");
6930 try writeMemoryOrder(writer, atomic_load.order);7002 try writeMemoryOrder(bw, atomic_load.order);
6931 try writer.writeAll(", ");7003 try bw.writeAll(", ");
6932 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);7004 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6933 try writer.writeAll(", ");7005 try bw.writeAll(", ");
6934 try f.renderType(writer, repr_ty);7006 try f.renderType(bw, repr_ty);
6935 try writer.writeAll(");\n");7007 try bw.writeAll(");");
7008 try f.object.newline();
69367009
6937 return local;7010 return local;
6938}7011}
...@@ -6946,7 +7019,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6946,7 +7019,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6946 const ptr = try f.resolveInst(bin_op.lhs);7019 const ptr = try f.resolveInst(bin_op.lhs);
6947 const element = try f.resolveInst(bin_op.rhs);7020 const element = try f.resolveInst(bin_op.rhs);
69487021
6949 const writer = f.object.writer();7022 const bw = &f.object.code.buffered_writer;
6950 const element_mat = try Materialize.start(f, inst, ty, element);7023 const element_mat = try Materialize.start(f, inst, ty, element);
6951 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7024 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...@@ -6955,31 +7028,32 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6955 else7028 else
6956 ty;7029 ty;
69577030
6958 try writer.writeAll("zig_atomic_store((zig_atomic(");7031 try bw.writeAll("zig_atomic_store((zig_atomic(");
6959 try f.renderType(writer, ty);7032 try f.renderType(bw, ty);
6960 try writer.writeByte(')');7033 try bw.writeByte(')');
6961 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");7034 if (ptr_ty.isVolatilePtr(zcu)) try bw.writeAll(" volatile");
6962 try writer.writeAll(" *)");7035 try bw.writeAll(" *)");
6963 try f.writeCValue(writer, ptr, .Other);7036 try f.writeCValue(bw, ptr, .Other);
6964 try writer.writeAll(", ");7037 try bw.writeAll(", ");
6965 try element_mat.mat(f, writer);7038 try element_mat.mat(f, bw);
6966 try writer.print(", {s}, ", .{order});7039 try bw.print(", {s}, ", .{order});
6967 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);7040 try f.object.dg.renderTypeForBuiltinFnName(bw, ty);
6968 try writer.writeAll(", ");7041 try bw.writeAll(", ");
6969 try f.renderType(writer, repr_ty);7042 try f.renderType(bw, repr_ty);
6970 try writer.writeAll(");\n");7043 try bw.writeAll(");");
7044 try f.object.newline();
6971 try element_mat.end(f, inst);7045 try element_mat.end(f, inst);
69727046
6973 return .none;7047 return .none;
6974}7048}
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 {
6977 const pt = f.object.dg.pt;7051 const pt = f.object.dg.pt;
6978 const zcu = pt.zcu;7052 const zcu = pt.zcu;
6979 if (ptr_ty.isSlice(zcu)) {7053 if (ptr_ty.isSlice(zcu)) {
6980 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });7054 try f.writeCValueMember(bw, ptr, .{ .identifier = "ptr" });
6981 } else {7055 } else {
6982 try f.writeCValue(writer, ptr, .FunctionArgument);7056 try f.writeCValue(bw, ptr, .FunctionArgument);
6983 }7057 }
6984}7058}
69857059
...@@ -6993,7 +7067,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -6993,7 +7067,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6993 const elem_ty = f.typeOf(bin_op.rhs);7067 const elem_ty = f.typeOf(bin_op.rhs);
6994 const elem_abi_size = elem_ty.abiSize(zcu);7068 const elem_abi_size = elem_ty.abiSize(zcu);
6995 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false;7069 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
6998 if (val_is_undef) {7072 if (val_is_undef) {
6999 if (!safety) {7073 if (!safety) {
...@@ -7001,24 +7075,25 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7001,24 +7075,25 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
7001 return .none;7075 return .none;
7002 }7076 }
70037077
7004 try writer.writeAll("memset(");7078 try bw.writeAll("memset(");
7005 switch (dest_ty.ptrSize(zcu)) {7079 switch (dest_ty.ptrSize(zcu)) {
7006 .slice => {7080 .slice => {
7007 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });7081 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "ptr" });
7008 try writer.writeAll(", 0xaa, ");7082 try bw.writeAll(", 0xaa, ");
7009 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7083 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
7010 if (elem_abi_size > 1) {7084 if (elem_abi_size > 1) {
7011 try writer.print(" * {d});\n", .{elem_abi_size});7085 try bw.print(" * {d}", .{elem_abi_size});
7012 } else {
7013 try writer.writeAll(");\n");
7014 }7086 }
7087 try bw.writeAll(");");
7088 try f.object.newline();
7015 },7089 },
7016 .one => {7090 .one => {
7017 const array_ty = dest_ty.childType(zcu);7091 const array_ty = dest_ty.childType(zcu);
7018 const len = array_ty.arrayLen(zcu) * elem_abi_size;7092 const len = array_ty.arrayLen(zcu) * elem_abi_size;
70197093
7020 try f.writeCValue(writer, dest_slice, .FunctionArgument);7094 try f.writeCValue(bw, dest_slice, .FunctionArgument);
7021 try writer.print(", 0xaa, {d});\n", .{len});7095 try bw.print(", 0xaa, {d});", .{len});
7096 try f.object.newline();
7022 },7097 },
7023 .many, .c => unreachable,7098 .many, .c => unreachable,
7024 }7099 }
...@@ -7039,38 +7114,38 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7039,38 +7114,38 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70397114
7040 const index = try f.allocLocal(inst, .usize);7115 const index = try f.allocLocal(inst, .usize);
70417116
7042 try writer.writeAll("for (");7117 try bw.writeAll("for (");
7043 try f.writeCValue(writer, index, .Other);7118 try f.writeCValue(bw, index, .Other);
7044 try writer.writeAll(" = ");7119 try bw.writeAll(" = ");
7045 try f.object.dg.renderValue(writer, .zero_usize, .Other);7120 try f.object.dg.renderValue(bw, .zero_usize, .Other);
7046 try writer.writeAll("; ");7121 try bw.writeAll("; ");
7047 try f.writeCValue(writer, index, .Other);7122 try f.writeCValue(bw, index, .Other);
7048 try writer.writeAll(" != ");7123 try bw.writeAll(" != ");
7049 switch (dest_ty.ptrSize(zcu)) {7124 switch (dest_ty.ptrSize(zcu)) {
7050 .slice => {7125 .slice => {
7051 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7126 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
7052 },7127 },
7053 .one => {7128 .one => {
7054 const array_ty = dest_ty.childType(zcu);7129 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)});
7056 },7131 },
7057 .many, .c => unreachable,7132 .many, .c => unreachable,
7058 }7133 }
7059 try writer.writeAll("; ++");7134 try bw.writeAll("; ++");
7060 try f.writeCValue(writer, index, .Other);7135 try f.writeCValue(bw, index, .Other);
7061 try writer.writeAll(") ");7136 try bw.writeAll(") ");
70627137
7063 const a = try Assignment.start(f, writer, try f.ctypeFromType(elem_ty, .complete));7138 const a = try Assignment.start(f, bw, try f.ctypeFromType(elem_ty, .complete));
7064 try writer.writeAll("((");7139 try bw.writeAll("((");
7065 try f.renderType(writer, elem_ptr_ty);7140 try f.renderType(bw, elem_ptr_ty);
7066 try writer.writeByte(')');7141 try bw.writeByte(')');
7067 try writeSliceOrPtr(f, writer, dest_slice, dest_ty);7142 try writeSliceOrPtr(f, bw, dest_slice, dest_ty);
7068 try writer.writeAll(")[");7143 try bw.writeAll(")[");
7069 try f.writeCValue(writer, index, .Other);7144 try f.writeCValue(bw, index, .Other);
7070 try writer.writeByte(']');7145 try bw.writeByte(']');
7071 try a.assign(f, writer);7146 try a.assign(f, bw);
7072 try f.writeCValue(writer, value, .Other);7147 try f.writeCValue(bw, value, .Other);
7073 try a.end(f, writer);7148 try a.end(f, bw);
70747149
7075 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7150 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
7076 try freeLocal(f, inst, index.new_local, null);7151 try freeLocal(f, inst, index.new_local, null);
...@@ -7080,24 +7155,26 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7080,24 +7155,26 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70807155
7081 const bitcasted = try bitcast(f, .u8, value, elem_ty);7156 const bitcasted = try bitcast(f, .u8, value, elem_ty);
70827157
7083 try writer.writeAll("memset(");7158 try bw.writeAll("memset(");
7084 switch (dest_ty.ptrSize(zcu)) {7159 switch (dest_ty.ptrSize(zcu)) {
7085 .slice => {7160 .slice => {
7086 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });7161 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "ptr" });
7087 try writer.writeAll(", ");7162 try bw.writeAll(", ");
7088 try f.writeCValue(writer, bitcasted, .FunctionArgument);7163 try f.writeCValue(bw, bitcasted, .FunctionArgument);
7089 try writer.writeAll(", ");7164 try bw.writeAll(", ");
7090 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7165 try f.writeCValueMember(bw, dest_slice, .{ .identifier = "len" });
7091 try writer.writeAll(");\n");7166 try bw.writeAll(");");
7167 try f.object.newline();
7092 },7168 },
7093 .one => {7169 .one => {
7094 const array_ty = dest_ty.childType(zcu);7170 const array_ty = dest_ty.childType(zcu);
7095 const len = array_ty.arrayLen(zcu) * elem_abi_size;7171 const len = array_ty.arrayLen(zcu) * elem_abi_size;
70967172
7097 try f.writeCValue(writer, dest_slice, .FunctionArgument);7173 try f.writeCValue(bw, dest_slice, .FunctionArgument);
7098 try writer.writeAll(", ");7174 try bw.writeAll(", ");
7099 try f.writeCValue(writer, bitcasted, .FunctionArgument);7175 try f.writeCValue(bw, bitcasted, .FunctionArgument);
7100 try writer.print(", {d});\n", .{len});7176 try bw.print(", {d});", .{len});
7177 try f.object.newline();
7101 },7178 },
7102 .many, .c => unreachable,7179 .many, .c => unreachable,
7103 }7180 }
...@@ -7114,22 +7191,23 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV...@@ -7114,22 +7191,23 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV
7114 const src_ptr = try f.resolveInst(bin_op.rhs);7191 const src_ptr = try f.resolveInst(bin_op.rhs);
7115 const dest_ty = f.typeOf(bin_op.lhs);7192 const dest_ty = f.typeOf(bin_op.lhs);
7116 const src_ty = f.typeOf(bin_op.rhs);7193 const src_ty = f.typeOf(bin_op.rhs);
7117 const writer = f.object.writer();7194 const bw = &f.object.code.buffered_writer;
71187195
7119 if (dest_ty.ptrSize(zcu) != .one) {7196 if (dest_ty.ptrSize(zcu) != .one) {
7120 try writer.writeAll("if (");7197 try bw.writeAll("if (");
7121 try writeArrayLen(f, writer, dest_ptr, dest_ty);7198 try writeArrayLen(f, dest_ptr, dest_ty);
7122 try writer.writeAll(" != 0) ");7199 try bw.writeAll(" != 0) ");
7123 }7200 }
7124 try writer.writeAll(function_paren);7201 try bw.writeAll(function_paren);
7125 try writeSliceOrPtr(f, writer, dest_ptr, dest_ty);7202 try writeSliceOrPtr(f, bw, dest_ptr, dest_ty);
7126 try writer.writeAll(", ");7203 try bw.writeAll(", ");
7127 try writeSliceOrPtr(f, writer, src_ptr, src_ty);7204 try writeSliceOrPtr(f, bw, src_ptr, src_ty);
7128 try writer.writeAll(", ");7205 try bw.writeAll(", ");
7129 try writeArrayLen(f, writer, dest_ptr, dest_ty);7206 try writeArrayLen(f, dest_ptr, dest_ty);
7130 try writer.writeAll(" * sizeof(");7207 try bw.writeAll(" * sizeof(");
7131 try f.renderType(writer, dest_ty.elemType2(zcu));7208 try f.renderType(bw, dest_ty.elemType2(zcu));
7132 try writer.writeAll("));\n");7209 try bw.writeAll("));");
7210 try f.object.newline();
71337211
7134 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7212 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
7135 return .none;7213 return .none;
...@@ -7138,13 +7216,13 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV...@@ -7138,13 +7216,13 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV
7138fn writeArrayLen(f: *Function, dest_ptr: CValue, dest_ty: Type) !void {7216fn writeArrayLen(f: *Function, dest_ptr: CValue, dest_ty: Type) !void {
7139 const pt = f.object.dg.pt;7217 const pt = f.object.dg.pt;
7140 const zcu = pt.zcu;7218 const zcu = pt.zcu;
7141 const writer = f.object.writer();7219 const bw = &f.object.code.buffered_writer;
7142 switch (dest_ty.ptrSize(zcu)) {7220 switch (dest_ty.ptrSize(zcu)) {
7143 .one => try writer.print("{}", .{7221 .one => try bw.print("{f}", .{
7144 try f.fmtIntLiteral(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),7222 try f.fmtIntLiteral(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),
7145 }),7223 }),
7146 .many, .c => unreachable,7224 .many, .c => unreachable,
7147 .slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),7225 .slice => try f.writeCValueMember(bw, dest_ptr, .{ .identifier = "len" }),
7148 }7226 }
7149}7227}
71507228
...@@ -7161,12 +7239,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7161,12 +7239,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7161 if (layout.tag_size == 0) return .none;7239 if (layout.tag_size == 0) return .none;
7162 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;7240 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
71637241
7164 const writer = f.object.writer();7242 const bw = &f.object.code.buffered_writer;
7165 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));7243 const a = try Assignment.start(f, bw, try f.ctypeFromType(tag_ty, .complete));
7166 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });7244 try f.writeCValueDerefMember(bw, union_ptr, .{ .identifier = "tag" });
7167 try a.assign(f, writer);7245 try a.assign(f, bw);
7168 try f.writeCValue(writer, new_tag, .Other);7246 try f.writeCValue(bw, new_tag, .Other);
7169 try a.end(f, writer);7247 try a.end(f, bw);
7170 return .none;7248 return .none;
7171}7249}
71727250
...@@ -7183,13 +7261,13 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7183,13 +7261,13 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7183 if (layout.tag_size == 0) return .none;7261 if (layout.tag_size == 0) return .none;
71847262
7185 const inst_ty = f.typeOfIndex(inst);7263 const inst_ty = f.typeOfIndex(inst);
7186 const writer = f.object.writer();7264 const bw = &f.object.code.buffered_writer;
7187 const local = try f.allocLocal(inst, inst_ty);7265 const local = try f.allocLocal(inst, inst_ty);
7188 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));7266 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_ty, .complete));
7189 try f.writeCValue(writer, local, .Other);7267 try f.writeCValue(bw, local, .Other);
7190 try a.assign(f, writer);7268 try a.assign(f, bw);
7191 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });7269 try f.writeCValueMember(bw, operand, .{ .identifier = "tag" });
7192 try a.end(f, writer);7270 try a.end(f, bw);
7193 return local;7271 return local;
7194}7272}
71957273
...@@ -7201,14 +7279,15 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7201,14 +7279,15 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7201 const operand = try f.resolveInst(un_op);7279 const operand = try f.resolveInst(un_op);
7202 try reap(f, inst, &.{un_op});7280 try reap(f, inst, &.{un_op});
72037281
7204 const writer = f.object.writer();7282 const bw = &f.object.code.buffered_writer;
7205 const local = try f.allocLocal(inst, inst_ty);7283 const local = try f.allocLocal(inst, inst_ty);
7206 try f.writeCValue(writer, local, .Other);7284 try f.writeCValue(bw, local, .Other);
7207 try writer.print(" = {s}(", .{7285 try bw.print(" = {s}(", .{
7208 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),7286 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),
7209 });7287 });
7210 try f.writeCValue(writer, operand, .Other);7288 try f.writeCValue(bw, operand, .Other);
7211 try writer.writeAll(");\n");7289 try bw.writeAll(");");
7290 try f.object.newline();
72127291
7213 return local;7292 return local;
7214}7293}
...@@ -7216,16 +7295,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7216,16 +7295,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7216fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {7295fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
7217 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7296 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;
7220 const inst_ty = f.typeOfIndex(inst);7299 const inst_ty = f.typeOfIndex(inst);
7221 const operand = try f.resolveInst(un_op);7300 const operand = try f.resolveInst(un_op);
7222 try reap(f, inst, &.{un_op});7301 try reap(f, inst, &.{un_op});
7223 const local = try f.allocLocal(inst, inst_ty);7302 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[");7305 try bw.writeAll(" = zig_errorName[");
7227 try f.writeCValue(writer, operand, .Other);7306 try f.writeCValue(bw, operand, .Other);
7228 try writer.writeAll(" - 1];\n");7307 try bw.writeAll(" - 1];");
7308 try f.object.newline();
7229 return local;7309 return local;
7230}7310}
72317311
...@@ -7240,16 +7320,16 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7240,16 +7320,16 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
7240 const inst_ty = f.typeOfIndex(inst);7320 const inst_ty = f.typeOfIndex(inst);
7241 const inst_scalar_ty = inst_ty.scalarType(zcu);7321 const inst_scalar_ty = inst_ty.scalarType(zcu);
72427322
7243 const writer = f.object.writer();7323 const bw = &f.object.code.buffered_writer;
7244 const local = try f.allocLocal(inst, inst_ty);7324 const local = try f.allocLocal(inst, inst_ty);
7245 const v = try Vectorize.start(f, inst, writer, inst_ty);7325 const v = try Vectorize.start(f, inst, bw, inst_ty);
7246 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));7326 const a = try Assignment.start(f, bw, try f.ctypeFromType(inst_scalar_ty, .complete));
7247 try f.writeCValue(writer, local, .Other);7327 try f.writeCValue(bw, local, .Other);
7248 try v.elem(f, writer);7328 try v.elem(f, bw);
7249 try a.assign(f, writer);7329 try a.assign(f, bw);
7250 try f.writeCValue(writer, operand, .Other);7330 try f.writeCValue(bw, operand, .Other);
7251 try a.end(f, writer);7331 try a.end(f, bw);
7252 try v.end(f, inst, writer);7332 try v.end(f, inst, bw);
72537333
7254 return local;7334 return local;
7255}7335}
...@@ -7265,22 +7345,23 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7265,22 +7345,23 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
72657345
7266 const inst_ty = f.typeOfIndex(inst);7346 const inst_ty = f.typeOfIndex(inst);
72677347
7268 const writer = f.object.writer();7348 const bw = &f.object.code.buffered_writer;
7269 const local = try f.allocLocal(inst, inst_ty);7349 const local = try f.allocLocal(inst, inst_ty);
7270 const v = try Vectorize.start(f, inst, writer, inst_ty);7350 const v = try Vectorize.start(f, inst, bw, inst_ty);
7271 try f.writeCValue(writer, local, .Other);7351 try f.writeCValue(bw, local, .Other);
7272 try v.elem(f, writer);7352 try v.elem(f, bw);
7273 try writer.writeAll(" = ");7353 try bw.writeAll(" = ");
7274 try f.writeCValue(writer, pred, .Other);7354 try f.writeCValue(bw, pred, .Other);
7275 try v.elem(f, writer);7355 try v.elem(f, bw);
7276 try writer.writeAll(" ? ");7356 try bw.writeAll(" ? ");
7277 try f.writeCValue(writer, lhs, .Other);7357 try f.writeCValue(bw, lhs, .Other);
7278 try v.elem(f, writer);7358 try v.elem(f, bw);
7279 try writer.writeAll(" : ");7359 try bw.writeAll(" : ");
7280 try f.writeCValue(writer, rhs, .Other);7360 try f.writeCValue(bw, rhs, .Other);
7281 try v.elem(f, writer);7361 try v.elem(f, bw);
7282 try writer.writeAll(";\n");7362 try bw.writeByte(';');
7283 try v.end(f, inst, writer);7363 try f.object.newline();
7364 try v.end(f, inst, bw);
72847365
7285 return local;7366 return local;
7286}7367}
...@@ -7294,24 +7375,24 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7294,24 +7375,24 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7294 const operand = try f.resolveInst(unwrapped.operand);7375 const operand = try f.resolveInst(unwrapped.operand);
7295 const inst_ty = unwrapped.result_ty;7376 const inst_ty = unwrapped.result_ty;
72967377
7297 const writer = f.object.writer();7378 const bw = &f.object.code.buffered_writer;
7298 const local = try f.allocLocal(inst, inst_ty);7379 const local = try f.allocLocal(inst, inst_ty);
7299 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand7380 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
7300 for (mask, 0..) |mask_elem, out_idx| {7381 for (mask, 0..) |mask_elem, out_idx| {
7301 try f.writeCValue(writer, local, .Other);7382 try f.writeCValue(bw, local, .Other);
7302 try writer.writeByte('[');7383 try bw.writeByte('[');
7303 try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other);7384 try f.object.dg.renderValue(bw, try pt.intValue(.usize, out_idx), .Other);
7304 try writer.writeAll("] = ");7385 try bw.writeAll("] = ");
7305 switch (mask_elem.unwrap()) {7386 switch (mask_elem.unwrap()) {
7306 .elem => |src_idx| {7387 .elem => |src_idx| {
7307 try f.writeCValue(writer, operand, .Other);7388 try f.writeCValue(bw, operand, .Other);
7308 try writer.writeByte('[');7389 try bw.writeByte('[');
7309 try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other);7390 try f.object.dg.renderValue(bw, try pt.intValue(.usize, src_idx), .Other);
7310 try writer.writeByte(']');7391 try bw.writeByte(']');
7311 },7392 },
7312 .value => |val| try f.object.dg.renderValue(writer, .fromInterned(val), .Other),7393 .value => |val| try f.object.dg.renderValue(bw, .fromInterned(val), .Other),
7313 }7394 }
7314 try writer.writeAll(";\n");7395 try bw.writeAll(";\n");
7315 }7396 }
73167397
7317 return local;7398 return local;
...@@ -7328,7 +7409,7 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7328,7 +7409,7 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
7328 const inst_ty = unwrapped.result_ty;7409 const inst_ty = unwrapped.result_ty;
7329 const elem_ty = inst_ty.childType(zcu);7410 const elem_ty = inst_ty.childType(zcu);
73307411
7331 const writer = f.object.writer();7412 const writer = &f.object.code.buffered_writer;
7332 const local = try f.allocLocal(inst, inst_ty);7413 const local = try f.allocLocal(inst, inst_ty);
7333 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands7414 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands
7334 for (mask, 0..) |mask_elem, out_idx| {7415 for (mask, 0..) |mask_elem, out_idx| {
...@@ -7366,7 +7447,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7366,7 +7447,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7366 const operand = try f.resolveInst(reduce.operand);7447 const operand = try f.resolveInst(reduce.operand);
7367 try reap(f, inst, &.{reduce.operand});7448 try reap(f, inst, &.{reduce.operand});
7368 const operand_ty = f.typeOf(reduce.operand);7449 const operand_ty = f.typeOf(reduce.operand);
7369 const writer = f.object.writer();7450 const bw = &f.object.code.buffered_writer;
73707451
7371 const use_operator = scalar_ty.bitSize(zcu) <= 64;7452 const use_operator = scalar_ty.bitSize(zcu) <= 64;
7372 const op: union(enum) {7453 const op: union(enum) {
...@@ -7413,10 +7494,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7413,10 +7494,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7413 // }7494 // }
74147495
7415 const accum = try f.allocLocal(inst, scalar_ty);7496 const accum = try f.allocLocal(inst, scalar_ty);
7416 try f.writeCValue(writer, accum, .Other);7497 try f.writeCValue(bw, accum, .Other);
7417 try writer.writeAll(" = ");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) {
7420 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {7501 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
7421 .bool => Value.false,7502 .bool => Value.false,
7422 .int => try pt.intValue(scalar_ty, 0),7503 .int => try pt.intValue(scalar_ty, 0),
...@@ -7453,42 +7534,44 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7453,42 +7534,44 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7453 else => unreachable,7534 else => unreachable,
7454 },7535 },
7455 }, .Other);7536 }, .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);7540 const v = try Vectorize.start(f, inst, bw, operand_ty);
7459 try f.writeCValue(writer, accum, .Other);7541 try f.writeCValue(bw, accum, .Other);
7460 switch (op) {7542 switch (op) {
7461 .builtin => |func| {7543 .builtin => |func| {
7462 try writer.print(" = zig_{s}_", .{func.operation});7544 try bw.print(" = zig_{s}_", .{func.operation});
7463 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);7545 try f.object.dg.renderTypeForBuiltinFnName(bw, scalar_ty);
7464 try writer.writeByte('(');7546 try bw.writeByte('(');
7465 try f.writeCValue(writer, accum, .FunctionArgument);7547 try f.writeCValue(bw, accum, .FunctionArgument);
7466 try writer.writeAll(", ");7548 try bw.writeAll(", ");
7467 try f.writeCValue(writer, operand, .Other);7549 try f.writeCValue(bw, operand, .Other);
7468 try v.elem(f, writer);7550 try v.elem(f, bw);
7469 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, func.info);7551 try f.object.dg.renderBuiltinInfo(bw, scalar_ty, func.info);
7470 try writer.writeByte(')');7552 try bw.writeByte(')');
7471 },7553 },
7472 .infix => |ass| {7554 .infix => |ass| {
7473 try writer.writeAll(ass);7555 try bw.writeAll(ass);
7474 try f.writeCValue(writer, operand, .Other);7556 try f.writeCValue(bw, operand, .Other);
7475 try v.elem(f, writer);7557 try v.elem(f, bw);
7476 },7558 },
7477 .ternary => |cmp| {7559 .ternary => |cmp| {
7478 try writer.writeAll(" = ");7560 try bw.writeAll(" = ");
7479 try f.writeCValue(writer, accum, .Other);7561 try f.writeCValue(bw, accum, .Other);
7480 try writer.writeAll(cmp);7562 try bw.writeAll(cmp);
7481 try f.writeCValue(writer, operand, .Other);7563 try f.writeCValue(bw, operand, .Other);
7482 try v.elem(f, writer);7564 try v.elem(f, bw);
7483 try writer.writeAll(" ? ");7565 try bw.writeAll(" ? ");
7484 try f.writeCValue(writer, accum, .Other);7566 try f.writeCValue(bw, accum, .Other);
7485 try writer.writeAll(" : ");7567 try bw.writeAll(" : ");
7486 try f.writeCValue(writer, operand, .Other);7568 try f.writeCValue(bw, operand, .Other);
7487 try v.elem(f, writer);7569 try v.elem(f, bw);
7488 },7570 },
7489 }7571 }
7490 try writer.writeAll(";\n");7572 try bw.writeByte(';');
7491 try v.end(f, inst, writer);7573 try f.object.newline();
7574 try v.end(f, inst, bw);
74927575
7493 return accum;7576 return accum;
7494}7577}
...@@ -7514,7 +7597,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7514,7 +7597,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7514 }7597 }
7515 }7598 }
75167599
7517 const writer = f.object.writer();7600 const bw = &f.object.code.buffered_writer;
7518 const local = try f.allocLocal(inst, inst_ty);7601 const local = try f.allocLocal(inst, inst_ty);
7519 switch (ip.indexToKey(inst_ty.toIntern())) {7602 switch (ip.indexToKey(inst_ty.toIntern())) {
7520 inline .array_type, .vector_type => |info, tag| {7603 inline .array_type, .vector_type => |info, tag| {
...@@ -7522,20 +7605,20 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7522,20 +7605,20 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7522 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),7605 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),
7523 };7606 };
7524 for (resolved_elements, 0..) |element, i| {7607 for (resolved_elements, 0..) |element, i| {
7525 try a.restart(f, writer);7608 try a.restart(f, bw);
7526 try f.writeCValue(writer, local, .Other);7609 try f.writeCValue(bw, local, .Other);
7527 try writer.print("[{d}]", .{i});7610 try bw.print("[{d}]", .{i});
7528 try a.assign(f, writer);7611 try a.assign(f, bw);
7529 try f.writeCValue(writer, element, .Other);7612 try f.writeCValue(bw, element, .Other);
7530 try a.end(f, writer);7613 try a.end(f, bw);
7531 }7614 }
7532 if (tag == .array_type and info.sentinel != .none) {7615 if (tag == .array_type and info.sentinel != .none) {
7533 try a.restart(f, writer);7616 try a.restart(f, bw);
7534 try f.writeCValue(writer, local, .Other);7617 try f.writeCValue(bw, local, .Other);
7535 try writer.print("[{d}]", .{info.len});7618 try bw.print("[{d}]", .{info.len});
7536 try a.assign(f, writer);7619 try a.assign(f, bw);
7537 try f.object.dg.renderValue(writer, Value.fromInterned(info.sentinel), .Other);7620 try f.object.dg.renderValue(bw, Value.fromInterned(info.sentinel), .Other);
7538 try a.end(f, writer);7621 try a.end(f, bw);
7539 }7622 }
7540 },7623 },
7541 .struct_type => {7624 .struct_type => {
...@@ -7547,19 +7630,19 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7547,19 +7630,19 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7547 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);7630 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
7548 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7631 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75497632
7550 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7633 const a = try Assignment.start(f, bw, try f.ctypeFromType(field_ty, .complete));
7551 try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|7634 try f.writeCValueMember(bw, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
7552 .{ .identifier = field_name.toSlice(ip) }7635 .{ .identifier = field_name.toSlice(ip) }
7553 else7636 else
7554 .{ .field = field_index });7637 .{ .field = field_index });
7555 try a.assign(f, writer);7638 try a.assign(f, bw);
7556 try f.writeCValue(writer, resolved_elements[field_index], .Other);7639 try f.writeCValue(bw, resolved_elements[field_index], .Other);
7557 try a.end(f, writer);7640 try a.end(f, bw);
7558 }7641 }
7559 },7642 },
7560 .@"packed" => {7643 .@"packed" => {
7561 try f.writeCValue(writer, local, .Other);7644 try f.writeCValue(bw, local, .Other);
7562 try writer.writeAll(" = ");7645 try bw.writeAll(" = ");
75637646
7564 const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));7647 const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));
7565 const int_info = backing_int_ty.intInfo(zcu);7648 const int_info = backing_int_ty.intInfo(zcu);
...@@ -7575,9 +7658,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7575,9 +7658,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7575 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7658 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75767659
7577 if (!empty) {7660 if (!empty) {
7578 try writer.writeAll("zig_or_");7661 try bw.writeAll("zig_or_");
7579 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7662 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7580 try writer.writeByte('(');7663 try bw.writeByte('(');
7581 }7664 }
7582 empty = false;7665 empty = false;
7583 }7666 }
...@@ -7587,57 +7670,58 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7587,57 +7670,58 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7587 const field_ty = inst_ty.fieldType(field_index, zcu);7670 const field_ty = inst_ty.fieldType(field_index, zcu);
7588 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7671 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75897672
7590 if (!empty) try writer.writeAll(", ");7673 if (!empty) try bw.writeAll(", ");
7591 // TODO: Skip this entire shift if val is 0?7674 // TODO: Skip this entire shift if val is 0?
7592 try writer.writeAll("zig_shlw_");7675 try bw.writeAll("zig_shlw_");
7593 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7676 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7594 try writer.writeByte('(');7677 try bw.writeByte('(');
75957678
7596 if (field_ty.isAbiInt(zcu)) {7679 if (field_ty.isAbiInt(zcu)) {
7597 try writer.writeAll("zig_and_");7680 try bw.writeAll("zig_and_");
7598 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7681 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_ty);
7599 try writer.writeByte('(');7682 try bw.writeByte('(');
7600 }7683 }
76017684
7602 if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {7685 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);
7604 } else {7687 } else {
7605 try writer.writeByte('(');7688 try bw.writeByte('(');
7606 try f.renderType(writer, inst_ty);7689 try f.renderType(bw, inst_ty);
7607 try writer.writeByte(')');7690 try bw.writeByte(')');
7608 if (field_ty.isPtrAtRuntime(zcu)) {7691 if (field_ty.isPtrAtRuntime(zcu)) {
7609 try writer.writeByte('(');7692 try bw.writeByte('(');
7610 try f.renderType(writer, switch (int_info.signedness) {7693 try f.renderType(bw, switch (int_info.signedness) {
7611 .unsigned => .usize,7694 .unsigned => .usize,
7612 .signed => .isize,7695 .signed => .isize,
7613 });7696 });
7614 try writer.writeByte(')');7697 try bw.writeByte(')');
7615 }7698 }
7616 try f.writeCValue(writer, element, .Other);7699 try f.writeCValue(bw, element, .Other);
7617 }7700 }
76187701
7619 if (field_ty.isAbiInt(zcu)) {7702 if (field_ty.isAbiInt(zcu)) {
7620 try writer.writeAll(", ");7703 try bw.writeAll(", ");
7621 const field_int_info = field_ty.intInfo(zcu);7704 const field_int_info = field_ty.intInfo(zcu);
7622 const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)7705 const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)
7623 try pt.intValue(backing_int_ty, -1)7706 try pt.intValue(backing_int_ty, -1)
7624 else7707 else
7625 try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);7708 try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);
7626 try f.object.dg.renderValue(writer, field_mask, .FunctionArgument);7709 try f.object.dg.renderValue(bw, field_mask, .FunctionArgument);
7627 try writer.writeByte(')');7710 try bw.writeByte(')');
7628 }7711 }
76297712
7630 try writer.print(", {}", .{7713 try bw.print(", {f}", .{
7631 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),7714 try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)),
7632 });7715 });
7633 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);7716 try f.object.dg.renderBuiltinInfo(bw, inst_ty, .bits);
7634 try writer.writeByte(')');7717 try bw.writeByte(')');
7635 if (!empty) try writer.writeByte(')');7718 if (!empty) try bw.writeByte(')');
76367719
7637 bit_offset += field_ty.bitSize(zcu);7720 bit_offset += field_ty.bitSize(zcu);
7638 empty = false;7721 empty = false;
7639 }7722 }
7640 try writer.writeAll(";\n");7723 try bw.writeByte(';');
7724 try f.object.newline();
7641 },7725 },
7642 }7726 }
7643 },7727 },
...@@ -7646,11 +7730,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7646,11 +7730,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7646 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);7730 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
7647 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7731 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
76487732
7649 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7733 const a = try Assignment.start(f, bw, try f.ctypeFromType(field_ty, .complete));
7650 try f.writeCValueMember(writer, local, .{ .field = field_index });7734 try f.writeCValueMember(bw, local, .{ .field = field_index });
7651 try a.assign(f, writer);7735 try a.assign(f, bw);
7652 try f.writeCValue(writer, resolved_elements[field_index], .Other);7736 try f.writeCValue(bw, resolved_elements[field_index], .Other);
7653 try a.end(f, writer);7737 try a.end(f, bw);
7654 },7738 },
7655 else => unreachable,7739 else => unreachable,
7656 }7740 }
...@@ -7672,7 +7756,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7672,7 +7756,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7672 const payload = try f.resolveInst(extra.init);7756 const payload = try f.resolveInst(extra.init);
7673 try reap(f, inst, &.{extra.init});7757 try reap(f, inst, &.{extra.init});
76747758
7675 const writer = f.object.writer();7759 const bw = &f.object.code.buffered_writer;
7676 const local = try f.allocLocal(inst, union_ty);7760 const local = try f.allocLocal(inst, union_ty);
7677 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);7761 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 {...@@ -7682,20 +7766,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7682 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;7766 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
7683 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);7767 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));7769 const a = try Assignment.start(f, bw, try f.ctypeFromType(tag_ty, .complete));
7686 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });7770 try f.writeCValueMember(bw, local, .{ .identifier = "tag" });
7687 try a.assign(f, writer);7771 try a.assign(f, bw);
7688 try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))});7772 try bw.print("{f}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))});
7689 try a.end(f, writer);7773 try a.end(f, bw);
7690 }7774 }
7691 break :field .{ .payload_identifier = field_name.toSlice(ip) };7775 break :field .{ .payload_identifier = field_name.toSlice(ip) };
7692 } else .{ .identifier = field_name.toSlice(ip) };7776 } else .{ .identifier = field_name.toSlice(ip) };
76937777
7694 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));7778 const a = try Assignment.start(f, bw, try f.ctypeFromType(payload_ty, .complete));
7695 try f.writeCValueMember(writer, local, field);7779 try f.writeCValueMember(bw, local, field);
7696 try a.assign(f, writer);7780 try a.assign(f, bw);
7697 try f.writeCValue(writer, payload, .Other);7781 try f.writeCValue(bw, payload, .Other);
7698 try a.end(f, writer);7782 try a.end(f, bw);
7699 return local;7783 return local;
7700}7784}
77017785
...@@ -7708,15 +7792,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7708,15 +7792,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7708 const ptr = try f.resolveInst(prefetch.ptr);7792 const ptr = try f.resolveInst(prefetch.ptr);
7709 try reap(f, inst, &.{prefetch.ptr});7793 try reap(f, inst, &.{prefetch.ptr});
77107794
7711 const writer = f.object.writer();7795 const bw = &f.object.code.buffered_writer;
7712 switch (prefetch.cache) {7796 switch (prefetch.cache) {
7713 .data => {7797 .data => {
7714 try writer.writeAll("zig_prefetch(");7798 try bw.writeAll("zig_prefetch(");
7715 if (ptr_ty.isSlice(zcu))7799 if (ptr_ty.isSlice(zcu))
7716 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" })7800 try f.writeCValueMember(bw, ptr, .{ .identifier = "ptr" })
7717 else7801 else
7718 try f.writeCValue(writer, ptr, .FunctionArgument);7802 try f.writeCValue(bw, ptr, .FunctionArgument);
7719 try writer.print(", {d}, {d});\n", .{ @intFromEnum(prefetch.rw), prefetch.locality });7803 try bw.print(", {d}, {d});", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7804 try f.object.newline();
7720 },7805 },
7721 // The available prefetch intrinsics do not accept a cache argument; only7806 // The available prefetch intrinsics do not accept a cache argument; only
7722 // address, rw, and locality.7807 // address, rw, and locality.
...@@ -7729,13 +7814,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7729,13 +7814,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7729fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {7814fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7730 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7815 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;
7733 const inst_ty = f.typeOfIndex(inst);7818 const inst_ty = f.typeOfIndex(inst);
7734 const local = try f.allocLocal(inst, inst_ty);7819 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(" = ");7822 try bw.writeAll(" = ");
7738 try writer.print("zig_wasm_memory_size({d});\n", .{pl_op.payload});7823 try bw.print("zig_wasm_memory_size({d});", .{pl_op.payload});
7824 try f.object.newline();
77397825
7740 return local;7826 return local;
7741}7827}
...@@ -7743,17 +7829,18 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7743,17 +7829,18 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7743fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {7829fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
7744 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7830 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;
7747 const inst_ty = f.typeOfIndex(inst);7833 const inst_ty = f.typeOfIndex(inst);
7748 const operand = try f.resolveInst(pl_op.operand);7834 const operand = try f.resolveInst(pl_op.operand);
7749 try reap(f, inst, &.{pl_op.operand});7835 try reap(f, inst, &.{pl_op.operand});
7750 const local = try f.allocLocal(inst, inst_ty);7836 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(" = ");7839 try bw.writeAll(" = ");
7754 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});7840 try bw.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
7755 try f.writeCValue(writer, operand, .FunctionArgument);7841 try f.writeCValue(bw, operand, .FunctionArgument);
7756 try writer.writeAll(");\n");7842 try bw.writeAll(");");
7843 try f.object.newline();
7757 return local;7844 return local;
7758}7845}
77597846
...@@ -7771,24 +7858,25 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7771,24 +7858,25 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7771 const inst_ty = f.typeOfIndex(inst);7858 const inst_ty = f.typeOfIndex(inst);
7772 const inst_scalar_ty = inst_ty.scalarType(zcu);7859 const inst_scalar_ty = inst_ty.scalarType(zcu);
77737860
7774 const writer = f.object.writer();7861 const bw = &f.object.code.buffered_writer;
7775 const local = try f.allocLocal(inst, inst_ty);7862 const local = try f.allocLocal(inst, inst_ty);
7776 const v = try Vectorize.start(f, inst, writer, inst_ty);7863 const v = try Vectorize.start(f, inst, bw, inst_ty);
7777 try f.writeCValue(writer, local, .Other);7864 try f.writeCValue(bw, local, .Other);
7778 try v.elem(f, writer);7865 try v.elem(f, bw);
7779 try writer.writeAll(" = zig_fma_");7866 try bw.writeAll(" = zig_fma_");
7780 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);7867 try f.object.dg.renderTypeForBuiltinFnName(bw, inst_scalar_ty);
7781 try writer.writeByte('(');7868 try bw.writeByte('(');
7782 try f.writeCValue(writer, mulend1, .FunctionArgument);7869 try f.writeCValue(bw, mulend1, .FunctionArgument);
7783 try v.elem(f, writer);7870 try v.elem(f, bw);
7784 try writer.writeAll(", ");7871 try bw.writeAll(", ");
7785 try f.writeCValue(writer, mulend2, .FunctionArgument);7872 try f.writeCValue(bw, mulend2, .FunctionArgument);
7786 try v.elem(f, writer);7873 try v.elem(f, bw);
7787 try writer.writeAll(", ");7874 try bw.writeAll(", ");
7788 try f.writeCValue(writer, addend, .FunctionArgument);7875 try f.writeCValue(bw, addend, .FunctionArgument);
7789 try v.elem(f, writer);7876 try v.elem(f, bw);
7790 try writer.writeAll(");\n");7877 try bw.writeAll(");");
7791 try v.end(f, inst, writer);7878 try f.object.newline();
7879 try v.end(f, inst, bw);
77927880
7793 return local;7881 return local;
7794}7882}
...@@ -7812,15 +7900,16 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7812,15 +7900,16 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7812 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;7900 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
7813 assert(function_info.varargs);7901 assert(function_info.varargs);
78147902
7815 const writer = f.object.writer();7903 const bw = &f.object.code.buffered_writer;
7816 const local = try f.allocLocal(inst, inst_ty);7904 const local = try f.allocLocal(inst, inst_ty);
7817 try writer.writeAll("va_start(*(va_list *)&");7905 try bw.writeAll("va_start(*(va_list *)&");
7818 try f.writeCValue(writer, local, .Other);7906 try f.writeCValue(bw, local, .Other);
7819 if (function_info.param_ctypes.len > 0) {7907 if (function_info.param_ctypes.len > 0) {
7820 try writer.writeAll(", ");7908 try bw.writeAll(", ");
7821 try f.writeCValue(writer, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);7909 try f.writeCValue(bw, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
7822 }7910 }
7823 try writer.writeAll(");\n");7911 try bw.writeAll(");");
7912 try f.object.newline();
7824 return local;7913 return local;
7825}7914}
78267915
...@@ -7831,14 +7920,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7831,14 +7920,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
7831 const va_list = try f.resolveInst(ty_op.operand);7920 const va_list = try f.resolveInst(ty_op.operand);
7832 try reap(f, inst, &.{ty_op.operand});7921 try reap(f, inst, &.{ty_op.operand});
78337922
7834 const writer = f.object.writer();7923 const bw = &f.object.code.buffered_writer;
7835 const local = try f.allocLocal(inst, inst_ty);7924 const local = try f.allocLocal(inst, inst_ty);
7836 try f.writeCValue(writer, local, .Other);7925 try f.writeCValue(bw, local, .Other);
7837 try writer.writeAll(" = va_arg(*(va_list *)");7926 try bw.writeAll(" = va_arg(*(va_list *)");
7838 try f.writeCValue(writer, va_list, .Other);7927 try f.writeCValue(bw, va_list, .Other);
7839 try writer.writeAll(", ");7928 try bw.writeAll(", ");
7840 try f.renderType(writer, ty_op.ty.toType());7929 try f.renderType(bw, ty_op.ty.toType());
7841 try writer.writeAll(");\n");7930 try bw.writeAll(");");
7931 try f.object.newline();
7842 return local;7932 return local;
7843}7933}
78447934
...@@ -7848,10 +7938,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7848,10 +7938,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
7848 const va_list = try f.resolveInst(un_op);7938 const va_list = try f.resolveInst(un_op);
7849 try reap(f, inst, &.{un_op});7939 try reap(f, inst, &.{un_op});
78507940
7851 const writer = f.object.writer();7941 const bw = &f.object.code.buffered_writer;
7852 try writer.writeAll("va_end(*(va_list *)");7942 try bw.writeAll("va_end(*(va_list *)");
7853 try f.writeCValue(writer, va_list, .Other);7943 try f.writeCValue(bw, va_list, .Other);
7854 try writer.writeAll(");\n");7944 try bw.writeAll(");");
7945 try f.object.newline();
7855 return .none;7946 return .none;
7856}7947}
78577948
...@@ -7862,13 +7953,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7862,13 +7953,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7862 const va_list = try f.resolveInst(ty_op.operand);7953 const va_list = try f.resolveInst(ty_op.operand);
7863 try reap(f, inst, &.{ty_op.operand});7954 try reap(f, inst, &.{ty_op.operand});
78647955
7865 const writer = f.object.writer();7956 const bw = &f.object.code.buffered_writer;
7866 const local = try f.allocLocal(inst, inst_ty);7957 const local = try f.allocLocal(inst, inst_ty);
7867 try writer.writeAll("va_copy(*(va_list *)&");7958 try bw.writeAll("va_copy(*(va_list *)&");
7868 try f.writeCValue(writer, local, .Other);7959 try f.writeCValue(bw, local, .Other);
7869 try writer.writeAll(", *(va_list *)");7960 try bw.writeAll(", *(va_list *)");
7870 try f.writeCValue(writer, va_list, .Other);7961 try f.writeCValue(bw, va_list, .Other);
7871 try writer.writeAll(");\n");7962 try bw.writeAll(");");
7963 try f.object.newline();
7872 return local;7964 return local;
7873}7965}
78747966
...@@ -7883,8 +7975,8 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {...@@ -7883,8 +7975,8 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
7883 };7975 };
7884}7976}
78857977
7886fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {7978fn writeMemoryOrder(bw: *std.io.BufferedWriter, order: std.builtin.AtomicOrder) !void {
7887 return w.writeAll(toMemoryOrder(order));7979 return bw.writeAll(toMemoryOrder(order));
7888}7980}
78897981
7890fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 {7982fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 {
...@@ -8027,8 +8119,7 @@ fn compareOperatorC(operator: std.math.CompareOperator) []const u8 {...@@ -8027,8 +8119,7 @@ fn compareOperatorC(operator: std.math.CompareOperator) []const u8 {
8027const StringLiteral = struct {8119const StringLiteral = struct {
8028 len: usize,8120 len: usize,
8029 cur_len: usize,8121 cur_len: usize,
8030 bytes_written: usize,8122 bw: *std.io.BufferedWriter,
8031 writer: *std.io.BufferedWriter,
80328123
8033 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,8124 // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal,
8034 // regardless of the length of the string literal initializing it. Array initializer syntax is8125 // regardless of the length of the string literal initializing it. Array initializer syntax is
...@@ -8041,65 +8132,62 @@ const StringLiteral = struct {...@@ -8041,65 +8132,62 @@ const StringLiteral = struct {
8041 const max_char_len = 4;8132 const max_char_len = 4;
8042 const max_literal_len = @min(16380 - max_char_len, 4095);8133 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 {
8045 return .{8136 return .{
8046 .cur_len = 0,8137 .cur_len = 0,
8047 .len = len,8138 .len = len,
8048 .writer = writer,8139 .bw = bw,
8049 .bytes_written = 0,
8050 };8140 };
8051 }8141 }
80528142
8053 pub fn start(self: *StringLiteral) std.io.Writer.Error!void {8143 pub fn start(sl: *StringLiteral) std.io.Writer.Error!void {
8054 const writer = self.writer;8144 if (sl.len <= max_string_initializer_len) {
8055 if (self.len <= max_string_initializer_len) {8145 try sl.bw.writeByte('\"');
8056 self.bytes_written += try writer.writeByteCount('\"');
8057 } else {8146 } else {
8058 self.bytes_written += try writer.writeByteCount('{');8147 try sl.bw.writeByte('{');
8059 }8148 }
8060 }8149 }
80618150
8062 pub fn end(self: *StringLiteral) std.io.Writer.Error!void {8151 pub fn end(sl: *StringLiteral) std.io.Writer.Error!void {
8063 const writer = self.writer;8152 if (sl.len <= max_string_initializer_len) {
8064 if (self.len <= max_string_initializer_len) {8153 try sl.bw.writeByte('\"');
8065 self.bytes_written += try writer.writeByteCount('\"');
8066 } else {8154 } else {
8067 self.bytes_written += try writer.writeByteCount('}');8155 try sl.bw.writeByte('}');
8068 }8156 }
8069 }8157 }
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 {
8072 switch (c) {8160 switch (c) {
8073 7 => return writer.writeAllCount("\\a"),8161 7 => try sl.bw.writeAll("\\a"),
8074 8 => return writer.writeAllCount("\\b"),8162 8 => try sl.bw.writeAll("\\b"),
8075 '\t' => return writer.writeAllCount("\\t"),8163 '\t' => try sl.bw.writeAll("\\t"),
8076 '\n' => return writer.writeAllCount("\\n"),8164 '\n' => try sl.bw.writeAll("\\n"),
8077 11 => return writer.writeAllCount("\\v"),8165 11 => try sl.bw.writeAll("\\v"),
8078 12 => return writer.writeAllCount("\\f"),8166 12 => try sl.bw.writeAll("\\f"),
8079 '\r' => return writer.writeAllCount("\\r"),8167 '\r' => try sl.bw.writeAll("\\r"),
8080 '"', '\'', '?', '\\' => return writer.printCount("\\{c}", .{c}),8168 '"', '\'', '?', '\\' => try sl.bw.print("\\{c}", .{c}),
8081 else => switch (c) {8169 else => switch (c) {
8082 ' '...'~' => return writer.writeByteCount(c),8170 ' '...'~' => try sl.bw.writeByte(c),
8083 else => return writer.printCount("\\{o:0>3}", .{c}),8171 else => try sl.bw.print("\\{o:0>3}", .{c}),
8084 },8172 },
8085 }8173 }
8086 }8174 }
80878175
8088 pub fn writeChar(self: *StringLiteral, c: u8) std.io.Writer.Error!void {8176 pub fn writeChar(sl: *StringLiteral, c: u8) std.io.Writer.Error!void {
8089 const writer = self.writer;8177 if (sl.len <= max_string_initializer_len) {
8090 if (self.len <= max_string_initializer_len) {8178 if (sl.cur_len == 0 and sl.bw.count > 1)
8091 if (self.cur_len == 0 and self.bytes_written > 1)8179 try sl.bw.writeAll("\"\"");
8092 self.bytes_written += try writer.writeAllCount("\"\"");
80938180
8094 const char_length = try writeStringLiteralChar(writer, c);8181 const count = sl.bw.count;
8095 self.bytes_written += char_length;8182 try sl.writeStringLiteralChar(c);
8096 assert(char_length <= max_char_len);8183 const char_len = sl.bw.count - count;
8097 self.cur_len += char_length;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;
8100 } else {8188 } else {
8101 if (self.bytes_written > 1) self.bytes_written += try writer.writeByteCount(',');8189 if (sl.bw.count > 1) try sl.bw.writeByte(',');
8102 self.bytes_written += try writer.printCount("'\\x{x}'", .{c});8190 try sl.bw.print("'\\x{x}'", .{c});
8103 }8191 }
8104 }8192 }
8105};8193};
...@@ -8107,13 +8195,12 @@ const StringLiteral = struct {...@@ -8107,13 +8195,12 @@ const StringLiteral = struct {
8107const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };8195const FormatStringContext = struct { str: []const u8, sentinel: ?u8 };
8108fn formatStringLiteral(8196fn formatStringLiteral(
8109 data: FormatStringContext,8197 data: FormatStringContext,
8198 bw: *std.io.BufferedWriter,
8110 comptime fmt: []const u8,8199 comptime fmt: []const u8,
8111 _: std.fmt.FormatOptions,8200) std.io.Writer.Error!void {
8112 writer: anytype,
8113) @TypeOf(writer).Error!void {
8114 if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt);8201 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));
8117 try literal.start();8204 try literal.start();
8118 for (data.str) |c| try literal.writeChar(c);8205 for (data.str) |c| try literal.writeChar(c);
8119 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);8206 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);
...@@ -8139,10 +8226,9 @@ const FormatIntLiteralContext = struct {...@@ -8139,10 +8226,9 @@ const FormatIntLiteralContext = struct {
8139};8226};
8140fn formatIntLiteral(8227fn formatIntLiteral(
8141 data: FormatIntLiteralContext,8228 data: FormatIntLiteralContext,
8229 bw: *std.io.BufferedWriter,
8142 comptime fmt: []const u8,8230 comptime fmt: []const u8,
8143 options: std.fmt.FormatOptions,8231) std.io.Writer.Error!void {
8144 writer: anytype,
8145) @TypeOf(writer).Error!void {
8146 const pt = data.dg.pt;8232 const pt = data.dg.pt;
8147 const zcu = pt.zcu;8233 const zcu = pt.zcu;
8148 const target = &data.dg.mod.resolved_target.result;8234 const target = &data.dg.mod.resolved_target.result;
...@@ -8167,7 +8253,7 @@ fn formatIntLiteral(...@@ -8167,7 +8253,7 @@ fn formatIntLiteral(
81678253
8168 var int_buf: Value.BigIntSpace = undefined;8254 var int_buf: Value.BigIntSpace = undefined;
8169 const int = if (data.val.isUndefDeep(zcu)) blk: {8255 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;
8171 @memset(undef_limbs, undefPattern(BigIntLimb));8257 @memset(undef_limbs, undefPattern(BigIntLimb));
81728258
8173 var undef_int = BigInt.Mutable{8259 var undef_int = BigInt.Mutable{
...@@ -8185,7 +8271,7 @@ fn formatIntLiteral(...@@ -8185,7 +8271,7 @@ fn formatIntLiteral(
8185 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();8271 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();
81868272
8187 var wrap = BigInt.Mutable{8273 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,
8189 .len = undefined,8275 .len = undefined,
8190 .positive = undefined,8276 .positive = undefined,
8191 };8277 };
...@@ -8222,30 +8308,30 @@ fn formatIntLiteral(...@@ -8222,30 +8308,30 @@ fn formatIntLiteral(
8222 if (c_limb_info.count == 1) {8308 if (c_limb_info.count == 1) {
8223 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or8309 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
8224 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))8310 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
8225 return writer.print("{s}_{s}", .{8311 return bw.print("{s}_{s}", .{
8226 data.ctype.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{8312 data.ctype.getStandardDefineAbbrev() orelse return bw.print("zig_{s}Int_{c}{d}", .{
8227 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,8313 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
8228 }),8314 }),
8229 if (int.positive) "MAX" else "MIN",8315 if (int.positive) "MAX" else "MIN",
8230 });8316 });
82318317
8232 if (!int.positive) try writer.writeByte('-');8318 if (!int.positive) try bw.writeByte('-');
8233 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);8319 try data.ctype.renderLiteralPrefix(bw, data.kind, ctype_pool);
82348320
8235 const style: struct { base: u8, case: std.fmt.Case = undefined } = switch (fmt.len) {8321 const style: struct { base: u8, case: std.fmt.Case = undefined } = switch (fmt.len) {
8236 0 => .{ .base = 10 },8322 0 => .{ .base = 10 },
8237 1 => switch (fmt[0]) {8323 1 => switch (fmt[0]) {
8238 'b' => style: {8324 'b' => style: {
8239 try writer.writeAll("0b");8325 try bw.writeAll("0b");
8240 break :style .{ .base = 2 };8326 break :style .{ .base = 2 };
8241 },8327 },
8242 'o' => style: {8328 'o' => style: {
8243 try writer.writeByte('0');8329 try bw.writeByte('0');
8244 break :style .{ .base = 8 };8330 break :style .{ .base = 8 };
8245 },8331 },
8246 'd' => .{ .base = 10 },8332 'd' => .{ .base = 10 },
8247 'x', 'X' => |base| style: {8333 'x', 'X' => |base| style: {
8248 try writer.writeAll("0x");8334 try bw.writeAll("0x");
8249 break :style .{ .base = 16, .case = switch (base) {8335 break :style .{ .base = 16, .case = switch (base) {
8250 'x' => .lower,8336 'x' => .lower,
8251 'X' => .upper,8337 'X' => .upper,
...@@ -8257,11 +8343,12 @@ fn formatIntLiteral(...@@ -8257,11 +8343,12 @@ fn formatIntLiteral(
8257 else => @compileError("Invalid fmt: " ++ fmt),8343 else => @compileError("Invalid fmt: " ++ fmt),
8258 };8344 };
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;
8261 defer allocator.free(string);8348 defer allocator.free(string);
8262 try writer.writeAll(string);8349 try bw.writeAll(string);
8263 } else {8350 } else {
8264 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);8351 try data.ctype.renderLiteralPrefix(bw, data.kind, ctype_pool);
8265 wrap.truncate(int, .unsigned, c_bits);8352 wrap.truncate(int, .unsigned, c_bits);
8266 @memset(wrap.limbs[wrap.len..], 0);8353 @memset(wrap.limbs[wrap.len..], 0);
8267 wrap.len = wrap.limbs.len;8354 wrap.len = wrap.limbs.len;
...@@ -8304,17 +8391,18 @@ fn formatIntLiteral(...@@ -8304,17 +8391,18 @@ fn formatIntLiteral(
8304 c_limb_ctype = c_limb_info.ctype;8391 c_limb_ctype = c_limb_info.ctype;
8305 }8392 }
83068393
8307 if (limb_offset > 0) try writer.writeAll(", ");8394 if (limb_offset > 0) try bw.writeAll(", ");
8308 try formatIntLiteral(.{8395 try formatIntLiteral(.{
8309 .dg = data.dg,8396 .dg = data.dg,
8310 .int_info = c_limb_int_info,8397 .int_info = c_limb_int_info,
8311 .kind = data.kind,8398 .kind = data.kind,
8312 .ctype = c_limb_ctype,8399 .ctype = c_limb_ctype,
8313 .val = try pt.intValue_big(.comptime_int, c_limb_mut.toConst()),8400 .val = pt.intValue_big(.comptime_int, c_limb_mut.toConst()) catch
8314 }, fmt, options, writer);8401 return error.WriteFailed,
8402 }, bw, fmt);
8315 }8403 }
8316 }8404 }
8317 try data.ctype.renderLiteralSuffix(writer, ctype_pool);8405 try data.ctype.renderLiteralSuffix(bw, ctype_pool);
8318}8406}
83198407
8320const Materialize = struct {8408const Materialize = struct {
...@@ -8328,8 +8416,8 @@ const Materialize = struct {...@@ -8328,8 +8416,8 @@ const Materialize = struct {
8328 } };8416 } };
8329 }8417 }
83308418
8331 pub fn mat(self: Materialize, f: *Function, writer: anytype) !void {8419 pub fn mat(self: Materialize, f: *Function, bw: *std.io.BufferedWriter) !void {
8332 try f.writeCValue(writer, self.local, .Other);8420 try f.writeCValue(bw, self.local, .Other);
8333 }8421 }
83348422
8335 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {8423 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
...@@ -8340,36 +8428,37 @@ const Materialize = struct {...@@ -8340,36 +8428,37 @@ const Materialize = struct {
8340const Assignment = struct {8428const Assignment = struct {
8341 ctype: CType,8429 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 {
8344 const self: Assignment = .{ .ctype = ctype };8432 const self: Assignment = .{ .ctype = ctype };
8345 try self.restart(f, writer);8433 try self.restart(f, bw);
8346 return self;8434 return self;
8347 }8435 }
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 {
8350 switch (self.strategy(f)) {8438 switch (self.strategy(f)) {
8351 .assign => {},8439 .assign => {},
8352 .memcpy => try writer.writeAll("memcpy("),8440 .memcpy => try bw.writeAll("memcpy("),
8353 }8441 }
8354 }8442 }
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 {
8357 switch (self.strategy(f)) {8445 switch (self.strategy(f)) {
8358 .assign => try writer.writeAll(" = "),8446 .assign => try bw.writeAll(" = "),
8359 .memcpy => try writer.writeAll(", "),8447 .memcpy => try bw.writeAll(", "),
8360 }8448 }
8361 }8449 }
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 {
8364 switch (self.strategy(f)) {8452 switch (self.strategy(f)) {
8365 .assign => {},8453 .assign => {},
8366 .memcpy => {8454 .memcpy => {
8367 try writer.writeAll(", sizeof(");8455 try bw.writeAll(", sizeof(");
8368 try f.renderCType(writer, self.ctype);8456 try f.renderCType(bw, self.ctype);
8369 try writer.writeAll("))");8457 try bw.writeAll("))");
8370 },8458 },
8371 }8459 }
8372 try writer.writeAll(";\n");8460 try bw.writeByte(';');
8461 try f.object.newline();
8373 }8462 }
83748463
8375 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {8464 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
...@@ -8383,7 +8472,7 @@ const Assignment = struct {...@@ -8383,7 +8472,7 @@ const Assignment = struct {
8383const Vectorize = struct {8472const Vectorize = struct {
8384 index: CValue = .none,8473 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 {
8387 const pt = f.object.dg.pt;8476 const pt = f.object.dg.pt;
8388 const zcu = pt.zcu;8477 const zcu = pt.zcu;
8389 return if (ty.zigTypeTag(zcu) == .vector) index: {8478 return if (ty.zigTypeTag(zcu) == .vector) index: {
...@@ -8391,29 +8480,31 @@ const Vectorize = struct {...@@ -8391,29 +8480,31 @@ const Vectorize = struct {
83918480
8392 try writer.writeAll("for (");8481 try writer.writeAll("for (");
8393 try f.writeCValue(writer, local, .Other);8482 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)});
8395 try f.writeCValue(writer, local, .Other);8484 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)))});
8397 try f.writeCValue(writer, local, .Other);8486 try f.writeCValue(writer, local, .Other);
8398 try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(.one_usize)});8487 try writer.print(" += {fd}) {{\n", .{try f.fmtIntLiteral(.one_usize)});
8399 f.object.indent_writer.pushIndent();8488 f.object.indent();
8489 try f.object.newline();
84008490
8401 break :index .{ .index = local };8491 break :index .{ .index = local };
8402 } else .{};8492 } else .{};
8403 }8493 }
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 {
8406 if (self.index != .none) {8496 if (self.index != .none) {
8407 try writer.writeByte('[');8497 try bw.writeByte('[');
8408 try f.writeCValue(writer, self.index, .Other);8498 try f.writeCValue(bw, self.index, .Other);
8409 try writer.writeByte(']');8499 try bw.writeByte(']');
8410 }8500 }
8411 }8501 }
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 {
8414 if (self.index != .none) {8504 if (self.index != .none) {
8415 f.object.indent_writer.popIndent();8505 f.object.outdent();
8416 try writer.writeAll("}\n");8506 try bw.writeByte('}');
8507 try f.object.newline();
8417 try freeLocal(f, inst, self.index.new_local, null);8508 try freeLocal(f, inst, self.index.new_local, null);
8418 }8509 }
8419 }8510 }
src/codegen/c/Type.zig+20-21
...@@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {...@@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {
209 };209 };
210}210}
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 {
213 switch (ctype.info(pool)) {213 switch (ctype.info(pool)) {
214 .basic => |basic_info| switch (basic_info) {214 .basic => |basic_info| switch (basic_info) {
215 .void => unreachable,215 .void => unreachable,
...@@ -224,7 +224,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con...@@ -224,7 +224,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
224 .uintptr_t,224 .uintptr_t,
225 .intptr_t,225 .intptr_t,
226 => switch (kind) {226 => switch (kind) {
227 else => try writer.print("({s})", .{@tagName(basic_info)}),227 else => try bw.print("({s})", .{@tagName(basic_info)}),
228 .global => {},228 .global => {},
229 },229 },
230 .int,230 .int,
...@@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con...@@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
246 .int32_t,246 .int32_t,
247 .uint64_t,247 .uint64_t,
248 .int64_t,248 .int64_t,
249 => try writer.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),249 => try bw.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),
250 .zig_u128,250 .zig_u128,
251 .zig_i128,251 .zig_i128,
252 .zig_f16,252 .zig_f16,
...@@ -255,7 +255,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con...@@ -255,7 +255,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
255 .zig_f80,255 .zig_f80,
256 .zig_f128,256 .zig_f128,
257 .zig_c_longdouble,257 .zig_c_longdouble,
258 => try writer.print("zig_{s}_{s}(", .{258 => try bw.print("zig_{s}_{s}(", .{
259 switch (kind) {259 switch (kind) {
260 else => "make",260 else => "make",
261 .global => "init",261 .global => "init",
...@@ -265,12 +265,12 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con...@@ -265,12 +265,12 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con
265 .va_list => unreachable,265 .va_list => unreachable,
266 _ => unreachable,266 _ => unreachable,
267 },267 },
268 .array, .vector => try writer.writeByte('{'),268 .array, .vector => try bw.writeByte('{'),
269 else => unreachable,269 else => unreachable,
270 }270 }
271}271}
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 {
274 switch (ctype.info(pool)) {274 switch (ctype.info(pool)) {
275 .basic => |basic_info| switch (basic_info) {275 .basic => |basic_info| switch (basic_info) {
276 .void => unreachable,276 .void => unreachable,
...@@ -280,20 +280,20 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty...@@ -280,20 +280,20 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty
280 .short,280 .short,
281 .int,281 .int,
282 => {},282 => {},
283 .long => try writer.writeByte('l'),283 .long => try bw.writeByte('l'),
284 .@"long long" => try writer.writeAll("ll"),284 .@"long long" => try bw.writeAll("ll"),
285 .@"unsigned char",285 .@"unsigned char",
286 .@"unsigned short",286 .@"unsigned short",
287 .@"unsigned int",287 .@"unsigned int",
288 => try writer.writeByte('u'),288 => try bw.writeByte('u'),
289 .@"unsigned long",289 .@"unsigned long",
290 .size_t,290 .size_t,
291 .uintptr_t,291 .uintptr_t,
292 => try writer.writeAll("ul"),292 => try bw.writeAll("ul"),
293 .@"unsigned long long" => try writer.writeAll("ull"),293 .@"unsigned long long" => try bw.writeAll("ull"),
294 .float => try writer.writeByte('f'),294 .float => try bw.writeByte('f'),
295 .double => {},295 .double => {},
296 .@"long double" => try writer.writeByte('l'),296 .@"long double" => try bw.writeByte('l'),
297 .bool,297 .bool,
298 .ptrdiff_t,298 .ptrdiff_t,
299 .intptr_t,299 .intptr_t,
...@@ -314,11 +314,11 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty...@@ -314,11 +314,11 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty
314 .zig_f80,314 .zig_f80,
315 .zig_f128,315 .zig_f128,
316 .zig_c_longdouble,316 .zig_c_longdouble,
317 => try writer.writeByte(')'),317 => try bw.writeByte(')'),
318 .va_list => unreachable,318 .va_list => unreachable,
319 _ => unreachable,319 _ => unreachable,
320 },320 },
321 .array, .vector => try writer.writeByte('}'),321 .array, .vector => try bw.writeByte('}'),
322 else => unreachable,322 else => unreachable,
323 }323 }
324}324}
...@@ -940,15 +940,14 @@ pub const Pool = struct {...@@ -940,15 +940,14 @@ pub const Pool = struct {
940 const FormatData = struct { string: String, pool: *const Pool };940 const FormatData = struct { string: String, pool: *const Pool };
941 fn format(941 fn format(
942 data: FormatData,942 data: FormatData,
943 bw: *std.io.BufferedWriter,
943 comptime fmt_str: []const u8,944 comptime fmt_str: []const u8,
944 _: std.fmt.FormatOptions,945 ) std.io.Writer.Error!void {
945 writer: anytype,
946 ) @TypeOf(writer).Error!void {
947 if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");946 if (fmt_str.len > 0) @compileError("invalid format string '" ++ fmt_str ++ "'");
948 if (data.string.toSlice(data.pool)) |slice|947 if (data.string.toSlice(data.pool)) |slice|
949 try writer.writeAll(slice)948 try bw.writeAll(slice)
950 else949 else
951 try writer.print("f{d}", .{@intFromEnum(data.string.index)});950 try bw.print("f{d}", .{@intFromEnum(data.string.index)});
952 }951 }
953 pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {952 pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {
954 return .{ .data = .{ .string = str, .pool = pool } };953 return .{ .data = .{ .string = str, .pool = pool } };
...@@ -2890,7 +2889,7 @@ pub const Pool = struct {...@@ -2890,7 +2889,7 @@ pub const Pool = struct {
2890 comptime fmt_str: []const u8,2889 comptime fmt_str: []const u8,
2891 fmt_args: anytype,2890 fmt_args: anytype,
2892 ) !String {2891 ) !String {
2893 try pool.string_bytes.writer(allocator).print(fmt_str, fmt_args);2892 try pool.string_bytes.print(allocator, fmt_str, fmt_args);
2894 return pool.trailingString(allocator);2893 return pool.trailingString(allocator);
2895 }2894 }
28962895
src/codegen/spirv.zig+1
...@@ -1262,6 +1262,7 @@ const NavGen = struct {...@@ -1262,6 +1262,7 @@ const NavGen = struct {
1262 fn resolveTypeName(self: *NavGen, ty: Type) Allocator.Error![]const u8 {1262 fn resolveTypeName(self: *NavGen, ty: Type) Allocator.Error![]const u8 {
1263 var aw: std.io.AllocatingWriter = undefined;1263 var aw: std.io.AllocatingWriter = undefined;
1264 aw.init(self.gpa);1264 aw.init(self.gpa);
1265 defer aw.deinit();
1265 ty.print(&aw.buffered_writer, self.pt) catch return error.OutOfMemory;1266 ty.print(&aw.buffered_writer, self.pt) catch return error.OutOfMemory;
1266 return aw.toOwnedSlice();1267 return aw.toOwnedSlice();
1267 }1268 }
src/link.zig+3-3
...@@ -1038,7 +1038,7 @@ pub const File = struct {...@@ -1038,7 +1038,7 @@ pub const File = struct {
1038 var fr = file.reader();1038 var fr = file.reader();
1039 var br = fr.interface().unbuffered();1039 var br = fr.interface().unbuffered();
1040 br.readSlice(buf) catch |err| switch (err) {1040 br.readSlice(buf) catch |err| switch (err) {
1041 error.ReadFailed => if (fr.err) |_| unreachable else |e| return e,1041 error.ReadFailed => return fr.err.?,
1042 error.EndOfStream => return error.UnexpectedEndOfFile,1042 error.EndOfStream => return error.UnexpectedEndOfFile,
1043 };1043 };
1044 var ld_script = try LdScript.parse(gpa, diags, path, buf);1044 var ld_script = try LdScript.parse(gpa, diags, path, buf);
...@@ -2107,7 +2107,7 @@ fn resolvePathInputLib(...@@ -2107,7 +2107,7 @@ fn resolvePathInputLib(
2107 br.readSlice(ld_script_bytes.items) catch |err| switch (err) {2107 br.readSlice(ld_script_bytes.items) catch |err| switch (err) {
2108 error.ReadFailed => fatal("failed to read '{f'}': {s}", .{2108 error.ReadFailed => fatal("failed to read '{f'}': {s}", .{
2109 test_path,2109 test_path,
2110 @errorName(if (fr.err) |_| unreachable else |e| e),2110 @errorName(fr.err.?),
2111 }),2111 }),
2112 error.EndOfStream => break :ok,2112 error.EndOfStream => break :ok,
2113 };2113 };
...@@ -2124,7 +2124,7 @@ fn resolvePathInputLib(...@@ -2124,7 +2124,7 @@ fn resolvePathInputLib(
2124 fatal("{f}: linker script too big", .{test_path});2124 fatal("{f}: linker script too big", .{test_path});
2125 try ld_script_bytes.resize(gpa, size);2125 try ld_script_bytes.resize(gpa, size);
2126 br.readSlice(ld_script_bytes.items[@intCast(fr.pos)..]) catch |err| switch (err) {2126 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.?) }),
2128 error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}),2128 error.EndOfStream => fatal("failed to read {f}: unexpected end of file", .{test_path}),
2129 };2129 };
2130 var diags: Diags = .init(gpa);2130 var diags: Diags = .init(gpa);