authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-02 07:55:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-02 07:55:25-07:00
log14678451848a6683904c24f75333699b4d166a46
tree75de5b34b8a8a298a2e1525aa28340ee0399616b
parent665737d845a5fc5a9182541cbe47643ee6d9f3f6

sync


5 files changed, 143 insertions(+), 154 deletions(-)

src/Air/print.zig+3-3
...@@ -78,9 +78,9 @@ pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {...@@ -78,9 +78,9 @@ pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
78}78}
7979
80pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {80pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void {
81 var bw = std.debug.lockStdErr2(&.{});81 const stderr_bw = std.debug.lockStderrWriter(&.{});
82 defer std.debug.unlockStdErr();82 defer std.debug.unlockStderrWriter();
83 air.writeInst(&bw, inst, pt, liveness);83 air.writeInst(stderr_bw, inst, pt, liveness);
84}84}
8585
86const Writer = struct {86const Writer = struct {
src/Zcu/PerThread.zig+10-10
...@@ -251,9 +251,9 @@ pub fn updateFile(...@@ -251,9 +251,9 @@ pub fn updateFile(
251251
252 const source = try gpa.allocSentinel(u8, @intCast(stat.size), 0);252 const source = try gpa.allocSentinel(u8, @intCast(stat.size), 0);
253 defer if (file.source == null) gpa.free(source);253 defer if (file.source == null) gpa.free(source);
254 var source_fr = source_file.reader();254 var source_fr = source_file.reader(&.{});
255 var source_br = source_fr.interface().unbuffered();255 source_fr.size = stat.size;
256 source_br.readSlice(source) catch |err| switch (err) {256 source_fr.interface.readSliceAll(source) catch |err| switch (err) {
257 error.ReadFailed => return source_fr.err.?,257 error.ReadFailed => return source_fr.err.?,
258 error.EndOfStream => return error.UnexpectedEndOfFile,258 error.EndOfStream => return error.UnexpectedEndOfFile,
259 };259 };
...@@ -344,8 +344,8 @@ fn loadZirZoirCache(...@@ -344,8 +344,8 @@ fn loadZirZoirCache(
344 };344 };
345345
346 var buffer: [@sizeOf(Header)]u8 = undefined;346 var buffer: [@sizeOf(Header)]u8 = undefined;
347 var cache_fr = cache_file.reader();347 var cache_fr = cache_file.reader(&buffer);
348 var cache_br = cache_fr.interface().buffered(&buffer);348 const cache_br = &cache_fr.interface;
349349
350 // First we read the header to determine the lengths of arrays.350 // First we read the header to determine the lengths of arrays.
351 const header = (cache_br.takeStruct(Header) catch |err| switch (err) {351 const header = (cache_br.takeStruct(Header) catch |err| switch (err) {
...@@ -366,12 +366,12 @@ fn loadZirZoirCache(...@@ -366,12 +366,12 @@ fn loadZirZoirCache(
366 }366 }
367367
368 switch (mode) {368 switch (mode) {
369 .zig => file.zir = Zcu.loadZirCacheBody(gpa, header, &cache_br) catch |err| switch (err) {369 .zig => file.zir = Zcu.loadZirCacheBody(gpa, header, cache_br) catch |err| switch (err) {
370 error.ReadFailed => return cache_fr.err.?,370 error.ReadFailed => return cache_fr.err.?,
371 error.EndOfStream => return .truncated,371 error.EndOfStream => return .truncated,
372 else => |e| return e,372 else => |e| return e,
373 },373 },
374 .zon => file.zoir = Zcu.loadZoirCacheBody(gpa, header, &cache_br) catch |err| switch (err) {374 .zon => file.zoir = Zcu.loadZoirCacheBody(gpa, header, cache_br) catch |err| switch (err) {
375 error.ReadFailed => return cache_fr.err.?,375 error.ReadFailed => return cache_fr.err.?,
376 error.EndOfStream => return .truncated,376 error.EndOfStream => return .truncated,
377 else => |e| return e,377 else => |e| return e,
...@@ -2439,9 +2439,9 @@ fn updateEmbedFileInner(...@@ -2439,9 +2439,9 @@ fn updateEmbedFileInner(
2439 const old_len = strings.mutate.len;2439 const old_len = strings.mutate.len;
2440 errdefer strings.shrinkRetainingCapacity(old_len);2440 errdefer strings.shrinkRetainingCapacity(old_len);
2441 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];2441 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];
2442 var fr = file.reader();2442 var fr = file.reader(&.{});
2443 var br = fr.interface().unbuffered();2443 fr.size = stat.size;
2444 br.readSlice(bytes[0..size]) catch |err| switch (err) {2444 fr.interface.readSliceAll(bytes[0..size]) catch |err| switch (err) {
2445 error.ReadFailed => return fr.err.?,2445 error.ReadFailed => return fr.err.?,
2446 error.EndOfStream => return error.UnexpectedEof,2446 error.EndOfStream => return error.UnexpectedEof,
2447 };2447 };
src/arch/x86_64/encoder.zig+107-115
...@@ -227,89 +227,81 @@ pub const Instruction = struct {...@@ -227,89 +227,81 @@ pub const Instruction = struct {
227 };227 };
228 }228 }
229229
230 fn format(op: Operand, bw: *Writer, comptime unused_format_string: []const u8) !void {230 const Format = struct {
231 _ = op;
232 _ = bw;
233 _ = unused_format_string;
234 @compileError("do not format Operand directly; use fmt() instead");
235 }
236
237 const FormatContext = struct {
238 op: Operand,231 op: Operand,
239 enc_op: Encoding.Op,232 enc_op: Encoding.Op,
240 };
241233
242 fn fmtContext(ctx: FormatContext, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {234 fn default(f: Format, w: *Writer) Writer.Error!void {
243 _ = unused_format_string;235 const op = f.op;
244 const op = ctx.op;236 const enc_op = f.enc_op;
245 const enc_op = ctx.enc_op;237 switch (op) {
246 switch (op) {238 .none => {},
247 .none => {},239 .reg => |reg| try w.writeAll(@tagName(reg)),
248 .reg => |reg| try bw.writeAll(@tagName(reg)),240 .mem => |mem| switch (mem) {
249 .mem => |mem| switch (mem) {241 .rip => |rip| {
250 .rip => |rip| {242 try w.print("{f} [rip", .{rip.ptr_size});
251 try bw.print("{f} [rip", .{rip.ptr_size});243 if (rip.disp != 0) try w.print(" {c} 0x{x}", .{
252 if (rip.disp != 0) try bw.print(" {c} 0x{x}", .{244 @as(u8, if (rip.disp < 0) '-' else '+'),
253 @as(u8, if (rip.disp < 0) '-' else '+'),245 @abs(rip.disp),
254 @abs(rip.disp),246 });
255 });247 try w.writeByte(']');
256 try bw.writeByte(']');248 },
257 },249 .sib => |sib| {
258 .sib => |sib| {250 try w.print("{f} ", .{sib.ptr_size});
259 try bw.print("{f} ", .{sib.ptr_size});
260251
261 if (mem.isSegmentRegister()) {252 if (mem.isSegmentRegister()) {
262 return bw.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp });253 return w.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp });
263 }254 }
264255
265 try bw.writeByte('[');256 try w.writeByte('[');
266257
267 var any = true;258 var any = true;
268 switch (sib.base) {259 switch (sib.base) {
269 .none => any = false,260 .none => any = false,
270 .reg => |reg| try bw.print("{s}", .{@tagName(reg)}),261 .reg => |reg| try w.print("{s}", .{@tagName(reg)}),
271 .frame => |frame_index| try bw.print("{}", .{frame_index}),262 .frame => |frame_index| try w.print("{}", .{frame_index}),
272 .table => try bw.print("Table", .{}),263 .table => try w.print("Table", .{}),
273 .rip_inst => |inst_index| try bw.print("RipInst({d})", .{inst_index}),264 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
274 .nav => |nav| try bw.print("Nav({d})", .{@intFromEnum(nav)}),265 .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),
275 .uav => |uav| try bw.print("Uav({d})", .{@intFromEnum(uav.val)}),266 .uav => |uav| try w.print("Uav({d})", .{@intFromEnum(uav.val)}),
276 .lazy_sym => |lazy_sym| try bw.print("LazySym({s}, {d})", .{267 .lazy_sym => |lazy_sym| try w.print("LazySym({s}, {d})", .{
277 @tagName(lazy_sym.kind),268 @tagName(lazy_sym.kind),
278 @intFromEnum(lazy_sym.ty),269 @intFromEnum(lazy_sym.ty),
279 }),270 }),
280 .extern_func => |extern_func| try bw.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),271 .extern_func => |extern_func| try w.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
281 }272 }
282 if (mem.scaleIndex()) |si| {273 if (mem.scaleIndex()) |si| {
283 if (any) try bw.writeAll(" + ");274 if (any) try w.writeAll(" + ");
284 try bw.print("{s} * {d}", .{ @tagName(si.index), si.scale });275 try w.print("{s} * {d}", .{ @tagName(si.index), si.scale });
285 any = true;276 any = true;
286 }277 }
287 if (sib.disp != 0 or !any) {278 if (sib.disp != 0 or !any) {
288 if (any)279 if (any)
289 try bw.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')})280 try w.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')})
290 else if (sib.disp < 0)281 else if (sib.disp < 0)
291 try bw.writeByte('-');282 try w.writeByte('-');
292 try bw.print("0x{x}", .{@abs(sib.disp)});283 try w.print("0x{x}", .{@abs(sib.disp)});
293 any = true;284 any = true;
294 }285 }
295286
296 try bw.writeByte(']');287 try w.writeByte(']');
288 },
289 .moffs => |moffs| try w.print("{s}:0x{x}", .{
290 @tagName(moffs.seg),
291 moffs.offset,
292 }),
297 },293 },
298 .moffs => |moffs| try bw.print("{s}:0x{x}", .{294 .imm => |imm| if (enc_op.isSigned()) {
299 @tagName(moffs.seg),295 const imms = imm.asSigned(enc_op.immBitSize());
300 moffs.offset,296 if (imms < 0) try w.writeByte('-');
301 }),297 try w.print("0x{x}", .{@abs(imms)});
302 },298 } else try w.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}),
303 .imm => |imm| if (enc_op.isSigned()) {299 .bytes => unreachable,
304 const imms = imm.asSigned(enc_op.immBitSize());300 }
305 if (imms < 0) try bw.writeByte('-');
306 try bw.print("0x{x}", .{@abs(imms)});
307 } else try bw.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}),
308 .bytes => unreachable,
309 }301 }
310 }302 };
311303
312 pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(fmtContext) {304 pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(Format, Format.default) {
313 return .{ .data = .{ .op = op, .enc_op = enc_op } };305 return .{ .data = .{ .op = op, .enc_op = enc_op } };
314 }306 }
315 };307 };
...@@ -361,23 +353,23 @@ pub const Instruction = struct {...@@ -361,23 +353,23 @@ pub const Instruction = struct {
361 return inst;353 return inst;
362 }354 }
363355
364 pub fn format(inst: Instruction, bw: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {356 pub fn format(inst: Instruction, w: *Writer, comptime unused_format_string: []const u8) Writer.Error!void {
365 _ = unused_format_string;357 comptime assert(unused_format_string.len == 0);
366 switch (inst.prefix) {358 switch (inst.prefix) {
367 .none, .directive => {},359 .none, .directive => {},
368 else => try bw.print("{s} ", .{@tagName(inst.prefix)}),360 else => try w.print("{s} ", .{@tagName(inst.prefix)}),
369 }361 }
370 try bw.print("{s}", .{@tagName(inst.encoding.mnemonic)});362 try w.print("{s}", .{@tagName(inst.encoding.mnemonic)});
371 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {363 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {
372 if (op == .none) break;364 if (op == .none) break;
373 if (i > 0) try bw.writeByte(',');365 if (i > 0) try w.writeByte(',');
374 try bw.print(" {f}", .{op.fmt(enc)});366 try w.print(" {f}", .{op.fmt(enc)});
375 }367 }
376 }368 }
377369
378 pub fn encode(inst: Instruction, bw: *Writer, comptime opts: Options) !void {370 pub fn encode(inst: Instruction, w: *Writer, comptime opts: Options) !void {
379 assert(inst.prefix != .directive);371 assert(inst.prefix != .directive);
380 const encoder: Encoder(opts) = .{ .bw = bw };372 const encoder: Encoder(opts) = .{ .w = w };
381 const enc = inst.encoding;373 const enc = inst.encoding;
382 const data = enc.data;374 const data = enc.data;
383375
...@@ -785,7 +777,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool...@@ -785,7 +777,7 @@ pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool
785777
786fn Encoder(comptime opts: Options) type {778fn Encoder(comptime opts: Options) type {
787 return struct {779 return struct {
788 bw: *Writer,780 w: *Writer,
789781
790 const Self = @This();782 const Self = @This();
791 pub const options = opts;783 pub const options = opts;
...@@ -800,31 +792,31 @@ fn Encoder(comptime opts: Options) type {...@@ -800,31 +792,31 @@ fn Encoder(comptime opts: Options) type {
800 // Hopefully this path isn't taken very often, so we'll do it the slow way for now792 // Hopefully this path isn't taken very often, so we'll do it the slow way for now
801793
802 // LOCK794 // LOCK
803 if (prefixes.prefix_f0) try self.bw.writeByte(0xf0);795 if (prefixes.prefix_f0) try self.w.writeByte(0xf0);
804 // REPNZ, REPNE, REP, Scalar Double-precision796 // REPNZ, REPNE, REP, Scalar Double-precision
805 if (prefixes.prefix_f2) try self.bw.writeByte(0xf2);797 if (prefixes.prefix_f2) try self.w.writeByte(0xf2);
806 // REPZ, REPE, REP, Scalar Single-precision798 // REPZ, REPE, REP, Scalar Single-precision
807 if (prefixes.prefix_f3) try self.bw.writeByte(0xf3);799 if (prefixes.prefix_f3) try self.w.writeByte(0xf3);
808800
809 // CS segment override or Branch not taken801 // CS segment override or Branch not taken
810 if (prefixes.prefix_2e) try self.bw.writeByte(0x2e);802 if (prefixes.prefix_2e) try self.w.writeByte(0x2e);
811 // DS segment override803 // DS segment override
812 if (prefixes.prefix_36) try self.bw.writeByte(0x36);804 if (prefixes.prefix_36) try self.w.writeByte(0x36);
813 // ES segment override805 // ES segment override
814 if (prefixes.prefix_26) try self.bw.writeByte(0x26);806 if (prefixes.prefix_26) try self.w.writeByte(0x26);
815 // FS segment override807 // FS segment override
816 if (prefixes.prefix_64) try self.bw.writeByte(0x64);808 if (prefixes.prefix_64) try self.w.writeByte(0x64);
817 // GS segment override809 // GS segment override
818 if (prefixes.prefix_65) try self.bw.writeByte(0x65);810 if (prefixes.prefix_65) try self.w.writeByte(0x65);
819811
820 // Branch taken812 // Branch taken
821 if (prefixes.prefix_3e) try self.bw.writeByte(0x3e);813 if (prefixes.prefix_3e) try self.w.writeByte(0x3e);
822814
823 // Operand size override815 // Operand size override
824 if (prefixes.prefix_66) try self.bw.writeByte(0x66);816 if (prefixes.prefix_66) try self.w.writeByte(0x66);
825817
826 // Address size override818 // Address size override
827 if (prefixes.prefix_67) try self.bw.writeByte(0x67);819 if (prefixes.prefix_67) try self.w.writeByte(0x67);
828 }820 }
829 }821 }
830822
...@@ -832,7 +824,7 @@ fn Encoder(comptime opts: Options) type {...@@ -832,7 +824,7 @@ fn Encoder(comptime opts: Options) type {
832 ///824 ///
833 /// Note that this flag is overridden by REX.W, if both are present.825 /// Note that this flag is overridden by REX.W, if both are present.
834 pub fn prefix16BitMode(self: Self) !void {826 pub fn prefix16BitMode(self: Self) !void {
835 try self.bw.writeByte(0x66);827 try self.w.writeByte(0x66);
836 }828 }
837829
838 /// Encodes a REX prefix byte given all the fields830 /// Encodes a REX prefix byte given all the fields
...@@ -851,7 +843,7 @@ fn Encoder(comptime opts: Options) type {...@@ -851,7 +843,7 @@ fn Encoder(comptime opts: Options) type {
851 if (fields.x) byte |= 0b0010;843 if (fields.x) byte |= 0b0010;
852 if (fields.b) byte |= 0b0001;844 if (fields.b) byte |= 0b0001;
853845
854 try self.bw.writeByte(byte);846 try self.w.writeByte(byte);
855 }847 }
856848
857 /// Encodes a VEX prefix given all the fields849 /// Encodes a VEX prefix given all the fields
...@@ -859,24 +851,24 @@ fn Encoder(comptime opts: Options) type {...@@ -859,24 +851,24 @@ fn Encoder(comptime opts: Options) type {
859 /// See struct `Vex` for a description of each field.851 /// See struct `Vex` for a description of each field.
860 pub fn vex(self: Self, fields: Vex) !void {852 pub fn vex(self: Self, fields: Vex) !void {
861 if (fields.is3Byte()) {853 if (fields.is3Byte()) {
862 try self.bw.writeByte(0b1100_0100);854 try self.w.writeByte(0b1100_0100);
863855
864 try self.bw.writeByte(856 try self.w.writeByte(
865 @as(u8, ~@intFromBool(fields.r)) << 7 |857 @as(u8, ~@intFromBool(fields.r)) << 7 |
866 @as(u8, ~@intFromBool(fields.x)) << 6 |858 @as(u8, ~@intFromBool(fields.x)) << 6 |
867 @as(u8, ~@intFromBool(fields.b)) << 5 |859 @as(u8, ~@intFromBool(fields.b)) << 5 |
868 @as(u8, @intFromEnum(fields.m)) << 0,860 @as(u8, @intFromEnum(fields.m)) << 0,
869 );861 );
870862
871 try self.bw.writeByte(863 try self.w.writeByte(
872 @as(u8, @intFromBool(fields.w)) << 7 |864 @as(u8, @intFromBool(fields.w)) << 7 |
873 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |865 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |
874 @as(u8, @intFromBool(fields.l)) << 2 |866 @as(u8, @intFromBool(fields.l)) << 2 |
875 @as(u8, @intFromEnum(fields.p)) << 0,867 @as(u8, @intFromEnum(fields.p)) << 0,
876 );868 );
877 } else {869 } else {
878 try self.bw.writeByte(0b1100_0101);870 try self.w.writeByte(0b1100_0101);
879 try self.bw.writeByte(871 try self.w.writeByte(
880 @as(u8, ~@intFromBool(fields.r)) << 7 |872 @as(u8, ~@intFromBool(fields.r)) << 7 |
881 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |873 @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 |
882 @as(u8, @intFromBool(fields.l)) << 2 |874 @as(u8, @intFromBool(fields.l)) << 2 |
...@@ -891,7 +883,7 @@ fn Encoder(comptime opts: Options) type {...@@ -891,7 +883,7 @@ fn Encoder(comptime opts: Options) type {
891883
892 /// Encodes a 1 byte opcode884 /// Encodes a 1 byte opcode
893 pub fn opcode_1byte(self: Self, opcode: u8) !void {885 pub fn opcode_1byte(self: Self, opcode: u8) !void {
894 try self.bw.writeByte(opcode);886 try self.w.writeByte(opcode);
895 }887 }
896888
897 /// Encodes a 2 byte opcode889 /// Encodes a 2 byte opcode
...@@ -900,7 +892,7 @@ fn Encoder(comptime opts: Options) type {...@@ -900,7 +892,7 @@ fn Encoder(comptime opts: Options) type {
900 ///892 ///
901 /// encoder.opcode_2byte(0x0f, 0xaf);893 /// encoder.opcode_2byte(0x0f, 0xaf);
902 pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void {894 pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void {
903 try self.bw.writeAll(&.{ prefix, opcode });895 try self.w.writeAll(&.{ prefix, opcode });
904 }896 }
905897
906 /// Encodes a 3 byte opcode898 /// Encodes a 3 byte opcode
...@@ -909,7 +901,7 @@ fn Encoder(comptime opts: Options) type {...@@ -909,7 +901,7 @@ fn Encoder(comptime opts: Options) type {
909 ///901 ///
910 /// encoder.opcode_3byte(0xf2, 0x0f, 0x10);902 /// encoder.opcode_3byte(0xf2, 0x0f, 0x10);
911 pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void {903 pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void {
912 try self.bw.writeAll(&.{ prefix_1, prefix_2, opcode });904 try self.w.writeAll(&.{ prefix_1, prefix_2, opcode });
913 }905 }
914906
915 /// Encodes a 1 byte opcode with a reg field907 /// Encodes a 1 byte opcode with a reg field
...@@ -917,7 +909,7 @@ fn Encoder(comptime opts: Options) type {...@@ -917,7 +909,7 @@ fn Encoder(comptime opts: Options) type {
917 /// Remember to add a REX prefix byte if reg is extended!909 /// Remember to add a REX prefix byte if reg is extended!
918 pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void {910 pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void {
919 assert(opcode & 0b111 == 0);911 assert(opcode & 0b111 == 0);
920 try self.bw.writeByte(opcode | reg);912 try self.w.writeByte(opcode | reg);
921 }913 }
922914
923 // ------915 // ------
...@@ -928,7 +920,7 @@ fn Encoder(comptime opts: Options) type {...@@ -928,7 +920,7 @@ fn Encoder(comptime opts: Options) type {
928 ///920 ///
929 /// Remember to add a REX prefix byte if reg or rm are extended!921 /// Remember to add a REX prefix byte if reg or rm are extended!
930 pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void {922 pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void {
931 try self.bw.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm);923 try self.w.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm);
932 }924 }
933925
934 /// Construct a ModR/M byte using direct r/m addressing926 /// Construct a ModR/M byte using direct r/m addressing
...@@ -1014,7 +1006,7 @@ fn Encoder(comptime opts: Options) type {...@@ -1014,7 +1006,7 @@ fn Encoder(comptime opts: Options) type {
1014 ///1006 ///
1015 /// Remember to add a REX prefix byte if index or base are extended!1007 /// Remember to add a REX prefix byte if index or base are extended!
1016 pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void {1008 pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void {
1017 try self.bw.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base);1009 try self.w.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base);
1018 }1010 }
10191011
1020 /// Construct a SIB byte with scale * index + base, no frills.1012 /// Construct a SIB byte with scale * index + base, no frills.
...@@ -1106,42 +1098,42 @@ fn Encoder(comptime opts: Options) type {...@@ -1106,42 +1098,42 @@ fn Encoder(comptime opts: Options) type {
1106 ///1098 ///
1107 /// It is sign-extended to 64 bits by the cpu.1099 /// It is sign-extended to 64 bits by the cpu.
1108 pub fn disp8(self: Self, disp: i8) !void {1100 pub fn disp8(self: Self, disp: i8) !void {
1109 try self.bw.writeByte(@as(u8, @bitCast(disp)));1101 try self.w.writeByte(@as(u8, @bitCast(disp)));
1110 }1102 }
11111103
1112 /// Encode an 32 bit displacement1104 /// Encode an 32 bit displacement
1113 ///1105 ///
1114 /// It is sign-extended to 64 bits by the cpu.1106 /// It is sign-extended to 64 bits by the cpu.
1115 pub fn disp32(self: Self, disp: i32) !void {1107 pub fn disp32(self: Self, disp: i32) !void {
1116 try self.bw.writeInt(i32, disp, .little);1108 try self.w.writeInt(i32, disp, .little);
1117 }1109 }
11181110
1119 /// Encode an 8 bit immediate1111 /// Encode an 8 bit immediate
1120 ///1112 ///
1121 /// It is sign-extended to 64 bits by the cpu.1113 /// It is sign-extended to 64 bits by the cpu.
1122 pub fn imm8(self: Self, imm: u8) !void {1114 pub fn imm8(self: Self, imm: u8) !void {
1123 try self.bw.writeByte(imm);1115 try self.w.writeByte(imm);
1124 }1116 }
11251117
1126 /// Encode an 16 bit immediate1118 /// Encode an 16 bit immediate
1127 ///1119 ///
1128 /// It is sign-extended to 64 bits by the cpu.1120 /// It is sign-extended to 64 bits by the cpu.
1129 pub fn imm16(self: Self, imm: u16) !void {1121 pub fn imm16(self: Self, imm: u16) !void {
1130 try self.bw.writeInt(u16, imm, .little);1122 try self.w.writeInt(u16, imm, .little);
1131 }1123 }
11321124
1133 /// Encode an 32 bit immediate1125 /// Encode an 32 bit immediate
1134 ///1126 ///
1135 /// It is sign-extended to 64 bits by the cpu.1127 /// It is sign-extended to 64 bits by the cpu.
1136 pub fn imm32(self: Self, imm: u32) !void {1128 pub fn imm32(self: Self, imm: u32) !void {
1137 try self.bw.writeInt(u32, imm, .little);1129 try self.w.writeInt(u32, imm, .little);
1138 }1130 }
11391131
1140 /// Encode an 64 bit immediate1132 /// Encode an 64 bit immediate
1141 ///1133 ///
1142 /// It is sign-extended to 64 bits by the cpu.1134 /// It is sign-extended to 64 bits by the cpu.
1143 pub fn imm64(self: Self, imm: u64) !void {1135 pub fn imm64(self: Self, imm: u64) !void {
1144 try self.bw.writeInt(u64, imm, .little);1136 try self.w.writeInt(u64, imm, .little);
1145 }1137 }
1146 };1138 };
1147}1139}
...@@ -2199,10 +2191,10 @@ const Assembler = struct {...@@ -2199,10 +2191,10 @@ const Assembler = struct {
2199 };2191 };
2200 }2192 }
22012193
2202 pub fn assemble(as: *Assembler, bw: *Writer) !void {2194 pub fn assemble(as: *Assembler, w: *Writer) !void {
2203 while (try as.next()) |parsed_inst| {2195 while (try as.next()) |parsed_inst| {
2204 const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops);2196 const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops);
2205 try inst.encode(bw, .{});2197 try inst.encode(w, .{});
2206 }2198 }
2207 }2199 }
22082200
src/codegen/c/Type.zig+19-24
...@@ -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, bw: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void {212pub fn renderLiteralPrefix(ctype: CType, w: *Writer, kind: Kind, pool: *const Pool) 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, bw: *Writer, kind: Kind, pool: *const P...@@ -224,7 +224,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const P
224 .uintptr_t,224 .uintptr_t,
225 .intptr_t,225 .intptr_t,
226 => switch (kind) {226 => switch (kind) {
227 else => try bw.print("({s})", .{@tagName(basic_info)}),227 else => try w.print("({s})", .{@tagName(basic_info)}),
228 .global => {},228 .global => {},
229 },229 },
230 .int,230 .int,
...@@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const P...@@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const P
246 .int32_t,246 .int32_t,
247 .uint64_t,247 .uint64_t,
248 .int64_t,248 .int64_t,
249 => try bw.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),249 => try w.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, bw: *Writer, kind: Kind, pool: *const P...@@ -255,7 +255,7 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const P
255 .zig_f80,255 .zig_f80,
256 .zig_f128,256 .zig_f128,
257 .zig_c_longdouble,257 .zig_c_longdouble,
258 => try bw.print("zig_{s}_{s}(", .{258 => try w.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, bw: *Writer, kind: Kind, pool: *const P...@@ -265,12 +265,12 @@ pub fn renderLiteralPrefix(ctype: CType, bw: *Writer, kind: Kind, pool: *const P
265 .va_list => unreachable,265 .va_list => unreachable,
266 _ => unreachable,266 _ => unreachable,
267 },267 },
268 .array, .vector => try bw.writeByte('{'),268 .array, .vector => try w.writeByte('{'),
269 else => unreachable,269 else => unreachable,
270 }270 }
271}271}
272272
273pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.Error!void {273pub fn renderLiteralSuffix(ctype: CType, w: *Writer, pool: *const Pool) 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, bw: *Writer, pool: *const Pool) Writer....@@ -280,20 +280,20 @@ pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.
280 .short,280 .short,
281 .int,281 .int,
282 => {},282 => {},
283 .long => try bw.writeByte('l'),283 .long => try w.writeByte('l'),
284 .@"long long" => try bw.writeAll("ll"),284 .@"long long" => try w.writeAll("ll"),
285 .@"unsigned char",285 .@"unsigned char",
286 .@"unsigned short",286 .@"unsigned short",
287 .@"unsigned int",287 .@"unsigned int",
288 => try bw.writeByte('u'),288 => try w.writeByte('u'),
289 .@"unsigned long",289 .@"unsigned long",
290 .size_t,290 .size_t,
291 .uintptr_t,291 .uintptr_t,
292 => try bw.writeAll("ul"),292 => try w.writeAll("ul"),
293 .@"unsigned long long" => try bw.writeAll("ull"),293 .@"unsigned long long" => try w.writeAll("ull"),
294 .float => try bw.writeByte('f'),294 .float => try w.writeByte('f'),
295 .double => {},295 .double => {},
296 .@"long double" => try bw.writeByte('l'),296 .@"long double" => try w.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, bw: *Writer, pool: *const Pool) Writer....@@ -314,11 +314,11 @@ pub fn renderLiteralSuffix(ctype: CType, bw: *Writer, pool: *const Pool) Writer.
314 .zig_f80,314 .zig_f80,
315 .zig_f128,315 .zig_f128,
316 .zig_c_longdouble,316 .zig_c_longdouble,
317 => try bw.writeByte(')'),317 => try w.writeByte(')'),
318 .va_list => unreachable,318 .va_list => unreachable,
319 _ => unreachable,319 _ => unreachable,
320 },320 },
321 .array, .vector => try bw.writeByte('}'),321 .array, .vector => try w.writeByte('}'),
322 else => unreachable,322 else => unreachable,
323 }323 }
324}324}
...@@ -938,18 +938,13 @@ pub const Pool = struct {...@@ -938,18 +938,13 @@ pub const Pool = struct {
938 index: String.Index,938 index: String.Index,
939939
940 const FormatData = struct { string: String, pool: *const Pool };940 const FormatData = struct { string: String, pool: *const Pool };
941 fn format(941 fn format(data: FormatData, writer: *Writer) Writer.Error!void {
942 data: FormatData,
943 bw: *Writer,
944 comptime fmt_str: []const u8,
945 ) Writer.Error!void {
946 comptime assert(fmt_str.len == 0);
947 if (data.string.toSlice(data.pool)) |slice|942 if (data.string.toSlice(data.pool)) |slice|
948 try bw.writeAll(slice)943 try writer.writeAll(slice)
949 else944 else
950 try bw.print("f{d}", .{@intFromEnum(data.string.index)});945 try writer.print("f{d}", .{@intFromEnum(data.string.index)});
951 }946 }
952 pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(format) {947 pub fn fmt(str: String, pool: *const Pool) std.fmt.Formatter(FormatData, format) {
953 return .{ .data = .{ .string = str, .pool = pool } };948 return .{ .data = .{ .string = str, .pool = pool } };
954 }949 }
955950
src/codegen/llvm.zig+4-2
...@@ -2491,7 +2491,7 @@ pub const Object = struct {...@@ -2491,7 +2491,7 @@ pub const Object = struct {
2491 var union_name_buf: ?[:0]const u8 = null;2491 var union_name_buf: ?[:0]const u8 = null;
2492 defer if (union_name_buf) |buf| gpa.free(buf);2492 defer if (union_name_buf) |buf| gpa.free(buf);
2493 const union_name = if (layout.tag_size == 0) name else name: {2493 const union_name = if (layout.tag_size == 0) name else name: {
2494 union_name_buf = try std.fmt.allocPrintZ(gpa, "{s}:Payload", .{name});2494 union_name_buf = try std.fmt.allocPrintSentinel(gpa, "{s}:Payload", .{name}, 0);
2495 break :name union_name_buf.?;2495 break :name union_name_buf.?;
2496 };2496 };
24972497
...@@ -2687,7 +2687,9 @@ pub const Object = struct {...@@ -2687,7 +2687,9 @@ pub const Object = struct {
2687 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {2687 fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 {
2688 var aw: std.io.Writer.Allocating = .init(o.gpa);2688 var aw: std.io.Writer.Allocating = .init(o.gpa);
2689 defer aw.deinit();2689 defer aw.deinit();
2690 ty.print(&aw.interface, o.pt) catch return error.OutOfMemory;2690 ty.print(&aw.writer, o.pt) catch |err| switch (err) {
2691 error.WriteFailed => return error.OutOfMemory,
2692 };
2691 return aw.toOwnedSliceSentinel(0);2693 return aw.toOwnedSliceSentinel(0);
2692 }2694 }
26932695