diff options
| -rw-r--r-- | lib/std/io/tty.zig | 11 | ||||
| -rw-r--r-- | src/Air/print.zig | 198 | ||||
| -rw-r--r-- | src/Compilation.zig | 4 | ||||
| -rw-r--r-- | src/Sema.zig | 10 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 9 | ||||
| -rw-r--r-- | src/arch/x86_64/encoder.zig | 246 | ||||
| -rw-r--r-- | src/codegen/c.zig | 224 | ||||
| -rw-r--r-- | src/codegen/c/Type.zig | 38 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 46 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 10 | ||||
| -rw-r--r-- | src/link/MachO/Atom.zig | 5 |
11 files changed, 398 insertions, 403 deletions
diff --git a/lib/std/io/tty.zig b/lib/std/io/tty.zig index c220e87880..1e9cd0d9bc 100644 --- a/lib/std/io/tty.zig +++ b/lib/std/io/tty.zig @@ -71,12 +71,9 @@ pub const Config = union(enum) { reset_attributes: u16, }; - pub fn setColor( - conf: Config, - writer: anytype, - color: Color, - ) (@typeInfo(@TypeOf(writer.writeAll(""))).error_union.error_set || - windows.SetConsoleTextAttributeError)!void { + pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || std.io.Writer.Error; + + pub fn setColor(conf: Config, w: *std.io.Writer, color: Color) SetColorError!void { nosuspend switch (conf) { .no_color => return, .escape_codes => { @@ -101,7 +98,7 @@ pub const Config = union(enum) { .dim => "\x1b[2m", .reset => "\x1b[0m", }; - try writer.writeAll(color_string); + try w.writeAll(color_string); }, .windows_api => |ctx| if (native_os == .windows) { const attributes = switch (color) { diff --git a/src/Air/print.zig b/src/Air/print.zig index 0e90496342..0aad8b1052 100644 --- a/src/Air/print.zig +++ b/src/Air/print.zig @@ -1,6 +1,5 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const fmtIntSizeBin = std.fmt.fmtIntSizeBin; const build_options = @import("build_options"); const Zcu = @import("../Zcu.zig"); @@ -9,7 +8,7 @@ const Type = @import("../Type.zig"); const Air = @import("../Air.zig"); const InternPool = @import("../InternPool.zig"); -pub fn write(air: Air, stream: anytype, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { +pub fn write(air: Air, stream: *std.io.Writer, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { comptime std.debug.assert(build_options.enable_debug_extensions); const instruction_bytes = air.instructions.len * // Here we don't use @sizeOf(Air.Inst.Data) because it would include @@ -25,20 +24,20 @@ pub fn write(air: Air, stream: anytype, pt: Zcu.PerThread, liveness: ?Air.Livene // zig fmt: off stream.print( - \\# Total AIR+Liveness bytes: {} - \\# AIR Instructions: {d} ({}) - \\# AIR Extra Data: {d} ({}) - \\# Liveness tomb_bits: {} - \\# Liveness Extra Data: {d} ({}) - \\# Liveness special table: {d} ({}) + \\# Total AIR+Liveness bytes: {Bi} + \\# AIR Instructions: {d} ({Bi}) + \\# AIR Extra Data: {d} ({Bi}) + \\# Liveness tomb_bits: {Bi} + \\# Liveness Extra Data: {d} ({Bi}) + \\# Liveness special table: {d} ({Bi}) \\ , .{ - fmtIntSizeBin(total_bytes), - air.instructions.len, fmtIntSizeBin(instruction_bytes), - air.extra.items.len, fmtIntSizeBin(extra_bytes), - fmtIntSizeBin(tomb_bytes), - if (liveness) |l| l.extra.len else 0, fmtIntSizeBin(liveness_extra_bytes), - if (liveness) |l| l.special.count() else 0, fmtIntSizeBin(liveness_special_bytes), + total_bytes, + air.instructions.len, instruction_bytes, + air.extra.items.len, extra_bytes, + tomb_bytes, + if (liveness) |l| l.extra.len else 0, liveness_extra_bytes, + if (liveness) |l| l.special.count() else 0, liveness_special_bytes, }) catch return; // zig fmt: on @@ -55,7 +54,7 @@ pub fn write(air: Air, stream: anytype, pt: Zcu.PerThread, liveness: ?Air.Livene pub fn writeInst( air: Air, - stream: anytype, + stream: *std.io.Writer, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness, @@ -73,11 +72,15 @@ pub fn writeInst( } pub fn dump(air: Air, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - air.write(std.fs.File.stderr().deprecatedWriter(), pt, liveness); + const stderr_bw = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + air.write(stderr_bw, pt, liveness); } pub fn dumpInst(air: Air, inst: Air.Inst.Index, pt: Zcu.PerThread, liveness: ?Air.Liveness) void { - air.writeInst(std.fs.File.stderr().deprecatedWriter(), inst, pt, liveness); + const stderr_bw = std.debug.lockStderrWriter(&.{}); + defer std.debug.unlockStderrWriter(); + air.writeInst(stderr_bw, inst, pt, liveness); } const Writer = struct { @@ -88,17 +91,19 @@ const Writer = struct { indent: usize, skip_body: bool, - fn writeBody(w: *Writer, s: anytype, body: []const Air.Inst.Index) @TypeOf(s).Error!void { + const Error = std.io.Writer.Error; + + fn writeBody(w: *Writer, s: *std.io.Writer, body: []const Air.Inst.Index) Error!void { for (body) |inst| { try w.writeInst(s, inst); try s.writeByte('\n'); } } - fn writeInst(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeInst(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)]; - try s.writeByteNTimes(' ', w.indent); - try s.print("{}{c}= {s}(", .{ + try s.splatByteAll(' ', w.indent); + try s.print("{f}{c}= {s}(", .{ inst, @as(u8, if (if (w.liveness) |liveness| liveness.isUnused(inst) else false) '!' else ' '), @tagName(tag), @@ -335,47 +340,48 @@ const Writer = struct { try s.writeByte(')'); } - fn writeBinOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeBinOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; try w.writeOperand(s, inst, 0, bin_op.lhs); try s.writeAll(", "); try w.writeOperand(s, inst, 1, bin_op.rhs); } - fn writeUnOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeUnOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const un_op = w.air.instructions.items(.data)[@intFromEnum(inst)].un_op; try w.writeOperand(s, inst, 0, un_op); } - fn writeNoOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeNoOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { _ = w; + _ = s; _ = inst; // no-op, no argument to write } - fn writeType(w: *Writer, s: anytype, ty: Type) !void { + fn writeType(w: *Writer, s: *std.io.Writer, ty: Type) !void { return ty.print(s, w.pt); } - fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeTy(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty = w.air.instructions.items(.data)[@intFromEnum(inst)].ty; try w.writeType(s, ty); } - fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeArg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg; try w.writeType(s, arg.ty.toType()); try s.print(", {d}", .{arg.zir_param_index}); } - fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeTyOp(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_op = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; try w.writeType(s, ty_op.ty.toType()); try s.writeAll(", "); try w.writeOperand(s, inst, 0, ty_op.operand); } - fn writeBlock(w: *Writer, s: anytype, tag: Air.Inst.Tag, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeBlock(w: *Writer, s: *std.io.Writer, tag: Air.Inst.Tag, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; try w.writeType(s, ty_pl.ty.toType()); const body: []const Air.Inst.Index = @ptrCast(switch (tag) { @@ -408,15 +414,15 @@ const Writer = struct { w.indent += 2; try w.writeBody(s, body); w.indent = old_indent; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); for (liveness_block.deaths) |operand| { - try s.print(" {}!", .{operand}); + try s.print(" {f}!", .{operand}); } } - fn writeLoop(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeLoop(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.Block, ty_pl.payload); const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); @@ -428,11 +434,11 @@ const Writer = struct { w.indent += 2; try w.writeBody(s, body); w.indent = old_indent; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); } - fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeAggregateInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const zcu = w.pt.zcu; const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const vector_ty = ty_pl.ty.toType(); @@ -448,7 +454,7 @@ const Writer = struct { try s.writeAll("]"); } - fn writeUnionInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeUnionInit(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.UnionInit, ty_pl.payload).data; @@ -456,7 +462,7 @@ const Writer = struct { try w.writeOperand(s, inst, 0, extra.init); } - fn writeStructField(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeStructField(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.StructField, ty_pl.payload).data; @@ -464,7 +470,7 @@ const Writer = struct { try s.print(", {d}", .{extra.field_index}); } - fn writeTyPlBin(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeTyPlBin(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const data = w.air.instructions.items(.data); const ty_pl = data[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.Bin, ty_pl.payload).data; @@ -477,7 +483,7 @@ const Writer = struct { try w.writeOperand(s, inst, 1, extra.rhs); } - fn writeCmpxchg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeCmpxchg(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.Cmpxchg, ty_pl.payload).data; @@ -491,7 +497,7 @@ const Writer = struct { }); } - fn writeMulAdd(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeMulAdd(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.Bin, pl_op.payload).data; @@ -502,7 +508,7 @@ const Writer = struct { try w.writeOperand(s, inst, 2, pl_op.operand); } - fn writeShuffleOne(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeShuffleOne(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const unwrapped = w.air.unwrapShuffleOne(w.pt.zcu, inst); try w.writeType(s, unwrapped.result_ty); try s.writeAll(", "); @@ -518,7 +524,7 @@ const Writer = struct { try s.writeByte(']'); } - fn writeShuffleTwo(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeShuffleTwo(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const unwrapped = w.air.unwrapShuffleTwo(w.pt.zcu, inst); try w.writeType(s, unwrapped.result_ty); try s.writeAll(", "); @@ -537,7 +543,7 @@ const Writer = struct { try s.writeByte(']'); } - fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeSelect(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const zcu = w.pt.zcu; const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.Bin, pl_op.payload).data; @@ -552,14 +558,14 @@ const Writer = struct { try w.writeOperand(s, inst, 2, extra.rhs); } - fn writeReduce(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeReduce(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const reduce = w.air.instructions.items(.data)[@intFromEnum(inst)].reduce; try w.writeOperand(s, inst, 0, reduce.operand); try s.print(", {s}", .{@tagName(reduce.operation)}); } - fn writeCmpVector(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeCmpVector(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.VectorCmp, ty_pl.payload).data; @@ -569,7 +575,7 @@ const Writer = struct { try w.writeOperand(s, inst, 1, extra.rhs); } - fn writeVectorStoreElem(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeVectorStoreElem(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const data = w.air.instructions.items(.data)[@intFromEnum(inst)].vector_store_elem; const extra = w.air.extraData(Air.VectorCmp, data.payload).data; @@ -580,21 +586,21 @@ const Writer = struct { try w.writeOperand(s, inst, 2, extra.rhs); } - fn writeRuntimeNavPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeRuntimeNavPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ip = &w.pt.zcu.intern_pool; const ty_nav = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav; try w.writeType(s, .fromInterned(ty_nav.ty)); try s.print(", '{}'", .{ip.getNav(ty_nav.nav).fqn.fmt(ip)}); } - fn writeAtomicLoad(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeAtomicLoad(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const atomic_load = w.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load; try w.writeOperand(s, inst, 0, atomic_load.ptr); try s.print(", {s}", .{@tagName(atomic_load.order)}); } - fn writePrefetch(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writePrefetch(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const prefetch = w.air.instructions.items(.data)[@intFromEnum(inst)].prefetch; try w.writeOperand(s, inst, 0, prefetch.ptr); @@ -605,10 +611,10 @@ const Writer = struct { fn writeAtomicStore( w: *Writer, - s: anytype, + s: *std.io.Writer, inst: Air.Inst.Index, order: std.builtin.AtomicOrder, - ) @TypeOf(s).Error!void { + ) Error!void { const bin_op = w.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; try w.writeOperand(s, inst, 0, bin_op.lhs); try s.writeAll(", "); @@ -616,7 +622,7 @@ const Writer = struct { try s.print(", {s}", .{@tagName(order)}); } - fn writeAtomicRmw(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeAtomicRmw(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.AtomicRmw, pl_op.payload).data; @@ -626,7 +632,7 @@ const Writer = struct { try s.print(", {s}, {s}", .{ @tagName(extra.op()), @tagName(extra.ordering()) }); } - fn writeFieldParentPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeFieldParentPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; @@ -634,7 +640,7 @@ const Writer = struct { try s.print(", {d}", .{extra.field_index}); } - fn writeAssembly(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeAssembly(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.Asm, ty_pl.payload); const is_volatile = @as(u1, @truncate(extra.data.flags >> 31)) != 0; @@ -704,22 +710,22 @@ const Writer = struct { } } const asm_source = std.mem.sliceAsBytes(w.air.extra.items[extra_i..])[0..extra.data.source_len]; - try s.print(", \"{f}\"", .{std.zig.fmtString(asm_source)}); + try s.print(", \"{f}\"", .{std.zig.fmtEscapes(asm_source)}); } - fn writeDbgStmt(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeDbgStmt(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const dbg_stmt = w.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt; try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); } - fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeDbgVar(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; try w.writeOperand(s, inst, 0, pl_op.operand); const name: Air.NullTerminatedString = @enumFromInt(pl_op.payload); - try s.print(", \"{f}\"", .{std.zig.fmtString(name.toSlice(w.air))}); + try s.print(", \"{f}\"", .{std.zig.fmtEscapes(name.toSlice(w.air))}); } - fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeCall(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.Call, pl_op.payload); const args = @as([]const Air.Inst.Ref, @ptrCast(w.air.extra.items[extra.end..][0..extra.data.args_len])); @@ -732,19 +738,19 @@ const Writer = struct { try s.writeAll("]"); } - fn writeBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const br = w.air.instructions.items(.data)[@intFromEnum(inst)].br; try w.writeInstIndex(s, br.block_inst, false); try s.writeAll(", "); try w.writeOperand(s, inst, 0, br.operand); } - fn writeRepeat(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeRepeat(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const repeat = w.air.instructions.items(.data)[@intFromEnum(inst)].repeat; try w.writeInstIndex(s, repeat.loop_inst, false); } - fn writeTry(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeTry(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.Try, pl_op.payload); const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); @@ -760,25 +766,25 @@ const Writer = struct { w.indent += 2; if (liveness_condbr.else_deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (liveness_condbr.else_deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } try w.writeBody(s, body); w.indent = old_indent; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); for (liveness_condbr.then_deaths) |operand| { - try s.print(" {}!", .{operand}); + try s.print(" {f}!", .{operand}); } } - fn writeTryPtr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeTryPtr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const ty_pl = w.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; const extra = w.air.extraData(Air.TryPtr, ty_pl.payload); const body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.body_len]); @@ -797,25 +803,25 @@ const Writer = struct { w.indent += 2; if (liveness_condbr.else_deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (liveness_condbr.else_deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } try w.writeBody(s, body); w.indent = old_indent; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); for (liveness_condbr.then_deaths) |operand| { - try s.print(" {}!", .{operand}); + try s.print(" {f}!", .{operand}); } } - fn writeCondBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeCondBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; const extra = w.air.extraData(Air.CondBr, pl_op.payload); const then_body: []const Air.Inst.Index = @ptrCast(w.air.extra.items[extra.end..][0..extra.data.then_body_len]); @@ -839,16 +845,16 @@ const Writer = struct { w.indent += 2; if (liveness_condbr.then_deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (liveness_condbr.then_deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } try w.writeBody(s, then_body); - try s.writeByteNTimes(' ', old_indent); + try s.splatByteAll(' ', old_indent); try s.writeAll("},"); if (extra.data.branch_hints.false != .none) { try s.print(" {s}", .{@tagName(extra.data.branch_hints.false)}); @@ -859,10 +865,10 @@ const Writer = struct { try s.writeAll(" {\n"); if (liveness_condbr.else_deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (liveness_condbr.else_deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } @@ -870,11 +876,11 @@ const Writer = struct { try w.writeBody(s, else_body); w.indent = old_indent; - try s.writeByteNTimes(' ', old_indent); + try s.splatByteAll(' ', old_indent); try s.writeAll("}"); } - fn writeSwitchBr(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeSwitchBr(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const switch_br = w.air.unwrapSwitch(inst); const liveness: Air.Liveness.SwitchBrTable = if (w.liveness) |liveness| @@ -916,17 +922,17 @@ const Writer = struct { const deaths = liveness.deaths[case.idx]; if (deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } try w.writeBody(s, case.body); w.indent -= 2; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); } @@ -942,47 +948,47 @@ const Writer = struct { const deaths = liveness.deaths[liveness.deaths.len - 1]; if (deaths.len != 0) { - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); for (deaths, 0..) |operand, i| { if (i != 0) try s.writeAll(" "); - try s.print("{}!", .{operand}); + try s.print("{f}!", .{operand}); } try s.writeAll("\n"); } try w.writeBody(s, else_body); w.indent -= 2; - try s.writeByteNTimes(' ', w.indent); + try s.splatByteAll(' ', w.indent); try s.writeAll("}"); } try s.writeAll("\n"); - try s.writeByteNTimes(' ', old_indent); + try s.splatByteAll(' ', old_indent); } - fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeWasmMemorySize(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; try s.print("{d}", .{pl_op.payload}); } - fn writeWasmMemoryGrow(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeWasmMemoryGrow(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; try s.print("{d}, ", .{pl_op.payload}); try w.writeOperand(s, inst, 0, pl_op.operand); } - fn writeWorkDimension(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeWorkDimension(w: *Writer, s: *std.io.Writer, inst: Air.Inst.Index) Error!void { const pl_op = w.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; try s.print("{d}", .{pl_op.payload}); } fn writeOperand( w: *Writer, - s: anytype, + s: *std.io.Writer, inst: Air.Inst.Index, op_index: usize, operand: Air.Inst.Ref, - ) @TypeOf(s).Error!void { + ) Error!void { const small_tomb_bits = Air.Liveness.bpi - 1; const dies = if (w.liveness) |liveness| blk: { if (op_index < small_tomb_bits) @@ -1004,16 +1010,16 @@ const Writer = struct { fn writeInstRef( w: *Writer, - s: anytype, + s: *std.io.Writer, operand: Air.Inst.Ref, dies: bool, - ) @TypeOf(s).Error!void { + ) Error!void { if (@intFromEnum(operand) < InternPool.static_len) { return s.print("@{}", .{operand}); } else if (operand.toInterned()) |ip_index| { const pt = w.pt; const ty = Type.fromInterned(pt.zcu.intern_pool.indexToKey(ip_index).typeOf()); - try s.print("<{}, {}>", .{ + try s.print("<{f}, {f}>", .{ ty.fmt(pt), Value.fromInterned(ip_index).fmtValue(pt), }); @@ -1024,12 +1030,12 @@ const Writer = struct { fn writeInstIndex( w: *Writer, - s: anytype, + s: *std.io.Writer, inst: Air.Inst.Index, dies: bool, - ) @TypeOf(s).Error!void { + ) Error!void { _ = w; - try s.print("{}", .{inst}); + try s.print("{f}", .{inst}); if (dies) try s.writeByte('!'); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 6af714bf3d..f5aace5f7b 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5852,7 +5852,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr try child.spawn(); - const stderr = try child.stderr.?.reader().readAllAlloc(arena, std.math.maxInt(usize)); + const stderr = try child.stderr.?.deprecatedReader().readAllAlloc(arena, std.math.maxInt(usize)); const term = child.wait() catch |err| { return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) }); @@ -6249,7 +6249,7 @@ fn spawnZigRc( } // Just in case there's a failure that didn't send an ErrorBundle (e.g. an error return trace) - const stderr_reader = child.stderr.?.reader(); + const stderr_reader = child.stderr.?.deprecatedReader(); const stderr = try stderr_reader.readAllAlloc(arena, 10 * 1024 * 1024); const term = child.wait() catch |err| { diff --git a/src/Sema.zig b/src/Sema.zig index 5ba17dccb8..5d62f95e45 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3026,8 +3026,8 @@ pub fn createTypeName( var aw: std.io.Writer.Allocating = .init(gpa); defer aw.deinit(); - const bw = &aw.writer; - bw.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch return error.OutOfMemory; + const w = &aw.writer; + w.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch return error.OutOfMemory; var arg_i: usize = 0; for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) { @@ -3040,13 +3040,13 @@ pub fn createTypeName( // result in a compile error. const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat - if (arg_i != 0) bw.writeByte(',') catch return error.OutOfMemory; + if (arg_i != 0) w.writeByte(',') catch return error.OutOfMemory; // Limiting the depth here helps avoid type names getting too long, which // in turn helps to avoid unreasonably long symbol names for namespaced // symbols. Such names should ideally be human-readable, and additionally, // some tooling may not support very long symbol names. - bw.print("{f}", .{Value.fmtValueSemaFull(.{ + w.print("{f}", .{Value.fmtValueSemaFull(.{ .val = arg_val, .pt = pt, .opt_sema = sema, @@ -3059,7 +3059,7 @@ pub fn createTypeName( else => continue, }; - try bw.writeByte(')'); + w.writeByte(')') catch return error.OutOfMemory; return .{ .name = try ip.getOrPutString(gpa, pt.tid, aw.getWritten(), .no_embedded_nulls), .nav = .none, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index d1ab3a86bd..a7318f0753 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -1135,15 +1135,10 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void { try w.writeAll(lower.err_msg.?.msg); return; }, - error.OutOfMemory, error.InvalidInstruction, error.CannotEncode => |e| { - try w.writeAll(switch (e) { - error.OutOfMemory => "Out of memory", - error.InvalidInstruction => "CodeGen failed to find a viable instruction.", - error.CannotEncode => "CodeGen failed to encode the instruction.", - }); + else => |e| { + try w.writeAll(@errorName(e)); return; }, - else => |e| return e, }).insts) |lowered_inst| { if (!first) try w.writeAll("\ndebug(wip_mir): "); try w.print(" | {f}", .{lowered_inst}); diff --git a/src/arch/x86_64/encoder.zig b/src/arch/x86_64/encoder.zig index ab3eeaa586..415b211e6a 100644 --- a/src/arch/x86_64/encoder.zig +++ b/src/arch/x86_64/encoder.zig @@ -3,6 +3,7 @@ const assert = std.debug.assert; const log = std.log.scoped(.x86_64_encoder); const math = std.math; const testing = std.testing; +const Writer = std.io.Writer; const bits = @import("bits.zig"); const Encoding = @import("Encoding.zig"); @@ -226,101 +227,81 @@ pub const Instruction = struct { }; } - fn format( - op: Operand, - comptime unused_format_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = op; - _ = unused_format_string; - _ = options; - _ = writer; - @compileError("do not format Operand directly; use fmt() instead"); - } - - const FormatContext = struct { + const Format = struct { op: Operand, enc_op: Encoding.Op, - }; - fn fmtContext( - ctx: FormatContext, - comptime unused_format_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) @TypeOf(writer).Error!void { - _ = unused_format_string; - _ = options; - const op = ctx.op; - const enc_op = ctx.enc_op; - switch (op) { - .none => {}, - .reg => |reg| try writer.writeAll(@tagName(reg)), - .mem => |mem| switch (mem) { - .rip => |rip| { - try writer.print("{} [rip", .{rip.ptr_size}); - if (rip.disp != 0) try writer.print(" {c} 0x{x}", .{ - @as(u8, if (rip.disp < 0) '-' else '+'), - @abs(rip.disp), - }); - try writer.writeByte(']'); - }, - .sib => |sib| { - try writer.print("{} ", .{sib.ptr_size}); + fn default(f: Format, w: *Writer) Writer.Error!void { + const op = f.op; + const enc_op = f.enc_op; + switch (op) { + .none => {}, + .reg => |reg| try w.writeAll(@tagName(reg)), + .mem => |mem| switch (mem) { + .rip => |rip| { + try w.print("{f} [rip", .{rip.ptr_size}); + if (rip.disp != 0) try w.print(" {c} 0x{x}", .{ + @as(u8, if (rip.disp < 0) '-' else '+'), + @abs(rip.disp), + }); + try w.writeByte(']'); + }, + .sib => |sib| { + try w.print("{f} ", .{sib.ptr_size}); - if (mem.isSegmentRegister()) { - return writer.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); - } + if (mem.isSegmentRegister()) { + return w.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp }); + } - try writer.writeByte('['); - - var any = true; - switch (sib.base) { - .none => any = false, - .reg => |reg| try writer.print("{s}", .{@tagName(reg)}), - .frame => |frame_index| try writer.print("{}", .{frame_index}), - .table => try writer.print("Table", .{}), - .rip_inst => |inst_index| try writer.print("RipInst({d})", .{inst_index}), - .nav => |nav| try writer.print("Nav({d})", .{@intFromEnum(nav)}), - .uav => |uav| try writer.print("Uav({d})", .{@intFromEnum(uav.val)}), - .lazy_sym => |lazy_sym| try writer.print("LazySym({s}, {d})", .{ - @tagName(lazy_sym.kind), - @intFromEnum(lazy_sym.ty), - }), - .extern_func => |extern_func| try writer.print("ExternFunc({d})", .{@intFromEnum(extern_func)}), - } - if (mem.scaleIndex()) |si| { - if (any) try writer.writeAll(" + "); - try writer.print("{s} * {d}", .{ @tagName(si.index), si.scale }); - any = true; - } - if (sib.disp != 0 or !any) { - if (any) - try writer.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')}) - else if (sib.disp < 0) - try writer.writeByte('-'); - try writer.print("0x{x}", .{@abs(sib.disp)}); - any = true; - } + try w.writeByte('['); + + var any = true; + switch (sib.base) { + .none => any = false, + .reg => |reg| try w.print("{s}", .{@tagName(reg)}), + .frame => |frame_index| try w.print("{}", .{frame_index}), + .table => try w.print("Table", .{}), + .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}), + .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}), + .uav => |uav| try w.print("Uav({d})", .{@intFromEnum(uav.val)}), + .lazy_sym => |lazy_sym| try w.print("LazySym({s}, {d})", .{ + @tagName(lazy_sym.kind), + @intFromEnum(lazy_sym.ty), + }), + .extern_func => |extern_func| try w.print("ExternFunc({d})", .{@intFromEnum(extern_func)}), + } + if (mem.scaleIndex()) |si| { + if (any) try w.writeAll(" + "); + try w.print("{s} * {d}", .{ @tagName(si.index), si.scale }); + any = true; + } + if (sib.disp != 0 or !any) { + if (any) + try w.print(" {c} ", .{@as(u8, if (sib.disp < 0) '-' else '+')}) + else if (sib.disp < 0) + try w.writeByte('-'); + try w.print("0x{x}", .{@abs(sib.disp)}); + any = true; + } - try writer.writeByte(']'); + try w.writeByte(']'); + }, + .moffs => |moffs| try w.print("{s}:0x{x}", .{ + @tagName(moffs.seg), + moffs.offset, + }), }, - .moffs => |moffs| try writer.print("{s}:0x{x}", .{ - @tagName(moffs.seg), - moffs.offset, - }), - }, - .imm => |imm| if (enc_op.isSigned()) { - const imms = imm.asSigned(enc_op.immBitSize()); - if (imms < 0) try writer.writeByte('-'); - try writer.print("0x{x}", .{@abs(imms)}); - } else try writer.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}), - .bytes => unreachable, + .imm => |imm| if (enc_op.isSigned()) { + const imms = imm.asSigned(enc_op.immBitSize()); + if (imms < 0) try w.writeByte('-'); + try w.print("0x{x}", .{@abs(imms)}); + } else try w.print("0x{x}", .{imm.asUnsigned(enc_op.immBitSize())}), + .bytes => unreachable, + } } - } + }; - pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(fmtContext) { + pub fn fmt(op: Operand, enc_op: Encoding.Op) std.fmt.Formatter(Format, Format.default) { return .{ .data = .{ .op = op, .enc_op = enc_op } }; } }; @@ -361,7 +342,7 @@ pub const Instruction = struct { }, }, }; - log.debug("selected encoding: {}", .{encoding}); + log.debug("selected encoding: {f}", .{encoding}); var inst: Instruction = .{ .prefix = prefix, @@ -372,30 +353,23 @@ pub const Instruction = struct { return inst; } - pub fn format( - inst: Instruction, - comptime unused_format_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) @TypeOf(writer).Error!void { - _ = unused_format_string; - _ = options; + pub fn format(inst: Instruction, w: *Writer, comptime unused_format_string: []const u8) Writer.Error!void { + comptime assert(unused_format_string.len == 0); switch (inst.prefix) { .none, .directive => {}, - else => try writer.print("{s} ", .{@tagName(inst.prefix)}), + else => try w.print("{s} ", .{@tagName(inst.prefix)}), } - try writer.print("{s}", .{@tagName(inst.encoding.mnemonic)}); + try w.print("{s}", .{@tagName(inst.encoding.mnemonic)}); for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| { if (op == .none) break; - if (i > 0) try writer.writeByte(','); - try writer.writeByte(' '); - try writer.print("{}", .{op.fmt(enc)}); + if (i > 0) try w.writeByte(','); + try w.print(" {f}", .{op.fmt(enc)}); } } - pub fn encode(inst: Instruction, writer: anytype, comptime opts: Options) !void { + pub fn encode(inst: Instruction, w: *Writer, comptime opts: Options) !void { assert(inst.prefix != .directive); - const encoder = Encoder(@TypeOf(writer), opts){ .writer = writer }; + const encoder: Encoder(opts) = .{ .w = w }; const enc = inst.encoding; const data = enc.data; @@ -801,9 +775,9 @@ pub const LegacyPrefixes = packed struct { pub const Options = struct { allow_frame_locs: bool = false, allow_symbols: bool = false }; -fn Encoder(comptime T: type, comptime opts: Options) type { +fn Encoder(comptime opts: Options) type { return struct { - writer: T, + w: *Writer, const Self = @This(); pub const options = opts; @@ -818,31 +792,31 @@ fn Encoder(comptime T: type, comptime opts: Options) type { // Hopefully this path isn't taken very often, so we'll do it the slow way for now // LOCK - if (prefixes.prefix_f0) try self.writer.writeByte(0xf0); + if (prefixes.prefix_f0) try self.w.writeByte(0xf0); // REPNZ, REPNE, REP, Scalar Double-precision - if (prefixes.prefix_f2) try self.writer.writeByte(0xf2); + if (prefixes.prefix_f2) try self.w.writeByte(0xf2); // REPZ, REPE, REP, Scalar Single-precision - if (prefixes.prefix_f3) try self.writer.writeByte(0xf3); + if (prefixes.prefix_f3) try self.w.writeByte(0xf3); // CS segment override or Branch not taken - if (prefixes.prefix_2e) try self.writer.writeByte(0x2e); + if (prefixes.prefix_2e) try self.w.writeByte(0x2e); // DS segment override - if (prefixes.prefix_36) try self.writer.writeByte(0x36); + if (prefixes.prefix_36) try self.w.writeByte(0x36); // ES segment override - if (prefixes.prefix_26) try self.writer.writeByte(0x26); + if (prefixes.prefix_26) try self.w.writeByte(0x26); // FS segment override - if (prefixes.prefix_64) try self.writer.writeByte(0x64); + if (prefixes.prefix_64) try self.w.writeByte(0x64); // GS segment override - if (prefixes.prefix_65) try self.writer.writeByte(0x65); + if (prefixes.prefix_65) try self.w.writeByte(0x65); // Branch taken - if (prefixes.prefix_3e) try self.writer.writeByte(0x3e); + if (prefixes.prefix_3e) try self.w.writeByte(0x3e); // Operand size override - if (prefixes.prefix_66) try self.writer.writeByte(0x66); + if (prefixes.prefix_66) try self.w.writeByte(0x66); // Address size override - if (prefixes.prefix_67) try self.writer.writeByte(0x67); + if (prefixes.prefix_67) try self.w.writeByte(0x67); } } @@ -850,7 +824,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// Note that this flag is overridden by REX.W, if both are present. pub fn prefix16BitMode(self: Self) !void { - try self.writer.writeByte(0x66); + try self.w.writeByte(0x66); } /// Encodes a REX prefix byte given all the fields @@ -869,7 +843,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { if (fields.x) byte |= 0b0010; if (fields.b) byte |= 0b0001; - try self.writer.writeByte(byte); + try self.w.writeByte(byte); } /// Encodes a VEX prefix given all the fields @@ -877,24 +851,24 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// See struct `Vex` for a description of each field. pub fn vex(self: Self, fields: Vex) !void { if (fields.is3Byte()) { - try self.writer.writeByte(0b1100_0100); + try self.w.writeByte(0b1100_0100); - try self.writer.writeByte( + try self.w.writeByte( @as(u8, ~@intFromBool(fields.r)) << 7 | @as(u8, ~@intFromBool(fields.x)) << 6 | @as(u8, ~@intFromBool(fields.b)) << 5 | @as(u8, @intFromEnum(fields.m)) << 0, ); - try self.writer.writeByte( + try self.w.writeByte( @as(u8, @intFromBool(fields.w)) << 7 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | @as(u8, @intFromBool(fields.l)) << 2 | @as(u8, @intFromEnum(fields.p)) << 0, ); } else { - try self.writer.writeByte(0b1100_0101); - try self.writer.writeByte( + try self.w.writeByte(0b1100_0101); + try self.w.writeByte( @as(u8, ~@intFromBool(fields.r)) << 7 | @as(u8, ~@as(u4, @intCast(fields.v.enc()))) << 3 | @as(u8, @intFromBool(fields.l)) << 2 | @@ -909,7 +883,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// Encodes a 1 byte opcode pub fn opcode_1byte(self: Self, opcode: u8) !void { - try self.writer.writeByte(opcode); + try self.w.writeByte(opcode); } /// Encodes a 2 byte opcode @@ -918,7 +892,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// encoder.opcode_2byte(0x0f, 0xaf); pub fn opcode_2byte(self: Self, prefix: u8, opcode: u8) !void { - try self.writer.writeAll(&.{ prefix, opcode }); + try self.w.writeAll(&.{ prefix, opcode }); } /// Encodes a 3 byte opcode @@ -927,7 +901,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// encoder.opcode_3byte(0xf2, 0x0f, 0x10); pub fn opcode_3byte(self: Self, prefix_1: u8, prefix_2: u8, opcode: u8) !void { - try self.writer.writeAll(&.{ prefix_1, prefix_2, opcode }); + try self.w.writeAll(&.{ prefix_1, prefix_2, opcode }); } /// Encodes a 1 byte opcode with a reg field @@ -935,7 +909,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// Remember to add a REX prefix byte if reg is extended! pub fn opcode_withReg(self: Self, opcode: u8, reg: u3) !void { assert(opcode & 0b111 == 0); - try self.writer.writeByte(opcode | reg); + try self.w.writeByte(opcode | reg); } // ------ @@ -946,7 +920,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// Remember to add a REX prefix byte if reg or rm are extended! pub fn modRm(self: Self, mod: u2, reg_or_opx: u3, rm: u3) !void { - try self.writer.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm); + try self.w.writeByte(@as(u8, mod) << 6 | @as(u8, reg_or_opx) << 3 | rm); } /// Construct a ModR/M byte using direct r/m addressing @@ -1032,7 +1006,7 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// Remember to add a REX prefix byte if index or base are extended! pub fn sib(self: Self, scale: u2, index: u3, base: u3) !void { - try self.writer.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base); + try self.w.writeByte(@as(u8, scale) << 6 | @as(u8, index) << 3 | base); } /// Construct a SIB byte with scale * index + base, no frills. @@ -1124,42 +1098,42 @@ fn Encoder(comptime T: type, comptime opts: Options) type { /// /// It is sign-extended to 64 bits by the cpu. pub fn disp8(self: Self, disp: i8) !void { - try self.writer.writeByte(@as(u8, @bitCast(disp))); + try self.w.writeByte(@as(u8, @bitCast(disp))); } /// Encode an 32 bit displacement /// /// It is sign-extended to 64 bits by the cpu. pub fn disp32(self: Self, disp: i32) !void { - try self.writer.writeInt(i32, disp, .little); + try self.w.writeInt(i32, disp, .little); } /// Encode an 8 bit immediate /// /// It is sign-extended to 64 bits by the cpu. pub fn imm8(self: Self, imm: u8) !void { - try self.writer.writeByte(imm); + try self.w.writeByte(imm); } /// Encode an 16 bit immediate /// /// It is sign-extended to 64 bits by the cpu. pub fn imm16(self: Self, imm: u16) !void { - try self.writer.writeInt(u16, imm, .little); + try self.w.writeInt(u16, imm, .little); } /// Encode an 32 bit immediate /// /// It is sign-extended to 64 bits by the cpu. pub fn imm32(self: Self, imm: u32) !void { - try self.writer.writeInt(u32, imm, .little); + try self.w.writeInt(u32, imm, .little); } /// Encode an 64 bit immediate /// /// It is sign-extended to 64 bits by the cpu. pub fn imm64(self: Self, imm: u64) !void { - try self.writer.writeInt(u64, imm, .little); + try self.w.writeInt(u64, imm, .little); } }; } @@ -2217,10 +2191,10 @@ const Assembler = struct { }; } - pub fn assemble(as: *Assembler, writer: anytype) !void { + pub fn assemble(as: *Assembler, w: *Writer) !void { while (try as.next()) |parsed_inst| { const inst: Instruction = try .new(.none, parsed_inst.mnemonic, &parsed_inst.ops); - try inst.encode(writer, .{}); + try inst.encode(w, .{}); } } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 224f86a78a..85cbd8c96f 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -604,8 +604,12 @@ pub const Function = struct { return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location); } - fn fmtIntLiteral(f: *Function, val: Value) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { - return f.object.dg.fmtIntLiteral(val, .Other); + fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { + return f.object.dg.fmtIntLiteralDec(val, .Other); + } + + fn fmtIntLiteralHex(f: *Function, val: Value) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { + return f.object.dg.fmtIntLiteralHex(val, .Other); } fn getLazyFnName(f: *Function, key: LazyFnKey) ![]const u8 { @@ -629,7 +633,7 @@ pub const Function = struct { }), .never_tail, .never_inline, - => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{}__{d}", .{ + => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{f}__{d}", .{ @tagName(key), fmtIdentUnsolo(ip.getNav(owner_nav).name.toSlice(ip)), @intFromEnum(owner_nav), @@ -880,7 +884,7 @@ pub const DeclGen = struct { const addr_val = try pt.intValue(.usize, int.addr); try writer.writeByte('('); try dg.renderCType(writer, ptr_ctype); - try writer.print("){x}", .{try dg.fmtIntLiteral(addr_val, .Other)}); + try writer.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .Other)}); }, .nav_ptr => |nav| try dg.renderNav(writer, nav, location), @@ -920,7 +924,7 @@ pub const DeclGen = struct { const offset_val = try pt.intValue(.usize, byte_offset); try writer.writeAll("((char *)"); try dg.renderPointer(writer, field.parent.*, location); - try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); + try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)}); }, } }, @@ -942,7 +946,7 @@ pub const DeclGen = struct { // The pointer already has an appropriate type - just do the arithmetic. try writer.writeByte('('); try dg.renderPointer(writer, elem.parent.*, location); - try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)}); + try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)}); } else { // We probably have an array pointer `T (*)[n]`. Cast to an element pointer, // and *then* apply the index. @@ -950,7 +954,7 @@ pub const DeclGen = struct { try dg.renderCType(writer, result_ctype); try writer.writeByte(')'); try dg.renderPointer(writer, elem.parent.*, location); - try writer.print(" + {})", .{try dg.fmtIntLiteral(index_val, .Other)}); + try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)}); } }, @@ -965,7 +969,7 @@ pub const DeclGen = struct { const offset_val = try pt.intValue(.usize, oac.byte_offset); try writer.writeAll("((char *)"); try dg.renderPointer(writer, oac.parent.*, location); - try writer.print(" + {})", .{try dg.fmtIntLiteral(offset_val, .Other)}); + try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)}); } }, } @@ -1037,11 +1041,11 @@ pub const DeclGen = struct { .empty_enum_value, => unreachable, // non-runtime values .int => |int| switch (int.storage) { - .u64, .i64, .big_int => try writer.print("{}", .{try dg.fmtIntLiteral(val, location)}), + .u64, .i64, .big_int => try writer.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}), .lazy_align, .lazy_size => { try writer.writeAll("(("); try dg.renderCType(writer, ctype); - try writer.print("){x})", .{try dg.fmtIntLiteral( + try writer.print("){f})", .{try dg.fmtIntLiteralHex( try pt.intValue(.usize, val.toUnsignedInt(zcu)), .Other, )}); @@ -1170,7 +1174,7 @@ pub const DeclGen = struct { try writer.writeAll(", "); empty = false; } - try writer.print("{x}", .{try dg.fmtIntLiteral( + try writer.print("{f}", .{try dg.fmtIntLiteralHex( try pt.intValue_big(repr_ty, repr_val_big.toConst()), location, )}); @@ -1642,15 +1646,15 @@ pub const DeclGen = struct { .enum_type, .error_set_type, .inferred_error_set_type, - => return writer.print("{x}", .{ - try dg.fmtIntLiteral(try pt.undefValue(ty), location), + => return writer.print("{f}", .{ + try dg.fmtIntLiteralHex(try pt.undefValue(ty), location), }), .ptr_type => |ptr_type| switch (ptr_type.flags.size) { .one, .many, .c => { try writer.writeAll("(("); try dg.renderCType(writer, ctype); - return writer.print("){x})", .{ - try dg.fmtIntLiteral(.undef_usize, .Other), + return writer.print("){f})", .{ + try dg.fmtIntLiteralHex(.undef_usize, .Other), }); }, .slice => { @@ -1663,8 +1667,8 @@ pub const DeclGen = struct { try writer.writeAll("{("); const ptr_ty = ty.slicePtrFieldType(zcu); try dg.renderType(writer, ptr_ty); - return writer.print("){x}, {0x}}}", .{ - try dg.fmtIntLiteral(.undef_usize, .Other), + return writer.print("){f}, {0x}}}", .{ + try dg.fmtIntLiteralHex(.undef_usize, .Other), }); }, }, @@ -1727,8 +1731,8 @@ pub const DeclGen = struct { } return writer.writeByte('}'); }, - .@"packed" => return writer.print("{x}", .{ - try dg.fmtIntLiteral(try pt.undefValue(ty), .Other), + .@"packed" => return writer.print("{f}", .{ + try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other), }), } }, @@ -1797,8 +1801,8 @@ pub const DeclGen = struct { } if (has_tag) try writer.writeByte('}'); }, - .@"packed" => return writer.print("{x}", .{ - try dg.fmtIntLiteral(try pt.undefValue(ty), .Other), + .@"packed" => return writer.print("{f}", .{ + try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other), }), } }, @@ -1940,8 +1944,8 @@ pub const DeclGen = struct { try w.print("{}", .{trailing}); switch (name) { .nav => |nav| try dg.renderNavName(w, nav), - .fmt_ctype_pool_string => |fmt| try w.print("{ }", .{fmt}), - .@"export" => |@"export"| try w.print("{ }", .{fmtIdentSolo(@"export".extern_name.toSlice(ip))}), + .fmt_ctype_pool_string => |fmt| try w.print("{f}", .{fmt}), + .@"export" => |@"export"| try w.print("{f}", .{fmtIdentSolo(@"export".extern_name.toSlice(ip))}), } try renderTypeSuffix( @@ -2126,7 +2130,7 @@ pub const DeclGen = struct { } else if (dest_bits > 64 and src_bits <= 64) { try w.writeAll("zig_make_"); try dg.renderTypeForBuiltinFnName(w, dest_ty); - try w.writeAll("(0, "); // TODO: Should the 0 go through fmtIntLiteral? + try w.writeAll("(0, "); if (src_is_ptr) { try w.writeByte('('); try dg.renderType(w, src_eff_ty); @@ -2398,7 +2402,7 @@ pub const DeclGen = struct { }; if (is_big) try writer.print(", {}", .{int_info.signedness == .signed}); - try writer.print(", {}", .{try dg.fmtIntLiteral( + try writer.print(", {f}", .{try dg.fmtIntLiteralDec( try pt.intValue(if (is_big) .u16 else .u8, int_info.bits), .FunctionArgument, )}); @@ -2408,18 +2412,38 @@ pub const DeclGen = struct { dg: *DeclGen, val: Value, loc: ValueRenderLocation, - ) !std.fmt.Formatter(formatIntLiteral) { + base: u8, + case: std.fmt.Case, + ) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { const zcu = dg.pt.zcu; const kind = loc.toCTypeKind(); const ty = val.typeOf(zcu); - return std.fmt.Formatter(formatIntLiteral){ .data = .{ + return .{ .data = .{ .dg = dg, .int_info = ty.intInfo(zcu), .kind = kind, .ctype = try dg.ctypeFromType(ty, kind), .val = val, + .base = base, + .case = case, } }; } + + fn fmtIntLiteralDec( + dg: *DeclGen, + val: Value, + loc: ValueRenderLocation, + ) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { + return fmtIntLiteral(dg, val, loc, 10, .lower); + } + + fn fmtIntLiteralHex( + dg: *DeclGen, + val: Value, + loc: ValueRenderLocation, + ) !std.fmt.Formatter(FormatIntLiteralContext, formatIntLiteral) { + return fmtIntLiteral(dg, val, loc, 16, .lower); + } }; const CTypeFix = enum { prefix, suffix }; @@ -2848,9 +2872,9 @@ pub fn genErrDecls(o: *Object) !void { for (names, 1..) |name_nts, val| { const name = name_nts.toSlice(ip); if (val > 1) try writer.writeAll(", "); - try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ + try writer.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{ fmtIdentUnsolo(name), - try o.dg.fmtIntLiteral(try pt.intValue(.usize, name.len), .StaticInitializer), + try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, name.len), .StaticInitializer), }); } try writer.writeAll("};\n"); @@ -2890,17 +2914,17 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn .storage = .{ .bytes = tag_name.toString() }, } }); - try w.print(" case {}: {{\n static ", .{ - try o.dg.fmtIntLiteral(try tag_val.intFromEnum(enum_ty, pt), .Other), + try w.print(" case {f}: {{\n static ", .{ + try o.dg.fmtIntLiteralDec(try tag_val.intFromEnum(enum_ty, pt), .Other), }); try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete); try w.writeAll(" = "); try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer); try w.writeAll(";\n return ("); try o.dg.renderType(w, name_slice_ty); - try w.print("){{{}, {}}};\n", .{ + try w.print("){{{f}, {f}}};\n", .{ fmtIdentUnsolo("name"), - try o.dg.fmtIntLiteral(try pt.intValue(.usize, tag_name_len), .Other), + try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, tag_name_len), .Other), }); try w.writeAll(" }\n"); @@ -2915,7 +2939,7 @@ pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFn const fn_val = zcu.navValue(fn_nav_index); const fn_ctype = try o.dg.ctypeFromType(fn_val.typeOf(zcu), .complete); const fn_info = fn_ctype.info(ctype_pool).function; - const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool); + const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool, true); const fwd = o.dg.fwdDeclWriter(); try fwd.print("static zig_{s} ", .{@tagName(key)}); @@ -3954,7 +3978,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeByte('('); try f.writeCValueDeref(writer, operand); try v.elem(f, writer); - try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_val)}); + try writer.print(", {f})", .{try f.fmtIntLiteralDec(bit_offset_val)}); if (cant_cast) try writer.writeByte(')'); try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits); try writer.writeByte(')'); @@ -4102,8 +4126,8 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeByte('('); try f.writeCValue(writer, operand, .FunctionArgument); try v.elem(f, writer); - try writer.print(", {x})", .{ - try f.fmtIntLiteral(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)), + try writer.print(", {f})", .{ + try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)), }); }, .signed => { @@ -4127,9 +4151,9 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { try f.writeCValue(writer, operand, .FunctionArgument); try v.elem(f, writer); if (c_bits == 128) try writer.writeByte(')'); - try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)}); + try writer.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)}); if (c_bits == 128) try writer.writeByte(')'); - try writer.print(", {})", .{try f.fmtIntLiteral(shift_val)}); + try writer.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)}); }, } if (need_lo) try writer.writeByte(')'); @@ -4244,7 +4268,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { try writer.writeByte('('); try f.writeCValueDeref(writer, ptr_val); try v.elem(f, writer); - try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(mask_val)}); + try writer.print(", {f}), zig_shl_", .{try f.fmtIntLiteralHex(mask_val)}); try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); try writer.writeByte('('); const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64; @@ -4267,7 +4291,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { try f.writeCValue(writer, src_val, .Other); try v.elem(f, writer); if (cant_cast) try writer.writeByte(')'); - try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_val)}); + try writer.print(", {f}))", .{try f.fmtIntLiteralDec(bit_offset_val)}); try a.end(f, writer); try v.end(f, inst, writer); } else { @@ -5348,7 +5372,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void write_val: { if (condition_ty.isPtrAtRuntime(zcu)) { if (item_value.?.getUnsignedInt(zcu)) |item_int| { - try writer.print("{}", .{try f.fmtIntLiteral(try pt.intValue(lowered_condition_ty, item_int))}); + try writer.print("{f}", .{try f.fmtIntLiteralDec(try pt.intValue(lowered_condition_ty, item_int))}); break :write_val; } } @@ -6004,8 +6028,8 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { try f.renderType(writer, u8_ptr_ty); try writer.writeByte(')'); try f.writeCValue(writer, field_ptr_val, .Other); - try writer.print(" - {})", .{ - try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)), + try writer.print(" - {f})", .{ + try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)), }); }, } @@ -6049,8 +6073,8 @@ fn fieldPtr( try f.renderType(writer, u8_ptr_ty); try writer.writeByte(')'); try f.writeCValue(writer, container_ptr_val, .Other); - try writer.print(" + {})", .{ - try f.fmtIntLiteral(try pt.intValue(.usize, byte_offset)), + try writer.print(" + {f})", .{ + try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)), }); }, } @@ -6121,8 +6145,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeByte('('); } try f.writeCValue(writer, struct_byval, .Other); - if (bit_offset > 0) try writer.print(", {})", .{ - try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)), + if (bit_offset > 0) try writer.print(", {f})", .{ + try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)), }); if (cant_cast) try writer.writeByte(')'); try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits); @@ -6227,8 +6251,8 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { if (!payload_ty.hasRuntimeBits(zcu)) try f.writeCValue(writer, operand, .Other) else if (error_ty.errorSetIsEmpty(zcu)) - try writer.print("{}", .{ - try f.fmtIntLiteral(try pt.intValue(try pt.errorIntType(), 0)), + try writer.print("{f}", .{ + try f.fmtIntLiteralDec(try pt.intValue(try pt.errorIntType(), 0)), }) else if (operand_is_ptr) try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) @@ -6374,7 +6398,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete)); try f.writeCValueDeref(writer, operand); try a.assign(f, writer); - try writer.print("{}", .{try f.fmtIntLiteral(no_err)}); + try writer.print("{f}", .{try f.fmtIntLiteralDec(no_err)}); try a.end(f, writer); return .none; } @@ -6382,7 +6406,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { const a = try Assignment.start(f, writer, try f.ctypeFromType(err_int_ty, .complete)); try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }); try a.assign(f, writer); - try writer.print("{}", .{try f.fmtIntLiteral(no_err)}); + try writer.print("{f}", .{try f.fmtIntLiteralDec(no_err)}); try a.end(f, writer); } @@ -6520,7 +6544,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { if (operand_child_ctype.info(ctype_pool) == .array) { try writer.writeByte('&'); try f.writeCValueDeref(writer, operand); - try writer.print("[{}]", .{try f.fmtIntLiteral(.zero_usize)}); + try writer.print("[{f}]", .{try f.fmtIntLiteralDec(.zero_usize)}); } else try f.writeCValue(writer, operand, .Other); } try a.end(f, writer); @@ -6529,8 +6553,8 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { const a = try Assignment.start(f, writer, .usize); try f.writeCValueMember(writer, local, .{ .identifier = "len" }); try a.assign(f, writer); - try writer.print("{}", .{ - try f.fmtIntLiteral(try pt.intValue(.usize, array_ty.arrayLen(zcu))), + try writer.print("{f}", .{ + try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))), }); try a.end(f, writer); } @@ -6736,9 +6760,9 @@ fn airCmpBuiltinCall( try v.elem(f, writer); try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info); try writer.writeByte(')'); - if (!ref_ret) try writer.print("{s}{}", .{ + if (!ref_ret) try writer.print("{s}{f}", .{ compareOperatorC(operator), - try f.fmtIntLiteral(try pt.intValue(.i32, 0)), + try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)), }); try writer.writeAll(";\n"); try v.end(f, inst, writer); @@ -7148,8 +7172,8 @@ fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_t const pt = f.object.dg.pt; const zcu = pt.zcu; switch (dest_ty.ptrSize(zcu)) { - .one => try writer.print("{}", .{ - try f.fmtIntLiteral(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))), + .one => try writer.print("{f}", .{ + try f.fmtIntLiteralDec(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))), }), .many, .c => unreachable, .slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }), @@ -7635,8 +7659,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeByte(')'); } - try writer.print(", {}", .{ - try f.fmtIntLiteral(try pt.intValue(bit_offset_ty, bit_offset)), + try writer.print(", {f}", .{ + try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)), }); try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits); try writer.writeByte(')'); @@ -7693,7 +7717,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete)); try f.writeCValueMember(writer, local, .{ .identifier = "tag" }); try a.assign(f, writer); - try writer.print("{}", .{try f.fmtIntLiteral(try tag_val.intFromEnum(tag_ty, pt))}); + try writer.print("{f}", .{try f.fmtIntLiteralDec(try tag_val.intFromEnum(tag_ty, pt))}); try a.end(f, writer); } break :field .{ .payload_identifier = field_name.toSlice(ip) }; @@ -8207,14 +8231,12 @@ fn stringLiteral( }; } -const FormatStringContext = struct { str: []const u8, sentinel: ?u8 }; -fn formatStringLiteral( - data: FormatStringContext, - writer: *std.io.Writer, - comptime fmt: []const u8, // TODO move this state to FormatStringContext -) std.io.Writer.Error!void { - if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt); +const FormatStringContext = struct { + str: []const u8, + sentinel: ?u8, +}; +fn formatStringLiteral(data: FormatStringContext, writer: *std.io.Writer) std.io.Writer.Error!void { var literal = stringLiteral(writer, data.str.len + @intFromBool(data.sentinel != null)); try literal.start(); for (data.str) |c| try literal.writeChar(c); @@ -8238,12 +8260,10 @@ const FormatIntLiteralContext = struct { kind: CType.Kind, ctype: CType, val: Value, + base: u8, + case: std.fmt.Case, }; -fn formatIntLiteral( - data: FormatIntLiteralContext, - writer: *std.io.Writer, - comptime fmt: []const u8, // TODO move this state to FormatIntLiteralContext -) std.io.Writer.Error!void { +fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.io.Writer.Error!void { const pt = data.dg.pt; const zcu = pt.zcu; const target = &data.dg.mod.resolved_target.result; @@ -8268,7 +8288,7 @@ fn formatIntLiteral( var int_buf: Value.BigIntSpace = undefined; const int = if (data.val.isUndefDeep(zcu)) blk: { - undef_limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)); + undef_limbs = try oom(allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits))); @memset(undef_limbs, undefPattern(BigIntLimb)); var undef_int = BigInt.Mutable{ @@ -8286,7 +8306,7 @@ fn formatIntLiteral( const one = BigInt.Mutable.init(&one_limbs, 1).toConst(); var wrap = BigInt.Mutable{ - .limbs = try allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)), + .limbs = try oom(allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits))), .len = undefined, .positive = undefined, }; @@ -8333,32 +8353,14 @@ fn formatIntLiteral( if (!int.positive) try writer.writeByte('-'); try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool); - const style: struct { base: u8, case: std.fmt.Case = undefined } = switch (fmt.len) { - 0 => .{ .base = 10 }, - 1 => switch (fmt[0]) { - 'b' => style: { - try writer.writeAll("0b"); - break :style .{ .base = 2 }; - }, - 'o' => style: { - try writer.writeByte('0'); - break :style .{ .base = 8 }; - }, - 'd' => .{ .base = 10 }, - 'x', 'X' => |base| style: { - try writer.writeAll("0x"); - break :style .{ .base = 16, .case = switch (base) { - 'x' => .lower, - 'X' => .upper, - else => unreachable, - } }; - }, - else => @compileError("Invalid fmt: " ++ fmt), - }, - else => @compileError("Invalid fmt: " ++ fmt), - }; - - const string = try int.abs().toStringAlloc(allocator, style.base, style.case); + switch (data.base) { + 2 => try writer.writeAll("0b"), + 8 => try writer.writeByte('0'), + 10 => {}, + 16 => try writer.writeAll("0x"), + else => unreachable, + } + const string = try oom(int.abs().toStringAlloc(allocator, data.base, data.case)); defer allocator.free(string); try writer.writeAll(string); } else { @@ -8411,8 +8413,10 @@ fn formatIntLiteral( .int_info = c_limb_int_info, .kind = data.kind, .ctype = c_limb_ctype, - .val = try pt.intValue_big(.comptime_int, c_limb_mut.toConst()), - }, fmt, writer); + .val = try oom(pt.intValue_big(.comptime_int, c_limb_mut.toConst())), + .base = data.base, + .case = data.case, + }, writer); } } try data.ctype.renderLiteralSuffix(writer, ctype_pool); @@ -8492,11 +8496,11 @@ const Vectorize = struct { try writer.writeAll("for ("); try f.writeCValue(writer, local, .Other); - try writer.print(" = {d}; ", .{try f.fmtIntLiteral(.zero_usize)}); + try writer.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)}); try f.writeCValue(writer, local, .Other); - try writer.print(" < {d}; ", .{try f.fmtIntLiteral(try pt.intValue(.usize, ty.vectorLen(zcu)))}); + try writer.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))}); try f.writeCValue(writer, local, .Other); - try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(.one_usize)}); + try writer.print(" += {f}) {{\n", .{try f.fmtIntLiteralDec(.one_usize)}); f.object.indent_writer.pushIndent(); break :index .{ .index = local }; @@ -8622,3 +8626,9 @@ fn deinitFreeLocalsMap(gpa: Allocator, map: *LocalsMap) void { } map.deinit(gpa); } + +fn oom(x: anytype) error{WriteFailed}!@typeInfo(@TypeOf(x)).error_union.payload { + return x catch |err| switch (err) { + error.OutOfMemory => error.WriteFailed, + }; +} diff --git a/src/codegen/c/Type.zig b/src/codegen/c/Type.zig index ad27832e77..77555d773c 100644 --- a/src/codegen/c/Type.zig +++ b/src/codegen/c/Type.zig @@ -209,7 +209,7 @@ pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 { }; } -pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *const Pool) @TypeOf(writer).Error!void { +pub fn renderLiteralPrefix(ctype: CType, w: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void { switch (ctype.info(pool)) { .basic => |basic_info| switch (basic_info) { .void => unreachable, @@ -224,7 +224,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con .uintptr_t, .intptr_t, => switch (kind) { - else => try writer.print("({s})", .{@tagName(basic_info)}), + else => try w.print("({s})", .{@tagName(basic_info)}), .global => {}, }, .int, @@ -246,7 +246,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con .int32_t, .uint64_t, .int64_t, - => try writer.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}), + => try w.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}), .zig_u128, .zig_i128, .zig_f16, @@ -255,7 +255,7 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con .zig_f80, .zig_f128, .zig_c_longdouble, - => try writer.print("zig_{s}_{s}(", .{ + => try w.print("zig_{s}_{s}(", .{ switch (kind) { else => "make", .global => "init", @@ -265,12 +265,12 @@ pub fn renderLiteralPrefix(ctype: CType, writer: anytype, kind: Kind, pool: *con .va_list => unreachable, _ => unreachable, }, - .array, .vector => try writer.writeByte('{'), + .array, .vector => try w.writeByte('{'), else => unreachable, } } -pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @TypeOf(writer).Error!void { +pub fn renderLiteralSuffix(ctype: CType, w: *Writer, pool: *const Pool) Writer.Error!void { switch (ctype.info(pool)) { .basic => |basic_info| switch (basic_info) { .void => unreachable, @@ -280,20 +280,20 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty .short, .int, => {}, - .long => try writer.writeByte('l'), - .@"long long" => try writer.writeAll("ll"), + .long => try w.writeByte('l'), + .@"long long" => try w.writeAll("ll"), .@"unsigned char", .@"unsigned short", .@"unsigned int", - => try writer.writeByte('u'), + => try w.writeByte('u'), .@"unsigned long", .size_t, .uintptr_t, - => try writer.writeAll("ul"), - .@"unsigned long long" => try writer.writeAll("ull"), - .float => try writer.writeByte('f'), + => try w.writeAll("ul"), + .@"unsigned long long" => try w.writeAll("ull"), + .float => try w.writeByte('f'), .double => {}, - .@"long double" => try writer.writeByte('l'), + .@"long double" => try w.writeByte('l'), .bool, .ptrdiff_t, .intptr_t, @@ -314,11 +314,11 @@ pub fn renderLiteralSuffix(ctype: CType, writer: anytype, pool: *const Pool) @Ty .zig_f80, .zig_f128, .zig_c_longdouble, - => try writer.writeByte(')'), + => try w.writeByte(')'), .va_list => unreachable, _ => unreachable, }, - .array, .vector => try writer.writeByte('}'), + .array, .vector => try w.writeByte('}'), else => unreachable, } } @@ -938,7 +938,7 @@ pub const Pool = struct { index: String.Index, const FormatData = struct { string: String, pool: *const Pool }; - fn format(data: FormatData, writer: *std.io.Writer) std.io.Writer.Error!void { + fn format(data: FormatData, writer: *Writer) Writer.Error!void { if (data.string.toSlice(data.pool)) |slice| try writer.writeAll(slice) else @@ -2884,7 +2884,7 @@ pub const Pool = struct { comptime fmt_str: []const u8, fmt_args: anytype, ) !String { - try pool.string_bytes.writer(allocator).print(fmt_str, fmt_args); + try pool.string_bytes.print(allocator, fmt_str, fmt_args); return pool.trailingString(allocator); } @@ -3275,10 +3275,12 @@ pub const AlignAs = packed struct { } }; +const std = @import("std"); const assert = std.debug.assert; +const Writer = std.io.Writer; + const CType = @This(); const InternPool = @import("../../InternPool.zig"); const Module = @import("../../Package/Module.zig"); -const std = @import("std"); const Type = @import("../../Type.zig"); const Zcu = @import("../../Zcu.zig"); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 40c5c234d3..3d670dce83 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -239,12 +239,12 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8 .none, .windows, => {}, - .semver => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{ + .semver => |ver| try llvm_triple.print("{d}.{d}.{d}", .{ ver.min.major, ver.min.minor, ver.min.patch, }), - inline .linux, .hurd => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{ + inline .linux, .hurd => |ver| try llvm_triple.print("{d}.{d}.{d}", .{ ver.range.min.major, ver.range.min.minor, ver.range.min.patch, @@ -295,13 +295,13 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8 .windows, => {}, inline .hurd, .linux => |ver| if (target.abi.isGnu()) { - try llvm_triple.writer().print("{d}.{d}.{d}", .{ + try llvm_triple.print("{d}.{d}.{d}", .{ ver.glibc.major, ver.glibc.minor, ver.glibc.patch, }); } else if (@TypeOf(ver) == std.Target.Os.LinuxVersionRange and target.abi.isAndroid()) { - try llvm_triple.writer().print("{d}", .{ver.android}); + try llvm_triple.print("{d}", .{ver.android}); }, } @@ -746,12 +746,18 @@ pub const Object = struct { try wip.finish(); } - fn genModuleLevelAssembly(object: *Object) !void { - const writer = object.builder.setModuleAsm(); + fn genModuleLevelAssembly(object: *Object) Allocator.Error!void { + const b = &object.builder; + const gpa = b.gpa; + b.module_asm.clearRetainingCapacity(); for (object.pt.zcu.global_assembly.values()) |assembly| { - try writer.print("{s}\n", .{assembly}); + try b.module_asm.ensureUnusedCapacity(gpa, assembly.len + 1); + b.module_asm.appendSliceAssumeCapacity(assembly); + b.module_asm.appendAssumeCapacity('\n'); + } + if (b.module_asm.getLastOrNull()) |last| { + if (last != '\n') try b.module_asm.append(gpa, '\n'); } - try object.builder.finishModuleAsm(); } pub const EmitOptions = struct { @@ -939,7 +945,9 @@ pub const Object = struct { if (std.mem.eql(u8, path, "-")) { o.builder.dump(); } else { - _ = try o.builder.printToFile(path); + o.builder.printToFilePath(std.fs.cwd(), path) catch |err| { + log.err("failed printing LLVM module to \"{s}\": {s}", .{ path, @errorName(err) }); + }; } } @@ -2680,10 +2688,12 @@ pub const Object = struct { } fn allocTypeName(o: *Object, ty: Type) Allocator.Error![:0]const u8 { - var buffer = std.ArrayList(u8).init(o.gpa); - errdefer buffer.deinit(); - try ty.print(buffer.writer(), o.pt); - return buffer.toOwnedSliceSentinel(0); + var aw: std.io.Writer.Allocating = .init(o.gpa); + defer aw.deinit(); + ty.print(&aw.writer, o.pt) catch |err| switch (err) { + error.WriteFailed => return error.OutOfMemory, + }; + return aw.toOwnedSliceSentinel(0); } /// If the llvm function does not exist, create it. @@ -4482,7 +4492,7 @@ pub const Object = struct { const target = &zcu.root_mod.resolved_target.result; const function_index = try o.builder.addFunction( try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), - try o.builder.strtabStringFmt("__zig_tag_name_{}", .{enum_type.name.fmt(ip)}), + try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_type.name.fmt(ip)}), toLlvmAddressSpace(.generic, target), ); @@ -4633,7 +4643,7 @@ pub const NavGen = struct { if (zcu.getTarget().cpu.arch.isWasm() and ty.zigTypeTag(zcu) == .@"fn") { if (lib_name.toSlice(ip)) |lib_name_slice| { if (!std.mem.eql(u8, lib_name_slice, "c")) { - break :decl_name try o.builder.strtabStringFmt("{}|{s}", .{ nav.name.fmt(ip), lib_name_slice }); + break :decl_name try o.builder.strtabStringFmt("{f}|{s}", .{ nav.name.fmt(ip), lib_name_slice }); } } } @@ -7472,7 +7482,7 @@ pub const FuncGen = struct { llvm_param_types[llvm_param_i] = llvm_elem_ty; } - try llvm_constraints.writer(self.gpa).print(",{d}", .{output_index}); + try llvm_constraints.print(self.gpa, ",{d}", .{output_index}); // In the case of indirect inputs, LLVM requires the callsite to have // an elementtype(<ty>) attribute. @@ -7573,7 +7583,7 @@ pub const FuncGen = struct { // we should validate the assembly in Sema; by now it is too late return self.todo("unknown input or output name: '{s}'", .{name}); }; - try rendered_template.writer().print("{d}", .{index}); + try rendered_template.print("{d}", .{index}); if (byte == ':') { try rendered_template.append(':'); modifier_start = i + 1; @@ -10370,7 +10380,7 @@ pub const FuncGen = struct { const target = &zcu.root_mod.resolved_target.result; const function_index = try o.builder.addFunction( try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal), - try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{enum_type.name.fmt(ip)}), + try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_type.name.fmt(ip)}), toLlvmAddressSpace(.generic, target), ); diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 8a782c54aa..901687d40b 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -1260,10 +1260,12 @@ const NavGen = struct { // Turn a Zig type's name into a cache reference. fn resolveTypeName(self: *NavGen, ty: Type) ![]const u8 { - var name = std.ArrayList(u8).init(self.gpa); - defer name.deinit(); - try ty.print(name.writer(), self.pt); - return try name.toOwnedSlice(); + var aw: std.io.Writer.Allocating = .init(self.gpa); + defer aw.deinit(); + ty.print(&aw.writer, self.pt) catch |err| switch (err) { + error.WriteFailed => return error.OutOfMemory, + }; + return try aw.toOwnedSlice(); } /// Create an integer type suitable for storing at least 'bits' bits. diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index b348b3620b..372d8f1ac8 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -938,10 +938,9 @@ const x86_64 = struct { } fn encode(insts: []const Instruction, code: []u8) !void { - var stream = std.io.fixedBufferStream(code); - const writer = stream.writer(); + var stream: std.io.Writer = .fixed(code); for (insts) |inst| { - try inst.encode(writer, .{}); + try inst.encode(&stream, .{}); } } |
