authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-02 16:31:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:52-07:00
log6963a1c7b97e459be0a5f3ca913ffa0862a099a8
treeae0a804c56aa674e2b9f98f6152a2ce1c2c4334a
parent6314e6f238758ce84a288e9ed990540232d04656

C backend: prepare for merge


1 files changed, 1763 insertions(+), 1762 deletions(-)

src/codegen/c.zig+1763-1762
...@@ -4,6 +4,7 @@ const assert = std.debug.assert;...@@ -4,6 +4,7 @@ const assert = std.debug.assert;
4const mem = std.mem;4const mem = std.mem;
5const log = std.log.scoped(.c);5const log = std.log.scoped(.c);
6const Allocator = mem.Allocator;6const Allocator = mem.Allocator;
7const Writer = std.io.Writer;
78
8const dev = @import("../dev.zig");9const dev = @import("../dev.zig");
9const link = @import("../link.zig");10const link = @import("../link.zig");
...@@ -340,28 +341,28 @@ fn isReservedIdent(ident: []const u8) bool {...@@ -340,28 +341,28 @@ fn isReservedIdent(ident: []const u8) bool {
340 } else return reserved_idents.has(ident);341 } else return reserved_idents.has(ident);
341}342}
342343
343fn formatIdentSolo(ident: []const u8, writer: *std.io.Writer) std.io.Writer.Error!void {344fn formatIdentSolo(ident: []const u8, w: *std.io.Writer) std.io.Writer.Error!void {
344 return formatIdentOptions(ident, writer, true);345 return formatIdentOptions(ident, w, true);
345}346}
346347
347fn formatIdentUnsolo(ident: []const u8, writer: *std.io.Writer) std.io.Writer.Error!void {348fn formatIdentUnsolo(ident: []const u8, w: *std.io.Writer) std.io.Writer.Error!void {
348 return formatIdentOptions(ident, writer, false);349 return formatIdentOptions(ident, w, false);
349}350}
350351
351fn formatIdentOptions(ident: []const u8, writer: *std.io.Writer, solo: bool) std.io.Writer.Error!void {352fn formatIdentOptions(ident: []const u8, w: *std.io.Writer, solo: bool) std.io.Writer.Error!void {
352 if (solo and isReservedIdent(ident)) {353 if (solo and isReservedIdent(ident)) {
353 try writer.writeAll("zig_e_");354 try w.writeAll("zig_e_");
354 }355 }
355 for (ident, 0..) |c, i| {356 for (ident, 0..) |c, i| {
356 switch (c) {357 switch (c) {
357 'a'...'z', 'A'...'Z', '_' => try writer.writeByte(c),358 'a'...'z', 'A'...'Z', '_' => try w.writeByte(c),
358 '.' => try writer.writeByte('_'),359 '.' => try w.writeByte('_'),
359 '0'...'9' => if (i == 0) {360 '0'...'9' => if (i == 0) {
360 try writer.print("_{x:2}", .{c});361 try w.print("_{x:2}", .{c});
361 } else {362 } else {
362 try writer.writeByte(c);363 try w.writeByte(c);
363 },364 },
364 else => try writer.print("_{x:2}", .{c}),365 else => try w.print("_{x:2}", .{c}),
365 }366 }
366 }367 }
367}368}
...@@ -379,11 +380,11 @@ const CTypePoolStringFormatData = struct {...@@ -379,11 +380,11 @@ const CTypePoolStringFormatData = struct {
379 ctype_pool: *const CType.Pool,380 ctype_pool: *const CType.Pool,
380 solo: bool,381 solo: bool,
381};382};
382fn formatCTypePoolString(data: CTypePoolStringFormatData, writer: *std.io.Writer) std.io.Writer.Error!void {383fn formatCTypePoolString(data: CTypePoolStringFormatData, w: *std.io.Writer) std.io.Writer.Error!void {
383 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|384 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
384 try formatIdentOptions(slice, writer, data.solo)385 try formatIdentOptions(slice, w, data.solo)
385 else386 else
386 try writer.print("{}", .{data.ctype_pool_string.fmt(data.ctype_pool)});387 try w.print("{}", .{data.ctype_pool_string.fmt(data.ctype_pool)});
387}388}
388pub fn fmtCTypePoolString(389pub fn fmtCTypePoolString(
389 ctype_pool_string: CType.Pool.String,390 ctype_pool_string: CType.Pool.String,
...@@ -448,18 +449,18 @@ pub const Function = struct {...@@ -448,18 +449,18 @@ pub const Function = struct {
448 const ty = f.typeOf(ref);449 const ty = f.typeOf(ref);
449450
450 const result: CValue = if (lowersToArray(ty, pt)) result: {451 const result: CValue = if (lowersToArray(ty, pt)) result: {
451 const writer = f.object.codeHeaderWriter();452 const w = f.object.codeHeaderWriter();
452 const decl_c_value = try f.allocLocalValue(.{453 const decl_c_value = try f.allocLocalValue(.{
453 .ctype = try f.ctypeFromType(ty, .complete),454 .ctype = try f.ctypeFromType(ty, .complete),
454 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)),455 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(pt.zcu)),
455 });456 });
456 const gpa = f.object.dg.gpa;457 const gpa = f.object.dg.gpa;
457 try f.allocs.put(gpa, decl_c_value.new_local, false);458 try f.allocs.put(gpa, decl_c_value.new_local, false);
458 try writer.writeAll("static ");459 try w.writeAll("static ");
459 try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, Const, .none, .complete);460 try f.object.dg.renderTypeAndName(w, ty, decl_c_value, Const, .none, .complete);
460 try writer.writeAll(" = ");461 try w.writeAll(" = ");
461 try f.object.dg.renderValue(writer, val, .StaticInitializer);462 try f.object.dg.renderValue(w, val, .StaticInitializer);
462 try writer.writeAll(";\n ");463 try w.writeAll(";\n ");
463 break :result .{ .local = decl_c_value.new_local };464 break :result .{ .local = decl_c_value.new_local };
464 } else .{ .constant = val };465 } else .{ .constant = val };
465466
...@@ -512,7 +513,7 @@ pub const Function = struct {...@@ -512,7 +513,7 @@ pub const Function = struct {
512 return result;513 return result;
513 }514 }
514515
515 fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void {516 fn writeCValue(f: *Function, w: *Writer, c_value: CValue, location: ValueRenderLocation) !void {
516 switch (c_value) {517 switch (c_value) {
517 .none => unreachable,518 .none => unreachable,
518 .new_local, .local => |i| try w.print("t{d}", .{i}),519 .new_local, .local => |i| try w.print("t{d}", .{i}),
...@@ -525,7 +526,7 @@ pub const Function = struct {...@@ -525,7 +526,7 @@ pub const Function = struct {
525 }526 }
526 }527 }
527528
528 fn writeCValueDeref(f: *Function, w: anytype, c_value: CValue) !void {529 fn writeCValueDeref(f: *Function, w: *Writer, c_value: CValue) !void {
529 switch (c_value) {530 switch (c_value) {
530 .none => unreachable,531 .none => unreachable,
531 .new_local, .local, .constant => {532 .new_local, .local, .constant => {
...@@ -546,38 +547,38 @@ pub const Function = struct {...@@ -546,38 +547,38 @@ pub const Function = struct {
546547
547 fn writeCValueMember(548 fn writeCValueMember(
548 f: *Function,549 f: *Function,
549 writer: anytype,550 w: *Writer,
550 c_value: CValue,551 c_value: CValue,
551 member: CValue,552 member: CValue,
552 ) error{ OutOfMemory, AnalysisFail }!void {553 ) error{ OutOfMemory, AnalysisFail }!void {
553 switch (c_value) {554 switch (c_value) {
554 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {555 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {
555 try f.writeCValue(writer, c_value, .Other);556 try f.writeCValue(w, c_value, .Other);
556 try writer.writeByte('.');557 try w.writeByte('.');
557 try f.writeCValue(writer, member, .Other);558 try f.writeCValue(w, member, .Other);
558 },559 },
559 else => return f.object.dg.writeCValueMember(writer, c_value, member),560 else => return f.object.dg.writeCValueMember(w, c_value, member),
560 }561 }
561 }562 }
562563
563 fn writeCValueDerefMember(f: *Function, writer: anytype, c_value: CValue, member: CValue) !void {564 fn writeCValueDerefMember(f: *Function, w: *Writer, c_value: CValue, member: CValue) !void {
564 switch (c_value) {565 switch (c_value) {
565 .new_local, .local, .arg, .arg_array => {566 .new_local, .local, .arg, .arg_array => {
566 try f.writeCValue(writer, c_value, .Other);567 try f.writeCValue(w, c_value, .Other);
567 try writer.writeAll("->");568 try w.writeAll("->");
568 },569 },
569 .constant => {570 .constant => {
570 try writer.writeByte('(');571 try w.writeByte('(');
571 try f.writeCValue(writer, c_value, .Other);572 try f.writeCValue(w, c_value, .Other);
572 try writer.writeAll(")->");573 try w.writeAll(")->");
573 },574 },
574 .local_ref => {575 .local_ref => {
575 try f.writeCValueDeref(writer, c_value);576 try f.writeCValueDeref(w, c_value);
576 try writer.writeByte('.');577 try w.writeByte('.');
577 },578 },
578 else => return f.object.dg.writeCValueDerefMember(writer, c_value, member),579 else => return f.object.dg.writeCValueDerefMember(w, c_value, member),
579 }580 }
580 try f.writeCValue(writer, member, .Other);581 try f.writeCValue(w, member, .Other);
581 }582 }
582583
583 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {584 fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
...@@ -592,15 +593,15 @@ pub const Function = struct {...@@ -592,15 +593,15 @@ pub const Function = struct {
592 return f.object.dg.byteSize(ctype);593 return f.object.dg.byteSize(ctype);
593 }594 }
594595
595 fn renderType(f: *Function, w: anytype, ctype: Type) !void {596 fn renderType(f: *Function, w: *Writer, ctype: Type) !void {
596 return f.object.dg.renderType(w, ctype);597 return f.object.dg.renderType(w, ctype);
597 }598 }
598599
599 fn renderCType(f: *Function, w: anytype, ctype: CType) !void {600 fn renderCType(f: *Function, w: *Writer, ctype: CType) !void {
600 return f.object.dg.renderCType(w, ctype);601 return f.object.dg.renderCType(w, ctype);
601 }602 }
602603
603 fn renderIntCast(f: *Function, w: anytype, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {604 fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
604 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);605 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
605 }606 }
606607
...@@ -671,12 +672,12 @@ pub const Function = struct {...@@ -671,12 +672,12 @@ pub const Function = struct {
671 },672 },
672 else => {},673 else => {},
673 }674 }
674 const writer = f.object.writer();675 const w = f.object.writer();
675 const a = try Assignment.start(f, writer, ctype);676 const a = try Assignment.start(f, w, ctype);
676 try f.writeCValue(writer, dst, .Other);677 try f.writeCValue(w, dst, .Other);
677 try a.assign(f, writer);678 try a.assign(f, w);
678 try f.writeCValue(writer, src, .Other);679 try f.writeCValue(w, src, .Other);
679 try a.end(f, writer);680 try a.end(f, w);
680 }681 }
681682
682 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {683 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
...@@ -711,7 +712,7 @@ pub const Object = struct {...@@ -711,7 +712,7 @@ pub const Object = struct {
711 code_header: std.ArrayList(u8) = undefined,712 code_header: std.ArrayList(u8) = undefined,
712 indent_writer: IndentWriter(std.ArrayList(u8).Writer),713 indent_writer: IndentWriter(std.ArrayList(u8).Writer),
713714
714 fn writer(o: *Object) IndentWriter(std.ArrayList(u8).Writer).Writer {715 fn w(o: *Object) IndentWriter(std.ArrayList(u8).Writer).Writer {
715 return o.indent_writer.writer();716 return o.indent_writer.writer();
716 }717 }
717718
...@@ -760,7 +761,7 @@ pub const DeclGen = struct {...@@ -760,7 +761,7 @@ pub const DeclGen = struct {
760761
761 fn renderUav(762 fn renderUav(
762 dg: *DeclGen,763 dg: *DeclGen,
763 writer: anytype,764 w: *Writer,
764 uav: InternPool.Key.Ptr.BaseAddr.Uav,765 uav: InternPool.Key.Ptr.BaseAddr.Uav,
765 location: ValueRenderLocation,766 location: ValueRenderLocation,
766 ) error{ OutOfMemory, AnalysisFail }!void {767 ) error{ OutOfMemory, AnalysisFail }!void {
...@@ -774,14 +775,14 @@ pub const DeclGen = struct {...@@ -774,14 +775,14 @@ pub const DeclGen = struct {
774 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.775 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
775 const ptr_ty: Type = .fromInterned(uav.orig_ty);776 const ptr_ty: Type = .fromInterned(uav.orig_ty);
776 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {777 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {
777 return dg.writeCValue(writer, .{ .undef = ptr_ty });778 return dg.writeCValue(w, .{ .undef = ptr_ty });
778 }779 }
779780
780 // Chase function values in order to be able to reference the original function.781 // Chase function values in order to be able to reference the original function.
781 switch (ip.indexToKey(uav.val)) {782 switch (ip.indexToKey(uav.val)) {
782 .variable => unreachable,783 .variable => unreachable,
783 .func => |func| return dg.renderNav(writer, func.owner_nav, location),784 .func => |func| return dg.renderNav(w, func.owner_nav, location),
784 .@"extern" => |@"extern"| return dg.renderNav(writer, @"extern".owner_nav, location),785 .@"extern" => |@"extern"| return dg.renderNav(w, @"extern".owner_nav, location),
785 else => {},786 else => {},
786 }787 }
787788
...@@ -795,13 +796,13 @@ pub const DeclGen = struct {...@@ -795,13 +796,13 @@ pub const DeclGen = struct {
795 const need_cast = !elem_ctype.eql(uav_ctype) and796 const need_cast = !elem_ctype.eql(uav_ctype) and
796 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);797 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
797 if (need_cast) {798 if (need_cast) {
798 try writer.writeAll("((");799 try w.writeAll("((");
799 try dg.renderCType(writer, ptr_ctype);800 try dg.renderCType(w, ptr_ctype);
800 try writer.writeByte(')');801 try w.writeByte(')');
801 }802 }
802 try writer.writeByte('&');803 try w.writeByte('&');
803 try renderUavName(writer, uav_val);804 try renderUavName(w, uav_val);
804 if (need_cast) try writer.writeByte(')');805 if (need_cast) try w.writeByte(')');
805806
806 // Indicate that the anon decl should be rendered to the output so that807 // Indicate that the anon decl should be rendered to the output so that
807 // our reference above is not undefined.808 // our reference above is not undefined.
...@@ -822,7 +823,7 @@ pub const DeclGen = struct {...@@ -822,7 +823,7 @@ pub const DeclGen = struct {
822823
823 fn renderNav(824 fn renderNav(
824 dg: *DeclGen,825 dg: *DeclGen,
825 writer: anytype,826 w: *Writer,
826 nav_index: InternPool.Nav.Index,827 nav_index: InternPool.Nav.Index,
827 location: ValueRenderLocation,828 location: ValueRenderLocation,
828 ) error{ OutOfMemory, AnalysisFail }!void {829 ) error{ OutOfMemory, AnalysisFail }!void {
...@@ -847,7 +848,7 @@ pub const DeclGen = struct {...@@ -847,7 +848,7 @@ pub const DeclGen = struct {
847 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));848 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));
848 const ptr_ty = try pt.navPtrType(owner_nav);849 const ptr_ty = try pt.navPtrType(owner_nav);
849 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {850 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {
850 return dg.writeCValue(writer, .{ .undef = ptr_ty });851 return dg.writeCValue(w, .{ .undef = ptr_ty });
851 }852 }
852853
853 // We shouldn't cast C function pointers as this is UB (when you call854 // We shouldn't cast C function pointers as this is UB (when you call
...@@ -860,18 +861,18 @@ pub const DeclGen = struct {...@@ -860,18 +861,18 @@ pub const DeclGen = struct {
860 const need_cast = !elem_ctype.eql(nav_ctype) and861 const need_cast = !elem_ctype.eql(nav_ctype) and
861 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);862 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
862 if (need_cast) {863 if (need_cast) {
863 try writer.writeAll("((");864 try w.writeAll("((");
864 try dg.renderCType(writer, ctype);865 try dg.renderCType(w, ctype);
865 try writer.writeByte(')');866 try w.writeByte(')');
866 }867 }
867 try writer.writeByte('&');868 try w.writeByte('&');
868 try dg.renderNavName(writer, owner_nav);869 try dg.renderNavName(w, owner_nav);
869 if (need_cast) try writer.writeByte(')');870 if (need_cast) try w.writeByte(')');
870 }871 }
871872
872 fn renderPointer(873 fn renderPointer(
873 dg: *DeclGen,874 dg: *DeclGen,
874 writer: anytype,875 w: *Writer,
875 derivation: Value.PointerDeriveStep,876 derivation: Value.PointerDeriveStep,
876 location: ValueRenderLocation,877 location: ValueRenderLocation,
877 ) error{ OutOfMemory, AnalysisFail }!void {878 ) error{ OutOfMemory, AnalysisFail }!void {
...@@ -882,18 +883,18 @@ pub const DeclGen = struct {...@@ -882,18 +883,18 @@ pub const DeclGen = struct {
882 .int => |int| {883 .int => |int| {
883 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);884 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
884 const addr_val = try pt.intValue(.usize, int.addr);885 const addr_val = try pt.intValue(.usize, int.addr);
885 try writer.writeByte('(');886 try w.writeByte('(');
886 try dg.renderCType(writer, ptr_ctype);887 try dg.renderCType(w, ptr_ctype);
887 try writer.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .Other)});888 try w.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .Other)});
888 },889 },
889890
890 .nav_ptr => |nav| try dg.renderNav(writer, nav, location),891 .nav_ptr => |nav| try dg.renderNav(w, nav, location),
891 .uav_ptr => |uav| try dg.renderUav(writer, uav, location),892 .uav_ptr => |uav| try dg.renderUav(w, uav, location),
892893
893 inline .eu_payload_ptr, .opt_payload_ptr => |info| {894 inline .eu_payload_ptr, .opt_payload_ptr => |info| {
894 try writer.writeAll("&(");895 try w.writeAll("&(");
895 try dg.renderPointer(writer, info.parent.*, location);896 try dg.renderPointer(w, info.parent.*, location);
896 try writer.writeAll(")->payload");897 try w.writeAll(")->payload");
897 },898 },
898899
899 .field_ptr => |field| {900 .field_ptr => |field| {
...@@ -905,26 +906,26 @@ pub const DeclGen = struct {...@@ -905,26 +906,26 @@ pub const DeclGen = struct {
905 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {906 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, pt)) {
906 .begin => {907 .begin => {
907 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);908 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
908 try writer.writeByte('(');909 try w.writeByte('(');
909 try dg.renderCType(writer, ptr_ctype);910 try dg.renderCType(w, ptr_ctype);
910 try writer.writeByte(')');911 try w.writeByte(')');
911 try dg.renderPointer(writer, field.parent.*, location);912 try dg.renderPointer(w, field.parent.*, location);
912 },913 },
913 .field => |name| {914 .field => |name| {
914 try writer.writeAll("&(");915 try w.writeAll("&(");
915 try dg.renderPointer(writer, field.parent.*, location);916 try dg.renderPointer(w, field.parent.*, location);
916 try writer.writeAll(")->");917 try w.writeAll(")->");
917 try dg.writeCValue(writer, name);918 try dg.writeCValue(w, name);
918 },919 },
919 .byte_offset => |byte_offset| {920 .byte_offset => |byte_offset| {
920 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);921 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
921 try writer.writeByte('(');922 try w.writeByte('(');
922 try dg.renderCType(writer, ptr_ctype);923 try dg.renderCType(w, ptr_ctype);
923 try writer.writeByte(')');924 try w.writeByte(')');
924 const offset_val = try pt.intValue(.usize, byte_offset);925 const offset_val = try pt.intValue(.usize, byte_offset);
925 try writer.writeAll("((char *)");926 try w.writeAll("((char *)");
926 try dg.renderPointer(writer, field.parent.*, location);927 try dg.renderPointer(w, field.parent.*, location);
927 try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});928 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});
928 },929 },
929 }930 }
930 },931 },
...@@ -932,10 +933,10 @@ pub const DeclGen = struct {...@@ -932,10 +933,10 @@ pub const DeclGen = struct {
932 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {933 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {
933 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.934 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.
934 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);935 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
935 try writer.writeByte('(');936 try w.writeByte('(');
936 try dg.renderCType(writer, ptr_ctype);937 try dg.renderCType(w, ptr_ctype);
937 try writer.writeByte(')');938 try w.writeByte(')');
938 try dg.renderPointer(writer, elem.parent.*, location);939 try dg.renderPointer(w, elem.parent.*, location);
939 } else {940 } else {
940 const index_val = try pt.intValue(.usize, elem.elem_idx);941 const index_val = try pt.intValue(.usize, elem.elem_idx);
941 // We want to do pointer arithmetic on a pointer to the element type.942 // We want to do pointer arithmetic on a pointer to the element type.
...@@ -944,45 +945,45 @@ pub const DeclGen = struct {...@@ -944,45 +945,45 @@ pub const DeclGen = struct {
944 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);945 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);
945 if (result_ctype.eql(parent_ctype)) {946 if (result_ctype.eql(parent_ctype)) {
946 // The pointer already has an appropriate type - just do the arithmetic.947 // The pointer already has an appropriate type - just do the arithmetic.
947 try writer.writeByte('(');948 try w.writeByte('(');
948 try dg.renderPointer(writer, elem.parent.*, location);949 try dg.renderPointer(w, elem.parent.*, location);
949 try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});950 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});
950 } else {951 } else {
951 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,952 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,
952 // and *then* apply the index.953 // and *then* apply the index.
953 try writer.writeAll("((");954 try w.writeAll("((");
954 try dg.renderCType(writer, result_ctype);955 try dg.renderCType(w, result_ctype);
955 try writer.writeByte(')');956 try w.writeByte(')');
956 try dg.renderPointer(writer, elem.parent.*, location);957 try dg.renderPointer(w, elem.parent.*, location);
957 try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});958 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});
958 }959 }
959 },960 },
960961
961 .offset_and_cast => |oac| {962 .offset_and_cast => |oac| {
962 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);963 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);
963 try writer.writeByte('(');964 try w.writeByte('(');
964 try dg.renderCType(writer, ptr_ctype);965 try dg.renderCType(w, ptr_ctype);
965 try writer.writeByte(')');966 try w.writeByte(')');
966 if (oac.byte_offset == 0) {967 if (oac.byte_offset == 0) {
967 try dg.renderPointer(writer, oac.parent.*, location);968 try dg.renderPointer(w, oac.parent.*, location);
968 } else {969 } else {
969 const offset_val = try pt.intValue(.usize, oac.byte_offset);970 const offset_val = try pt.intValue(.usize, oac.byte_offset);
970 try writer.writeAll("((char *)");971 try w.writeAll("((char *)");
971 try dg.renderPointer(writer, oac.parent.*, location);972 try dg.renderPointer(w, oac.parent.*, location);
972 try writer.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});973 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});
973 }974 }
974 },975 },
975 }976 }
976 }977 }
977978
978 fn renderErrorName(dg: *DeclGen, writer: anytype, err_name: InternPool.NullTerminatedString) !void {979 fn renderErrorName(dg: *DeclGen, w: *Writer, err_name: InternPool.NullTerminatedString) !void {
979 const ip = &dg.pt.zcu.intern_pool;980 const ip = &dg.pt.zcu.intern_pool;
980 try writer.print("zig_error_{}", .{fmtIdentUnsolo(err_name.toSlice(ip))});981 try w.print("zig_error_{}", .{fmtIdentUnsolo(err_name.toSlice(ip))});
981 }982 }
982983
983 fn renderValue(984 fn renderValue(
984 dg: *DeclGen,985 dg: *DeclGen,
985 writer: anytype,986 w: *Writer,
986 val: Value,987 val: Value,
987 location: ValueRenderLocation,988 location: ValueRenderLocation,
988 ) error{ OutOfMemory, AnalysisFail }!void {989 ) error{ OutOfMemory, AnalysisFail }!void {
...@@ -998,7 +999,7 @@ pub const DeclGen = struct {...@@ -998,7 +999,7 @@ pub const DeclGen = struct {
998 };999 };
9991000
1000 const ty = val.typeOf(zcu);1001 const ty = val.typeOf(zcu);
1001 if (val.isUndefDeep(zcu)) return dg.renderUndefValue(writer, ty, location);1002 if (val.isUndefDeep(zcu)) return dg.renderUndefValue(w, ty, location);
1002 const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());1003 const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
1003 switch (ip.indexToKey(val.toIntern())) {1004 switch (ip.indexToKey(val.toIntern())) {
1004 // types, not values1005 // types, not values
...@@ -1031,8 +1032,8 @@ pub const DeclGen = struct {...@@ -1031,8 +1032,8 @@ pub const DeclGen = struct {
1031 .empty_tuple => unreachable,1032 .empty_tuple => unreachable,
1032 .@"unreachable" => unreachable,1033 .@"unreachable" => unreachable,
10331034
1034 .false => try writer.writeAll("false"),1035 .false => try w.writeAll("false"),
1035 .true => try writer.writeAll("true"),1036 .true => try w.writeAll("true"),
1036 },1037 },
1037 .variable,1038 .variable,
1038 .@"extern",1039 .@"extern",
...@@ -1041,45 +1042,45 @@ pub const DeclGen = struct {...@@ -1041,45 +1042,45 @@ pub const DeclGen = struct {
1041 .empty_enum_value,1042 .empty_enum_value,
1042 => unreachable, // non-runtime values1043 => unreachable, // non-runtime values
1043 .int => |int| switch (int.storage) {1044 .int => |int| switch (int.storage) {
1044 .u64, .i64, .big_int => try writer.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),1045 .u64, .i64, .big_int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
1045 .lazy_align, .lazy_size => {1046 .lazy_align, .lazy_size => {
1046 try writer.writeAll("((");1047 try w.writeAll("((");
1047 try dg.renderCType(writer, ctype);1048 try dg.renderCType(w, ctype);
1048 try writer.print("){f})", .{try dg.fmtIntLiteralHex(1049 try w.print("){f})", .{try dg.fmtIntLiteralHex(
1049 try pt.intValue(.usize, val.toUnsignedInt(zcu)),1050 try pt.intValue(.usize, val.toUnsignedInt(zcu)),
1050 .Other,1051 .Other,
1051 )});1052 )});
1052 },1053 },
1053 },1054 },
1054 .err => |err| try dg.renderErrorName(writer, err.name),1055 .err => |err| try dg.renderErrorName(w, err.name),
1055 .error_union => |error_union| switch (ctype.info(ctype_pool)) {1056 .error_union => |error_union| switch (ctype.info(ctype_pool)) {
1056 .basic => switch (error_union.val) {1057 .basic => switch (error_union.val) {
1057 .err_name => |err_name| try dg.renderErrorName(writer, err_name),1058 .err_name => |err_name| try dg.renderErrorName(w, err_name),
1058 .payload => try writer.writeAll("0"),1059 .payload => try w.writeAll("0"),
1059 },1060 },
1060 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,1061 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1061 .aggregate => |aggregate| {1062 .aggregate => |aggregate| {
1062 if (!location.isInitializer()) {1063 if (!location.isInitializer()) {
1063 try writer.writeByte('(');1064 try w.writeByte('(');
1064 try dg.renderCType(writer, ctype);1065 try dg.renderCType(w, ctype);
1065 try writer.writeByte(')');1066 try w.writeByte(')');
1066 }1067 }
1067 try writer.writeByte('{');1068 try w.writeByte('{');
1068 for (0..aggregate.fields.len) |field_index| {1069 for (0..aggregate.fields.len) |field_index| {
1069 if (field_index > 0) try writer.writeByte(',');1070 if (field_index > 0) try w.writeByte(',');
1070 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1071 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1071 .@"error" => switch (error_union.val) {1072 .@"error" => switch (error_union.val) {
1072 .err_name => |err_name| try dg.renderErrorName(writer, err_name),1073 .err_name => |err_name| try dg.renderErrorName(w, err_name),
1073 .payload => try writer.writeByte('0'),1074 .payload => try w.writeByte('0'),
1074 },1075 },
1075 .payload => switch (error_union.val) {1076 .payload => switch (error_union.val) {
1076 .err_name => try dg.renderUndefValue(1077 .err_name => try dg.renderUndefValue(
1077 writer,1078 w,
1078 ty.errorUnionPayload(zcu),1079 ty.errorUnionPayload(zcu),
1079 initializer_type,1080 initializer_type,
1080 ),1081 ),
1081 .payload => |payload| try dg.renderValue(1082 .payload => |payload| try dg.renderValue(
1082 writer,1083 w,
1083 Value.fromInterned(payload),1084 Value.fromInterned(payload),
1084 initializer_type,1085 initializer_type,
1085 ),1086 ),
...@@ -1087,10 +1088,10 @@ pub const DeclGen = struct {...@@ -1087,10 +1088,10 @@ pub const DeclGen = struct {
1087 else => unreachable,1088 else => unreachable,
1088 }1089 }
1089 }1090 }
1090 try writer.writeByte('}');1091 try w.writeByte('}');
1091 },1092 },
1092 },1093 },
1093 .enum_tag => |enum_tag| try dg.renderValue(writer, Value.fromInterned(enum_tag.int), location),1094 .enum_tag => |enum_tag| try dg.renderValue(w, Value.fromInterned(enum_tag.int), location),
1094 .float => {1095 .float => {
1095 const bits = ty.floatBits(target);1096 const bits = ty.floatBits(target);
1096 const f128_val = val.toFloat(f128, zcu);1097 const f128_val = val.toFloat(f128, zcu);
...@@ -1117,18 +1118,18 @@ pub const DeclGen = struct {...@@ -1117,18 +1118,18 @@ pub const DeclGen = struct {
11171118
1118 var empty = true;1119 var empty = true;
1119 if (std.math.isFinite(f128_val)) {1120 if (std.math.isFinite(f128_val)) {
1120 try writer.writeAll("zig_make_");1121 try w.writeAll("zig_make_");
1121 try dg.renderTypeForBuiltinFnName(writer, ty);1122 try dg.renderTypeForBuiltinFnName(w, ty);
1122 try writer.writeByte('(');1123 try w.writeByte('(');
1123 switch (bits) {1124 switch (bits) {
1124 16 => try writer.print("{x}", .{val.toFloat(f16, zcu)}),1125 16 => try w.print("{x}", .{val.toFloat(f16, zcu)}),
1125 32 => try writer.print("{x}", .{val.toFloat(f32, zcu)}),1126 32 => try w.print("{x}", .{val.toFloat(f32, zcu)}),
1126 64 => try writer.print("{x}", .{val.toFloat(f64, zcu)}),1127 64 => try w.print("{x}", .{val.toFloat(f64, zcu)}),
1127 80 => try writer.print("{x}", .{val.toFloat(f80, zcu)}),1128 80 => try w.print("{x}", .{val.toFloat(f80, zcu)}),
1128 128 => try writer.print("{x}", .{f128_val}),1129 128 => try w.print("{x}", .{f128_val}),
1129 else => unreachable,1130 else => unreachable,
1130 }1131 }
1131 try writer.writeAll(", ");1132 try w.writeAll(", ");
1132 empty = false;1133 empty = false;
1133 } else {1134 } else {
1134 // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan1135 // isSignalNan is equivalent to isNan currently, and MSVC doesn't have nans, so prefer nan
...@@ -1152,45 +1153,45 @@ pub const DeclGen = struct {...@@ -1152,45 +1153,45 @@ pub const DeclGen = struct {
1152 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});1153 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});
1153 }1154 }
11541155
1155 try writer.writeAll("zig_");1156 try w.writeAll("zig_");
1156 try writer.writeAll(if (location == .StaticInitializer) "init" else "make");1157 try w.writeAll(if (location == .StaticInitializer) "init" else "make");
1157 try writer.writeAll("_special_");1158 try w.writeAll("_special_");
1158 try dg.renderTypeForBuiltinFnName(writer, ty);1159 try dg.renderTypeForBuiltinFnName(w, ty);
1159 try writer.writeByte('(');1160 try w.writeByte('(');
1160 if (std.math.signbit(f128_val)) try writer.writeByte('-');1161 if (std.math.signbit(f128_val)) try w.writeByte('-');
1161 try writer.writeAll(", ");1162 try w.writeAll(", ");
1162 try writer.writeAll(operation);1163 try w.writeAll(operation);
1163 try writer.writeAll(", ");1164 try w.writeAll(", ");
1164 if (std.math.isNan(f128_val)) switch (bits) {1165 if (std.math.isNan(f128_val)) switch (bits) {
1165 // We only actually need to pass the significand, but it will get1166 // We only actually need to pass the significand, but it will get
1166 // properly masked anyway, so just pass the whole value.1167 // properly masked anyway, so just pass the whole value.
1167 16 => try writer.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),1168 16 => try w.print("\"0x{x}\"", .{@as(u16, @bitCast(val.toFloat(f16, zcu)))}),
1168 32 => try writer.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}),1169 32 => try w.print("\"0x{x}\"", .{@as(u32, @bitCast(val.toFloat(f32, zcu)))}),
1169 64 => try writer.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),1170 64 => try w.print("\"0x{x}\"", .{@as(u64, @bitCast(val.toFloat(f64, zcu)))}),
1170 80 => try writer.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),1171 80 => try w.print("\"0x{x}\"", .{@as(u80, @bitCast(val.toFloat(f80, zcu)))}),
1171 128 => try writer.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),1172 128 => try w.print("\"0x{x}\"", .{@as(u128, @bitCast(f128_val))}),
1172 else => unreachable,1173 else => unreachable,
1173 };1174 };
1174 try writer.writeAll(", ");1175 try w.writeAll(", ");
1175 empty = false;1176 empty = false;
1176 }1177 }
1177 try writer.print("{f}", .{try dg.fmtIntLiteralHex(1178 try w.print("{f}", .{try dg.fmtIntLiteralHex(
1178 try pt.intValue_big(repr_ty, repr_val_big.toConst()),1179 try pt.intValue_big(repr_ty, repr_val_big.toConst()),
1179 location,1180 location,
1180 )});1181 )});
1181 if (!empty) try writer.writeByte(')');1182 if (!empty) try w.writeByte(')');
1182 },1183 },
1183 .slice => |slice| {1184 .slice => |slice| {
1184 const aggregate = ctype.info(ctype_pool).aggregate;1185 const aggregate = ctype.info(ctype_pool).aggregate;
1185 if (!location.isInitializer()) {1186 if (!location.isInitializer()) {
1186 try writer.writeByte('(');1187 try w.writeByte('(');
1187 try dg.renderCType(writer, ctype);1188 try dg.renderCType(w, ctype);
1188 try writer.writeByte(')');1189 try w.writeByte(')');
1189 }1190 }
1190 try writer.writeByte('{');1191 try w.writeByte('{');
1191 for (0..aggregate.fields.len) |field_index| {1192 for (0..aggregate.fields.len) |field_index| {
1192 if (field_index > 0) try writer.writeByte(',');1193 if (field_index > 0) try w.writeByte(',');
1193 try dg.renderValue(writer, Value.fromInterned(1194 try dg.renderValue(w, Value.fromInterned(
1194 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1195 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1195 .ptr => slice.ptr,1196 .ptr => slice.ptr,
1196 .len => slice.len,1197 .len => slice.len,
...@@ -1198,33 +1199,33 @@ pub const DeclGen = struct {...@@ -1198,33 +1199,33 @@ pub const DeclGen = struct {
1198 },1199 },
1199 ), initializer_type);1200 ), initializer_type);
1200 }1201 }
1201 try writer.writeByte('}');1202 try w.writeByte('}');
1202 },1203 },
1203 .ptr => {1204 .ptr => {
1204 var arena = std.heap.ArenaAllocator.init(zcu.gpa);1205 var arena = std.heap.ArenaAllocator.init(zcu.gpa);
1205 defer arena.deinit();1206 defer arena.deinit();
1206 const derivation = try val.pointerDerivation(arena.allocator(), pt);1207 const derivation = try val.pointerDerivation(arena.allocator(), pt);
1207 try dg.renderPointer(writer, derivation, location);1208 try dg.renderPointer(w, derivation, location);
1208 },1209 },
1209 .opt => |opt| switch (ctype.info(ctype_pool)) {1210 .opt => |opt| switch (ctype.info(ctype_pool)) {
1210 .basic => if (ctype.isBool()) try writer.writeAll(switch (opt.val) {1211 .basic => if (ctype.isBool()) try w.writeAll(switch (opt.val) {
1211 .none => "true",1212 .none => "true",
1212 else => "false",1213 else => "false",
1213 }) else switch (opt.val) {1214 }) else switch (opt.val) {
1214 .none => try writer.writeAll("0"),1215 .none => try w.writeAll("0"),
1215 else => |payload| switch (ip.indexToKey(payload)) {1216 else => |payload| switch (ip.indexToKey(payload)) {
1216 .undef => |err_ty| try dg.renderUndefValue(1217 .undef => |err_ty| try dg.renderUndefValue(
1217 writer,1218 w,
1218 .fromInterned(err_ty),1219 .fromInterned(err_ty),
1219 location,1220 location,
1220 ),1221 ),
1221 .err => |err| try dg.renderErrorName(writer, err.name),1222 .err => |err| try dg.renderErrorName(w, err.name),
1222 else => unreachable,1223 else => unreachable,
1223 },1224 },
1224 },1225 },
1225 .pointer => switch (opt.val) {1226 .pointer => switch (opt.val) {
1226 .none => try writer.writeAll("NULL"),1227 .none => try w.writeAll("NULL"),
1227 else => |payload| try dg.renderValue(writer, Value.fromInterned(payload), location),1228 else => |payload| try dg.renderValue(w, Value.fromInterned(payload), location),
1228 },1229 },
1229 .aligned, .array, .vector, .fwd_decl, .function => unreachable,1230 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1230 .aggregate => |aggregate| {1231 .aggregate => |aggregate| {
...@@ -1233,7 +1234,7 @@ pub const DeclGen = struct {...@@ -1233,7 +1234,7 @@ pub const DeclGen = struct {
1233 else => |payload| switch (aggregate.fields.at(0, ctype_pool).name.index) {1234 else => |payload| switch (aggregate.fields.at(0, ctype_pool).name.index) {
1234 .is_null, .payload => {},1235 .is_null, .payload => {},
1235 .ptr, .len => return dg.renderValue(1236 .ptr, .len => return dg.renderValue(
1236 writer,1237 w,
1237 Value.fromInterned(payload),1238 Value.fromInterned(payload),
1238 location,1239 location,
1239 ),1240 ),
...@@ -1241,48 +1242,48 @@ pub const DeclGen = struct {...@@ -1241,48 +1242,48 @@ pub const DeclGen = struct {
1241 },1242 },
1242 }1243 }
1243 if (!location.isInitializer()) {1244 if (!location.isInitializer()) {
1244 try writer.writeByte('(');1245 try w.writeByte('(');
1245 try dg.renderCType(writer, ctype);1246 try dg.renderCType(w, ctype);
1246 try writer.writeByte(')');1247 try w.writeByte(')');
1247 }1248 }
1248 try writer.writeByte('{');1249 try w.writeByte('{');
1249 for (0..aggregate.fields.len) |field_index| {1250 for (0..aggregate.fields.len) |field_index| {
1250 if (field_index > 0) try writer.writeByte(',');1251 if (field_index > 0) try w.writeByte(',');
1251 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1252 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1252 .is_null => try writer.writeAll(switch (opt.val) {1253 .is_null => try w.writeAll(switch (opt.val) {
1253 .none => "true",1254 .none => "true",
1254 else => "false",1255 else => "false",
1255 }),1256 }),
1256 .payload => switch (opt.val) {1257 .payload => switch (opt.val) {
1257 .none => try dg.renderUndefValue(1258 .none => try dg.renderUndefValue(
1258 writer,1259 w,
1259 ty.optionalChild(zcu),1260 ty.optionalChild(zcu),
1260 initializer_type,1261 initializer_type,
1261 ),1262 ),
1262 else => |payload| try dg.renderValue(1263 else => |payload| try dg.renderValue(
1263 writer,1264 w,
1264 Value.fromInterned(payload),1265 Value.fromInterned(payload),
1265 initializer_type,1266 initializer_type,
1266 ),1267 ),
1267 },1268 },
1268 .ptr => try writer.writeAll("NULL"),1269 .ptr => try w.writeAll("NULL"),
1269 .len => try dg.renderUndefValue(writer, .usize, initializer_type),1270 .len => try dg.renderUndefValue(w, .usize, initializer_type),
1270 else => unreachable,1271 else => unreachable,
1271 }1272 }
1272 }1273 }
1273 try writer.writeByte('}');1274 try w.writeByte('}');
1274 },1275 },
1275 },1276 },
1276 .aggregate => switch (ip.indexToKey(ty.toIntern())) {1277 .aggregate => switch (ip.indexToKey(ty.toIntern())) {
1277 .array_type, .vector_type => {1278 .array_type, .vector_type => {
1278 if (location == .FunctionArgument) {1279 if (location == .FunctionArgument) {
1279 try writer.writeByte('(');1280 try w.writeByte('(');
1280 try dg.renderCType(writer, ctype);1281 try dg.renderCType(w, ctype);
1281 try writer.writeByte(')');1282 try w.writeByte(')');
1282 }1283 }
1283 const ai = ty.arrayInfo(zcu);1284 const ai = ty.arrayInfo(zcu);
1284 if (ai.elem_type.eql(.u8, zcu)) {1285 if (ai.elem_type.eql(.u8, zcu)) {
1285 var literal: StringLiteral = .init(writer, ty.arrayLenIncludingSentinel(zcu));1286 var literal: StringLiteral = .init(w, ty.arrayLenIncludingSentinel(zcu));
1286 try literal.start();1287 try literal.start();
1287 var index: usize = 0;1288 var index: usize = 0;
1288 while (index < ai.len) : (index += 1) {1289 while (index < ai.len) : (index += 1) {
...@@ -1299,28 +1300,28 @@ pub const DeclGen = struct {...@@ -1299,28 +1300,28 @@ pub const DeclGen = struct {
1299 }1300 }
1300 try literal.end();1301 try literal.end();
1301 } else {1302 } else {
1302 try writer.writeByte('{');1303 try w.writeByte('{');
1303 var index: usize = 0;1304 var index: usize = 0;
1304 while (index < ai.len) : (index += 1) {1305 while (index < ai.len) : (index += 1) {
1305 if (index != 0) try writer.writeByte(',');1306 if (index != 0) try w.writeByte(',');
1306 const elem_val = try val.elemValue(pt, index);1307 const elem_val = try val.elemValue(pt, index);
1307 try dg.renderValue(writer, elem_val, initializer_type);1308 try dg.renderValue(w, elem_val, initializer_type);
1308 }1309 }
1309 if (ai.sentinel) |s| {1310 if (ai.sentinel) |s| {
1310 if (index != 0) try writer.writeByte(',');1311 if (index != 0) try w.writeByte(',');
1311 try dg.renderValue(writer, s, initializer_type);1312 try dg.renderValue(w, s, initializer_type);
1312 }1313 }
1313 try writer.writeByte('}');1314 try w.writeByte('}');
1314 }1315 }
1315 },1316 },
1316 .tuple_type => |tuple| {1317 .tuple_type => |tuple| {
1317 if (!location.isInitializer()) {1318 if (!location.isInitializer()) {
1318 try writer.writeByte('(');1319 try w.writeByte('(');
1319 try dg.renderCType(writer, ctype);1320 try dg.renderCType(w, ctype);
1320 try writer.writeByte(')');1321 try w.writeByte(')');
1321 }1322 }
13221323
1323 try writer.writeByte('{');1324 try w.writeByte('{');
1324 var empty = true;1325 var empty = true;
1325 for (0..tuple.types.len) |field_index| {1326 for (0..tuple.types.len) |field_index| {
1326 const comptime_val = tuple.values.get(ip)[field_index];1327 const comptime_val = tuple.values.get(ip)[field_index];
...@@ -1328,7 +1329,7 @@ pub const DeclGen = struct {...@@ -1328,7 +1329,7 @@ pub const DeclGen = struct {
1328 const field_ty: Type = .fromInterned(tuple.types.get(ip)[field_index]);1329 const field_ty: Type = .fromInterned(tuple.types.get(ip)[field_index]);
1329 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1330 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
13301331
1331 if (!empty) try writer.writeByte(',');1332 if (!empty) try w.writeByte(',');
13321333
1333 const field_val = Value.fromInterned(1334 const field_val = Value.fromInterned(
1334 switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1335 switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
...@@ -1340,30 +1341,30 @@ pub const DeclGen = struct {...@@ -1340,30 +1341,30 @@ pub const DeclGen = struct {
1340 .repeated_elem => |elem| elem,1341 .repeated_elem => |elem| elem,
1341 },1342 },
1342 );1343 );
1343 try dg.renderValue(writer, field_val, initializer_type);1344 try dg.renderValue(w, field_val, initializer_type);
13441345
1345 empty = false;1346 empty = false;
1346 }1347 }
1347 try writer.writeByte('}');1348 try w.writeByte('}');
1348 },1349 },
1349 .struct_type => {1350 .struct_type => {
1350 const loaded_struct = ip.loadStructType(ty.toIntern());1351 const loaded_struct = ip.loadStructType(ty.toIntern());
1351 switch (loaded_struct.layout) {1352 switch (loaded_struct.layout) {
1352 .auto, .@"extern" => {1353 .auto, .@"extern" => {
1353 if (!location.isInitializer()) {1354 if (!location.isInitializer()) {
1354 try writer.writeByte('(');1355 try w.writeByte('(');
1355 try dg.renderCType(writer, ctype);1356 try dg.renderCType(w, ctype);
1356 try writer.writeByte(')');1357 try w.writeByte(')');
1357 }1358 }
13581359
1359 try writer.writeByte('{');1360 try w.writeByte('{');
1360 var field_it = loaded_struct.iterateRuntimeOrder(ip);1361 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1361 var need_comma = false;1362 var need_comma = false;
1362 while (field_it.next()) |field_index| {1363 while (field_it.next()) |field_index| {
1363 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1364 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1364 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1365 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
13651366
1366 if (need_comma) try writer.writeByte(',');1367 if (need_comma) try w.writeByte(',');
1367 need_comma = true;1368 need_comma = true;
1368 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1369 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1369 .bytes => |bytes| try pt.intern(.{ .int = .{1370 .bytes => |bytes| try pt.intern(.{ .int = .{
...@@ -1373,9 +1374,9 @@ pub const DeclGen = struct {...@@ -1373,9 +1374,9 @@ pub const DeclGen = struct {
1373 .elems => |elems| elems[field_index],1374 .elems => |elems| elems[field_index],
1374 .repeated_elem => |elem| elem,1375 .repeated_elem => |elem| elem,
1375 };1376 };
1376 try dg.renderValue(writer, Value.fromInterned(field_val), initializer_type);1377 try dg.renderValue(w, Value.fromInterned(field_val), initializer_type);
1377 }1378 }
1378 try writer.writeByte('}');1379 try w.writeByte('}');
1379 },1380 },
1380 .@"packed" => {1381 .@"packed" => {
1381 const int_info = ty.intInfo(zcu);1382 const int_info = ty.intInfo(zcu);
...@@ -1393,16 +1394,16 @@ pub const DeclGen = struct {...@@ -1393,16 +1394,16 @@ pub const DeclGen = struct {
1393 }1394 }
13941395
1395 if (eff_num_fields == 0) {1396 if (eff_num_fields == 0) {
1396 try writer.writeByte('(');1397 try w.writeByte('(');
1397 try dg.renderUndefValue(writer, ty, location);1398 try dg.renderUndefValue(w, ty, location);
1398 try writer.writeByte(')');1399 try w.writeByte(')');
1399 } else if (ty.bitSize(zcu) > 64) {1400 } else if (ty.bitSize(zcu) > 64) {
1400 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))1401 // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
1401 var num_or = eff_num_fields - 1;1402 var num_or = eff_num_fields - 1;
1402 while (num_or > 0) : (num_or -= 1) {1403 while (num_or > 0) : (num_or -= 1) {
1403 try writer.writeAll("zig_or_");1404 try w.writeAll("zig_or_");
1404 try dg.renderTypeForBuiltinFnName(writer, ty);1405 try dg.renderTypeForBuiltinFnName(w, ty);
1405 try writer.writeByte('(');1406 try w.writeByte('(');
1406 }1407 }
14071408
1408 var eff_index: usize = 0;1409 var eff_index: usize = 0;
...@@ -1421,36 +1422,36 @@ pub const DeclGen = struct {...@@ -1421,36 +1422,36 @@ pub const DeclGen = struct {
1421 };1422 };
1422 const cast_context = IntCastContext{ .value = .{ .value = Value.fromInterned(field_val) } };1423 const cast_context = IntCastContext{ .value = .{ .value = Value.fromInterned(field_val) } };
1423 if (bit_offset != 0) {1424 if (bit_offset != 0) {
1424 try writer.writeAll("zig_shl_");1425 try w.writeAll("zig_shl_");
1425 try dg.renderTypeForBuiltinFnName(writer, ty);1426 try dg.renderTypeForBuiltinFnName(w, ty);
1426 try writer.writeByte('(');1427 try w.writeByte('(');
1427 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);1428 try dg.renderIntCast(w, ty, cast_context, field_ty, .FunctionArgument);
1428 try writer.writeAll(", ");1429 try w.writeAll(", ");
1429 try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);1430 try dg.renderValue(w, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
1430 try writer.writeByte(')');1431 try w.writeByte(')');
1431 } else {1432 } else {
1432 try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);1433 try dg.renderIntCast(w, ty, cast_context, field_ty, .FunctionArgument);
1433 }1434 }
14341435
1435 if (needs_closing_paren) try writer.writeByte(')');1436 if (needs_closing_paren) try w.writeByte(')');
1436 if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");1437 if (eff_index != eff_num_fields - 1) try w.writeAll(", ");
14371438
1438 bit_offset += field_ty.bitSize(zcu);1439 bit_offset += field_ty.bitSize(zcu);
1439 needs_closing_paren = true;1440 needs_closing_paren = true;
1440 eff_index += 1;1441 eff_index += 1;
1441 }1442 }
1442 } else {1443 } else {
1443 try writer.writeByte('(');1444 try w.writeByte('(');
1444 // a << a_off | b << b_off | c << c_off1445 // a << a_off | b << b_off | c << c_off
1445 var empty = true;1446 var empty = true;
1446 for (0..loaded_struct.field_types.len) |field_index| {1447 for (0..loaded_struct.field_types.len) |field_index| {
1447 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1448 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1448 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1449 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
14491450
1450 if (!empty) try writer.writeAll(" | ");1451 if (!empty) try w.writeAll(" | ");
1451 try writer.writeByte('(');1452 try w.writeByte('(');
1452 try dg.renderCType(writer, ctype);1453 try dg.renderCType(w, ctype);
1453 try writer.writeByte(')');1454 try w.writeByte(')');
14541455
1455 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {1456 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1456 .bytes => |bytes| try pt.intern(.{ .int = .{1457 .bytes => |bytes| try pt.intern(.{ .int = .{
...@@ -1467,24 +1468,24 @@ pub const DeclGen = struct {...@@ -1467,24 +1468,24 @@ pub const DeclGen = struct {
1467 .{ .signedness = .unsigned, .bits = undefined };1468 .{ .signedness = .unsigned, .bits = undefined };
1468 switch (field_int_info.signedness) {1469 switch (field_int_info.signedness) {
1469 .signed => {1470 .signed => {
1470 try writer.writeByte('(');1471 try w.writeByte('(');
1471 try dg.renderValue(writer, Value.fromInterned(field_val), .Other);1472 try dg.renderValue(w, Value.fromInterned(field_val), .Other);
1472 try writer.writeAll(" & ");1473 try w.writeAll(" & ");
1473 const field_uint_ty = try pt.intType(.unsigned, field_int_info.bits);1474 const field_uint_ty = try pt.intType(.unsigned, field_int_info.bits);
1474 try dg.renderValue(writer, try field_uint_ty.maxIntScalar(pt, field_uint_ty), .Other);1475 try dg.renderValue(w, try field_uint_ty.maxIntScalar(pt, field_uint_ty), .Other);
1475 try writer.writeByte(')');1476 try w.writeByte(')');
1476 },1477 },
1477 .unsigned => try dg.renderValue(writer, Value.fromInterned(field_val), .Other),1478 .unsigned => try dg.renderValue(w, Value.fromInterned(field_val), .Other),
1478 }1479 }
1479 if (bit_offset != 0) {1480 if (bit_offset != 0) {
1480 try writer.writeAll(" << ");1481 try w.writeAll(" << ");
1481 try dg.renderValue(writer, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);1482 try dg.renderValue(w, try pt.intValue(bit_offset_ty, bit_offset), .FunctionArgument);
1482 }1483 }
14831484
1484 bit_offset += field_ty.bitSize(zcu);1485 bit_offset += field_ty.bitSize(zcu);
1485 empty = false;1486 empty = false;
1486 }1487 }
1487 try writer.writeByte(')');1488 try w.writeByte(')');
1488 }1489 }
1489 },1490 },
1490 }1491 }
...@@ -1498,11 +1499,11 @@ pub const DeclGen = struct {...@@ -1498,11 +1499,11 @@ pub const DeclGen = struct {
1498 switch (loaded_union.flagsUnordered(ip).layout) {1499 switch (loaded_union.flagsUnordered(ip).layout) {
1499 .@"packed" => {1500 .@"packed" => {
1500 if (!location.isInitializer()) {1501 if (!location.isInitializer()) {
1501 try writer.writeByte('(');1502 try w.writeByte('(');
1502 try dg.renderType(writer, backing_ty);1503 try dg.renderType(w, backing_ty);
1503 try writer.writeByte(')');1504 try w.writeByte(')');
1504 }1505 }
1505 try dg.renderValue(writer, Value.fromInterned(un.val), location);1506 try dg.renderValue(w, Value.fromInterned(un.val), location);
1506 },1507 },
1507 .@"extern" => {1508 .@"extern" => {
1508 if (location == .StaticInitializer) {1509 if (location == .StaticInitializer) {
...@@ -1510,21 +1511,21 @@ pub const DeclGen = struct {...@@ -1510,21 +1511,21 @@ pub const DeclGen = struct {
1510 }1511 }
15111512
1512 const ptr_ty = try pt.singleConstPtrType(ty);1513 const ptr_ty = try pt.singleConstPtrType(ty);
1513 try writer.writeAll("*((");1514 try w.writeAll("*((");
1514 try dg.renderType(writer, ptr_ty);1515 try dg.renderType(w, ptr_ty);
1515 try writer.writeAll(")(");1516 try w.writeAll(")(");
1516 try dg.renderType(writer, backing_ty);1517 try dg.renderType(w, backing_ty);
1517 try writer.writeAll("){");1518 try w.writeAll("){");
1518 try dg.renderValue(writer, Value.fromInterned(un.val), location);1519 try dg.renderValue(w, Value.fromInterned(un.val), location);
1519 try writer.writeAll("})");1520 try w.writeAll("})");
1520 },1521 },
1521 else => unreachable,1522 else => unreachable,
1522 }1523 }
1523 } else {1524 } else {
1524 if (!location.isInitializer()) {1525 if (!location.isInitializer()) {
1525 try writer.writeByte('(');1526 try w.writeByte('(');
1526 try dg.renderCType(writer, ctype);1527 try dg.renderCType(w, ctype);
1527 try writer.writeByte(')');1528 try w.writeByte(')');
1528 }1529 }
15291530
1530 const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;1531 const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;
...@@ -1533,57 +1534,57 @@ pub const DeclGen = struct {...@@ -1533,57 +1534,57 @@ pub const DeclGen = struct {
1533 if (loaded_union.flagsUnordered(ip).layout == .@"packed") {1534 if (loaded_union.flagsUnordered(ip).layout == .@"packed") {
1534 if (field_ty.hasRuntimeBits(zcu)) {1535 if (field_ty.hasRuntimeBits(zcu)) {
1535 if (field_ty.isPtrAtRuntime(zcu)) {1536 if (field_ty.isPtrAtRuntime(zcu)) {
1536 try writer.writeByte('(');1537 try w.writeByte('(');
1537 try dg.renderCType(writer, ctype);1538 try dg.renderCType(w, ctype);
1538 try writer.writeByte(')');1539 try w.writeByte(')');
1539 } else if (field_ty.zigTypeTag(zcu) == .float) {1540 } else if (field_ty.zigTypeTag(zcu) == .float) {
1540 try writer.writeByte('(');1541 try w.writeByte('(');
1541 try dg.renderCType(writer, ctype);1542 try dg.renderCType(w, ctype);
1542 try writer.writeByte(')');1543 try w.writeByte(')');
1543 }1544 }
1544 try dg.renderValue(writer, Value.fromInterned(un.val), location);1545 try dg.renderValue(w, Value.fromInterned(un.val), location);
1545 } else try writer.writeAll("0");1546 } else try w.writeAll("0");
1546 return;1547 return;
1547 }1548 }
15481549
1549 const has_tag = loaded_union.hasTag(ip);1550 const has_tag = loaded_union.hasTag(ip);
1550 if (has_tag) try writer.writeByte('{');1551 if (has_tag) try w.writeByte('{');
1551 const aggregate = ctype.info(ctype_pool).aggregate;1552 const aggregate = ctype.info(ctype_pool).aggregate;
1552 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {1553 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
1553 if (outer_field_index > 0) try writer.writeByte(',');1554 if (outer_field_index > 0) try w.writeByte(',');
1554 switch (if (has_tag)1555 switch (if (has_tag)
1555 aggregate.fields.at(outer_field_index, ctype_pool).name.index1556 aggregate.fields.at(outer_field_index, ctype_pool).name.index
1556 else1557 else
1557 .payload) {1558 .payload) {
1558 .tag => try dg.renderValue(1559 .tag => try dg.renderValue(
1559 writer,1560 w,
1560 Value.fromInterned(un.tag),1561 Value.fromInterned(un.tag),
1561 initializer_type,1562 initializer_type,
1562 ),1563 ),
1563 .payload => {1564 .payload => {
1564 try writer.writeByte('{');1565 try w.writeByte('{');
1565 if (field_ty.hasRuntimeBits(zcu)) {1566 if (field_ty.hasRuntimeBits(zcu)) {
1566 try writer.print(" .{f} = ", .{fmtIdentSolo(field_name.toSlice(ip))});1567 try w.print(" .{f} = ", .{fmtIdentSolo(field_name.toSlice(ip))});
1567 try dg.renderValue(1568 try dg.renderValue(
1568 writer,1569 w,
1569 Value.fromInterned(un.val),1570 Value.fromInterned(un.val),
1570 initializer_type,1571 initializer_type,
1571 );1572 );
1572 try writer.writeByte(' ');1573 try w.writeByte(' ');
1573 } else for (0..loaded_union.field_types.len) |inner_field_index| {1574 } else for (0..loaded_union.field_types.len) |inner_field_index| {
1574 const inner_field_ty: Type = .fromInterned(1575 const inner_field_ty: Type = .fromInterned(
1575 loaded_union.field_types.get(ip)[inner_field_index],1576 loaded_union.field_types.get(ip)[inner_field_index],
1576 );1577 );
1577 if (!inner_field_ty.hasRuntimeBits(zcu)) continue;1578 if (!inner_field_ty.hasRuntimeBits(zcu)) continue;
1578 try dg.renderUndefValue(writer, inner_field_ty, initializer_type);1579 try dg.renderUndefValue(w, inner_field_ty, initializer_type);
1579 break;1580 break;
1580 }1581 }
1581 try writer.writeByte('}');1582 try w.writeByte('}');
1582 },1583 },
1583 else => unreachable,1584 else => unreachable,
1584 }1585 }
1585 }1586 }
1586 if (has_tag) try writer.writeByte('}');1587 if (has_tag) try w.writeByte('}');
1587 }1588 }
1588 },1589 },
1589 }1590 }
...@@ -1591,7 +1592,7 @@ pub const DeclGen = struct {...@@ -1591,7 +1592,7 @@ pub const DeclGen = struct {
15911592
1592 fn renderUndefValue(1593 fn renderUndefValue(
1593 dg: *DeclGen,1594 dg: *DeclGen,
1594 writer: anytype,1595 w: *Writer,
1595 ty: Type,1596 ty: Type,
1596 location: ValueRenderLocation,1597 location: ValueRenderLocation,
1597 ) error{ OutOfMemory, AnalysisFail }!void {1598 ) error{ OutOfMemory, AnalysisFail }!void {
...@@ -1624,57 +1625,57 @@ pub const DeclGen = struct {...@@ -1624,57 +1625,57 @@ pub const DeclGen = struct {
1624 // All unsigned ints matching float types are pre-allocated.1625 // All unsigned ints matching float types are pre-allocated.
1625 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;1626 const repr_ty = dg.pt.intType(.unsigned, bits) catch unreachable;
16261627
1627 try writer.writeAll("zig_make_");1628 try w.writeAll("zig_make_");
1628 try dg.renderTypeForBuiltinFnName(writer, ty);1629 try dg.renderTypeForBuiltinFnName(w, ty);
1629 try writer.writeByte('(');1630 try w.writeByte('(');
1630 switch (bits) {1631 switch (bits) {
1631 16 => try writer.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),1632 16 => try w.print("{x}", .{@as(f16, @bitCast(undefPattern(i16)))}),
1632 32 => try writer.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),1633 32 => try w.print("{x}", .{@as(f32, @bitCast(undefPattern(i32)))}),
1633 64 => try writer.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),1634 64 => try w.print("{x}", .{@as(f64, @bitCast(undefPattern(i64)))}),
1634 80 => try writer.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),1635 80 => try w.print("{x}", .{@as(f80, @bitCast(undefPattern(i80)))}),
1635 128 => try writer.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),1636 128 => try w.print("{x}", .{@as(f128, @bitCast(undefPattern(i128)))}),
1636 else => unreachable,1637 else => unreachable,
1637 }1638 }
1638 try writer.writeAll(", ");1639 try w.writeAll(", ");
1639 try dg.renderUndefValue(writer, repr_ty, .FunctionArgument);1640 try dg.renderUndefValue(w, repr_ty, .FunctionArgument);
1640 return writer.writeByte(')');1641 return w.writeByte(')');
1641 },1642 },
1642 .bool_type => try writer.writeAll(if (safety_on) "0xaa" else "false"),1643 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),
1643 else => switch (ip.indexToKey(ty.toIntern())) {1644 else => switch (ip.indexToKey(ty.toIntern())) {
1644 .simple_type,1645 .simple_type,
1645 .int_type,1646 .int_type,
1646 .enum_type,1647 .enum_type,
1647 .error_set_type,1648 .error_set_type,
1648 .inferred_error_set_type,1649 .inferred_error_set_type,
1649 => return writer.print("{f}", .{1650 => return w.print("{f}", .{
1650 try dg.fmtIntLiteralHex(try pt.undefValue(ty), location),1651 try dg.fmtIntLiteralHex(try pt.undefValue(ty), location),
1651 }),1652 }),
1652 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {1653 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1653 .one, .many, .c => {1654 .one, .many, .c => {
1654 try writer.writeAll("((");1655 try w.writeAll("((");
1655 try dg.renderCType(writer, ctype);1656 try dg.renderCType(w, ctype);
1656 return writer.print("){f})", .{1657 return w.print("){f})", .{
1657 try dg.fmtIntLiteralHex(.undef_usize, .Other),1658 try dg.fmtIntLiteralHex(.undef_usize, .Other),
1658 });1659 });
1659 },1660 },
1660 .slice => {1661 .slice => {
1661 if (!location.isInitializer()) {1662 if (!location.isInitializer()) {
1662 try writer.writeByte('(');1663 try w.writeByte('(');
1663 try dg.renderCType(writer, ctype);1664 try dg.renderCType(w, ctype);
1664 try writer.writeByte(')');1665 try w.writeByte(')');
1665 }1666 }
16661667
1667 try writer.writeAll("{(");1668 try w.writeAll("{(");
1668 const ptr_ty = ty.slicePtrFieldType(zcu);1669 const ptr_ty = ty.slicePtrFieldType(zcu);
1669 try dg.renderType(writer, ptr_ty);1670 try dg.renderType(w, ptr_ty);
1670 return writer.print("){f}, {0fx}}}", .{1671 return w.print("){f}, {0fx}}}", .{
1671 try dg.fmtIntLiteralHex(.undef_usize, .Other),1672 try dg.fmtIntLiteralHex(.undef_usize, .Other),
1672 });1673 });
1673 },1674 },
1674 },1675 },
1675 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {1676 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {
1676 .basic, .pointer => try dg.renderUndefValue(1677 .basic, .pointer => try dg.renderUndefValue(
1677 writer,1678 w,
1678 .fromInterned(if (ctype.isBool()) .bool_type else child_type),1679 .fromInterned(if (ctype.isBool()) .bool_type else child_type),
1679 location,1680 location,
1680 ),1681 ),
...@@ -1683,21 +1684,21 @@ pub const DeclGen = struct {...@@ -1683,21 +1684,21 @@ pub const DeclGen = struct {
1683 switch (aggregate.fields.at(0, ctype_pool).name.index) {1684 switch (aggregate.fields.at(0, ctype_pool).name.index) {
1684 .is_null, .payload => {},1685 .is_null, .payload => {},
1685 .ptr, .len => return dg.renderUndefValue(1686 .ptr, .len => return dg.renderUndefValue(
1686 writer,1687 w,
1687 .fromInterned(child_type),1688 .fromInterned(child_type),
1688 location,1689 location,
1689 ),1690 ),
1690 else => unreachable,1691 else => unreachable,
1691 }1692 }
1692 if (!location.isInitializer()) {1693 if (!location.isInitializer()) {
1693 try writer.writeByte('(');1694 try w.writeByte('(');
1694 try dg.renderCType(writer, ctype);1695 try dg.renderCType(w, ctype);
1695 try writer.writeByte(')');1696 try w.writeByte(')');
1696 }1697 }
1697 try writer.writeByte('{');1698 try w.writeByte('{');
1698 for (0..aggregate.fields.len) |field_index| {1699 for (0..aggregate.fields.len) |field_index| {
1699 if (field_index > 0) try writer.writeByte(',');1700 if (field_index > 0) try w.writeByte(',');
1700 try dg.renderUndefValue(writer, .fromInterned(1701 try dg.renderUndefValue(w, .fromInterned(
1701 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1702 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1702 .is_null => .bool_type,1703 .is_null => .bool_type,
1703 .payload => child_type,1704 .payload => child_type,
...@@ -1705,7 +1706,7 @@ pub const DeclGen = struct {...@@ -1705,7 +1706,7 @@ pub const DeclGen = struct {
1705 },1706 },
1706 ), initializer_type);1707 ), initializer_type);
1707 }1708 }
1708 try writer.writeByte('}');1709 try w.writeByte('}');
1709 },1710 },
1710 },1711 },
1711 .struct_type => {1712 .struct_type => {
...@@ -1713,117 +1714,117 @@ pub const DeclGen = struct {...@@ -1713,117 +1714,117 @@ pub const DeclGen = struct {
1713 switch (loaded_struct.layout) {1714 switch (loaded_struct.layout) {
1714 .auto, .@"extern" => {1715 .auto, .@"extern" => {
1715 if (!location.isInitializer()) {1716 if (!location.isInitializer()) {
1716 try writer.writeByte('(');1717 try w.writeByte('(');
1717 try dg.renderCType(writer, ctype);1718 try dg.renderCType(w, ctype);
1718 try writer.writeByte(')');1719 try w.writeByte(')');
1719 }1720 }
17201721
1721 try writer.writeByte('{');1722 try w.writeByte('{');
1722 var field_it = loaded_struct.iterateRuntimeOrder(ip);1723 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1723 var need_comma = false;1724 var need_comma = false;
1724 while (field_it.next()) |field_index| {1725 while (field_it.next()) |field_index| {
1725 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);1726 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1726 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1727 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17271728
1728 if (need_comma) try writer.writeByte(',');1729 if (need_comma) try w.writeByte(',');
1729 need_comma = true;1730 need_comma = true;
1730 try dg.renderUndefValue(writer, field_ty, initializer_type);1731 try dg.renderUndefValue(w, field_ty, initializer_type);
1731 }1732 }
1732 return writer.writeByte('}');1733 return w.writeByte('}');
1733 },1734 },
1734 .@"packed" => return writer.print("{f}", .{1735 .@"packed" => return w.print("{f}", .{
1735 try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other),1736 try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other),
1736 }),1737 }),
1737 }1738 }
1738 },1739 },
1739 .tuple_type => |tuple_info| {1740 .tuple_type => |tuple_info| {
1740 if (!location.isInitializer()) {1741 if (!location.isInitializer()) {
1741 try writer.writeByte('(');1742 try w.writeByte('(');
1742 try dg.renderCType(writer, ctype);1743 try dg.renderCType(w, ctype);
1743 try writer.writeByte(')');1744 try w.writeByte(')');
1744 }1745 }
17451746
1746 try writer.writeByte('{');1747 try w.writeByte('{');
1747 var need_comma = false;1748 var need_comma = false;
1748 for (0..tuple_info.types.len) |field_index| {1749 for (0..tuple_info.types.len) |field_index| {
1749 if (tuple_info.values.get(ip)[field_index] != .none) continue;1750 if (tuple_info.values.get(ip)[field_index] != .none) continue;
1750 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);1751 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
1751 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;1752 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
17521753
1753 if (need_comma) try writer.writeByte(',');1754 if (need_comma) try w.writeByte(',');
1754 need_comma = true;1755 need_comma = true;
1755 try dg.renderUndefValue(writer, field_ty, initializer_type);1756 try dg.renderUndefValue(w, field_ty, initializer_type);
1756 }1757 }
1757 return writer.writeByte('}');1758 return w.writeByte('}');
1758 },1759 },
1759 .union_type => {1760 .union_type => {
1760 const loaded_union = ip.loadUnionType(ty.toIntern());1761 const loaded_union = ip.loadUnionType(ty.toIntern());
1761 switch (loaded_union.flagsUnordered(ip).layout) {1762 switch (loaded_union.flagsUnordered(ip).layout) {
1762 .auto, .@"extern" => {1763 .auto, .@"extern" => {
1763 if (!location.isInitializer()) {1764 if (!location.isInitializer()) {
1764 try writer.writeByte('(');1765 try w.writeByte('(');
1765 try dg.renderCType(writer, ctype);1766 try dg.renderCType(w, ctype);
1766 try writer.writeByte(')');1767 try w.writeByte(')');
1767 }1768 }
17681769
1769 const has_tag = loaded_union.hasTag(ip);1770 const has_tag = loaded_union.hasTag(ip);
1770 if (has_tag) try writer.writeByte('{');1771 if (has_tag) try w.writeByte('{');
1771 const aggregate = ctype.info(ctype_pool).aggregate;1772 const aggregate = ctype.info(ctype_pool).aggregate;
1772 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {1773 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
1773 if (outer_field_index > 0) try writer.writeByte(',');1774 if (outer_field_index > 0) try w.writeByte(',');
1774 switch (if (has_tag)1775 switch (if (has_tag)
1775 aggregate.fields.at(outer_field_index, ctype_pool).name.index1776 aggregate.fields.at(outer_field_index, ctype_pool).name.index
1776 else1777 else
1777 .payload) {1778 .payload) {
1778 .tag => try dg.renderUndefValue(1779 .tag => try dg.renderUndefValue(
1779 writer,1780 w,
1780 .fromInterned(loaded_union.enum_tag_ty),1781 .fromInterned(loaded_union.enum_tag_ty),
1781 initializer_type,1782 initializer_type,
1782 ),1783 ),
1783 .payload => {1784 .payload => {
1784 try writer.writeByte('{');1785 try w.writeByte('{');
1785 for (0..loaded_union.field_types.len) |inner_field_index| {1786 for (0..loaded_union.field_types.len) |inner_field_index| {
1786 const inner_field_ty: Type = .fromInterned(1787 const inner_field_ty: Type = .fromInterned(
1787 loaded_union.field_types.get(ip)[inner_field_index],1788 loaded_union.field_types.get(ip)[inner_field_index],
1788 );1789 );
1789 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;1790 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;
1790 try dg.renderUndefValue(1791 try dg.renderUndefValue(
1791 writer,1792 w,
1792 inner_field_ty,1793 inner_field_ty,
1793 initializer_type,1794 initializer_type,
1794 );1795 );
1795 break;1796 break;
1796 }1797 }
1797 try writer.writeByte('}');1798 try w.writeByte('}');
1798 },1799 },
1799 else => unreachable,1800 else => unreachable,
1800 }1801 }
1801 }1802 }
1802 if (has_tag) try writer.writeByte('}');1803 if (has_tag) try w.writeByte('}');
1803 },1804 },
1804 .@"packed" => return writer.print("{f}", .{1805 .@"packed" => return w.print("{f}", .{
1805 try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other),1806 try dg.fmtIntLiteralHex(try pt.undefValue(ty), .Other),
1806 }),1807 }),
1807 }1808 }
1808 },1809 },
1809 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {1810 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {
1810 .basic => try dg.renderUndefValue(1811 .basic => try dg.renderUndefValue(
1811 writer,1812 w,
1812 .fromInterned(error_union_type.error_set_type),1813 .fromInterned(error_union_type.error_set_type),
1813 location,1814 location,
1814 ),1815 ),
1815 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,1816 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1816 .aggregate => |aggregate| {1817 .aggregate => |aggregate| {
1817 if (!location.isInitializer()) {1818 if (!location.isInitializer()) {
1818 try writer.writeByte('(');1819 try w.writeByte('(');
1819 try dg.renderCType(writer, ctype);1820 try dg.renderCType(w, ctype);
1820 try writer.writeByte(')');1821 try w.writeByte(')');
1821 }1822 }
1822 try writer.writeByte('{');1823 try w.writeByte('{');
1823 for (0..aggregate.fields.len) |field_index| {1824 for (0..aggregate.fields.len) |field_index| {
1824 if (field_index > 0) try writer.writeByte(',');1825 if (field_index > 0) try w.writeByte(',');
1825 try dg.renderUndefValue(1826 try dg.renderUndefValue(
1826 writer,1827 w,
1827 .fromInterned(1828 .fromInterned(
1828 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {1829 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1829 .@"error" => error_union_type.error_set_type,1830 .@"error" => error_union_type.error_set_type,
...@@ -1834,14 +1835,14 @@ pub const DeclGen = struct {...@@ -1834,14 +1835,14 @@ pub const DeclGen = struct {
1834 initializer_type,1835 initializer_type,
1835 );1836 );
1836 }1837 }
1837 try writer.writeByte('}');1838 try w.writeByte('}');
1838 },1839 },
1839 },1840 },
1840 .array_type, .vector_type => {1841 .array_type, .vector_type => {
1841 const ai = ty.arrayInfo(zcu);1842 const ai = ty.arrayInfo(zcu);
1842 if (ai.elem_type.eql(.u8, zcu)) {1843 if (ai.elem_type.eql(.u8, zcu)) {
1843 const c_len = ty.arrayLenIncludingSentinel(zcu);1844 const c_len = ty.arrayLenIncludingSentinel(zcu);
1844 var literal: StringLiteral = .init(writer, c_len);1845 var literal: StringLiteral = .init(w, c_len);
1845 try literal.start();1846 try literal.start();
1846 var index: u64 = 0;1847 var index: u64 = 0;
1847 while (index < c_len) : (index += 1)1848 while (index < c_len) : (index += 1)
...@@ -1849,19 +1850,19 @@ pub const DeclGen = struct {...@@ -1849,19 +1850,19 @@ pub const DeclGen = struct {
1849 return literal.end();1850 return literal.end();
1850 } else {1851 } else {
1851 if (!location.isInitializer()) {1852 if (!location.isInitializer()) {
1852 try writer.writeByte('(');1853 try w.writeByte('(');
1853 try dg.renderCType(writer, ctype);1854 try dg.renderCType(w, ctype);
1854 try writer.writeByte(')');1855 try w.writeByte(')');
1855 }1856 }
18561857
1857 try writer.writeByte('{');1858 try w.writeByte('{');
1858 const c_len = ty.arrayLenIncludingSentinel(zcu);1859 const c_len = ty.arrayLenIncludingSentinel(zcu);
1859 var index: u64 = 0;1860 var index: u64 = 0;
1860 while (index < c_len) : (index += 1) {1861 while (index < c_len) : (index += 1) {
1861 if (index > 0) try writer.writeAll(", ");1862 if (index > 0) try w.writeAll(", ");
1862 try dg.renderUndefValue(writer, ty.childType(zcu), initializer_type);1863 try dg.renderUndefValue(w, ty.childType(zcu), initializer_type);
1863 }1864 }
1864 return writer.writeByte('}');1865 return w.writeByte('}');
1865 }1866 }
1866 },1867 },
1867 .anyframe_type,1868 .anyframe_type,
...@@ -1894,7 +1895,7 @@ pub const DeclGen = struct {...@@ -1894,7 +1895,7 @@ pub const DeclGen = struct {
18941895
1895 fn renderFunctionSignature(1896 fn renderFunctionSignature(
1896 dg: *DeclGen,1897 dg: *DeclGen,
1897 w: anytype,1898 w: *Writer,
1898 fn_val: Value,1899 fn_val: Value,
1899 fn_align: InternPool.Alignment,1900 fn_align: InternPool.Alignment,
1900 kind: CType.Kind,1901 kind: CType.Kind,
...@@ -2015,11 +2016,11 @@ pub const DeclGen = struct {...@@ -2015,11 +2016,11 @@ pub const DeclGen = struct {
2015 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |2016 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
2016 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |2017 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
2017 ///2018 ///
2018 fn renderType(dg: *DeclGen, w: anytype, t: Type) error{OutOfMemory}!void {2019 fn renderType(dg: *DeclGen, w: *Writer, t: Type) error{OutOfMemory}!void {
2019 try dg.renderCType(w, try dg.ctypeFromType(t, .complete));2020 try dg.renderCType(w, try dg.ctypeFromType(t, .complete));
2020 }2021 }
20212022
2022 fn renderCType(dg: *DeclGen, w: anytype, ctype: CType) error{OutOfMemory}!void {2023 fn renderCType(dg: *DeclGen, w: *Writer, ctype: CType) error{OutOfMemory}!void {
2023 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});2024 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
2024 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});2025 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
2025 }2026 }
...@@ -2034,7 +2035,7 @@ pub const DeclGen = struct {...@@ -2034,7 +2035,7 @@ pub const DeclGen = struct {
2034 value: Value,2035 value: Value,
2035 },2036 },
20362037
2037 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: anytype, location: ValueRenderLocation) !void {2038 pub fn writeValue(self: *const IntCastContext, dg: *DeclGen, w: *Writer, location: ValueRenderLocation) !void {
2038 switch (self.*) {2039 switch (self.*) {
2039 .c_value => |v| {2040 .c_value => |v| {
2040 try v.f.writeCValue(w, v.value, location);2041 try v.f.writeCValue(w, v.value, location);
...@@ -2080,7 +2081,7 @@ pub const DeclGen = struct {...@@ -2080,7 +2081,7 @@ pub const DeclGen = struct {
2080 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))2081 /// | > 64 bit integer | > 64 bit integer | zig_make_<dest_ty>(zig_hi_<src_ty>(src), zig_lo_<src_ty>(src))
2081 fn renderIntCast(2082 fn renderIntCast(
2082 dg: *DeclGen,2083 dg: *DeclGen,
2083 w: anytype,2084 w: *Writer,
2084 dest_ty: Type,2085 dest_ty: Type,
2085 context: IntCastContext,2086 context: IntCastContext,
2086 src_ty: Type,2087 src_ty: Type,
...@@ -2164,7 +2165,7 @@ pub const DeclGen = struct {...@@ -2164,7 +2165,7 @@ pub const DeclGen = struct {
2164 ///2165 ///
2165 fn renderTypeAndName(2166 fn renderTypeAndName(
2166 dg: *DeclGen,2167 dg: *DeclGen,
2167 w: anytype,2168 w: *Writer,
2168 ty: Type,2169 ty: Type,
2169 name: CValue,2170 name: CValue,
2170 qualifiers: CQualifiers,2171 qualifiers: CQualifiers,
...@@ -2185,7 +2186,7 @@ pub const DeclGen = struct {...@@ -2185,7 +2186,7 @@ pub const DeclGen = struct {
21852186
2186 fn renderCTypeAndName(2187 fn renderCTypeAndName(
2187 dg: *DeclGen,2188 dg: *DeclGen,
2188 w: anytype,2189 w: *Writer,
2189 ctype: CType,2190 ctype: CType,
2190 name: CValue,2191 name: CValue,
2191 qualifiers: CQualifiers,2192 qualifiers: CQualifiers,
...@@ -2205,7 +2206,7 @@ pub const DeclGen = struct {...@@ -2205,7 +2206,7 @@ pub const DeclGen = struct {
2205 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});2206 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});
2206 }2207 }
22072208
2208 fn writeName(dg: *DeclGen, w: anytype, c_value: CValue) !void {2209 fn writeName(dg: *DeclGen, w: *Writer, c_value: CValue) !void {
2209 switch (c_value) {2210 switch (c_value) {
2210 .new_local, .local => |i| try w.print("t{d}", .{i}),2211 .new_local, .local => |i| try w.print("t{d}", .{i}),
2211 .constant => |uav| try renderUavName(w, uav),2212 .constant => |uav| try renderUavName(w, uav),
...@@ -2215,7 +2216,7 @@ pub const DeclGen = struct {...@@ -2215,7 +2216,7 @@ pub const DeclGen = struct {
2215 }2216 }
2216 }2217 }
22172218
2218 fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void {2219 fn writeCValue(dg: *DeclGen, w: *Writer, c_value: CValue) !void {
2219 switch (c_value) {2220 switch (c_value) {
2220 .none, .new_local, .local, .local_ref => unreachable,2221 .none, .new_local, .local, .local_ref => unreachable,
2221 .constant => |uav| try renderUavName(w, uav),2222 .constant => |uav| try renderUavName(w, uav),
...@@ -2238,7 +2239,7 @@ pub const DeclGen = struct {...@@ -2238,7 +2239,7 @@ pub const DeclGen = struct {
2238 }2239 }
2239 }2240 }
22402241
2241 fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void {2242 fn writeCValueDeref(dg: *DeclGen, w: *Writer, c_value: CValue) !void {
2242 switch (c_value) {2243 switch (c_value) {
2243 .none,2244 .none,
2244 .new_local,2245 .new_local,
...@@ -2267,16 +2268,16 @@ pub const DeclGen = struct {...@@ -2267,16 +2268,16 @@ pub const DeclGen = struct {
22672268
2268 fn writeCValueMember(2269 fn writeCValueMember(
2269 dg: *DeclGen,2270 dg: *DeclGen,
2270 writer: anytype,2271 w: *Writer,
2271 c_value: CValue,2272 c_value: CValue,
2272 member: CValue,2273 member: CValue,
2273 ) error{ OutOfMemory, AnalysisFail }!void {2274 ) error{ OutOfMemory, AnalysisFail }!void {
2274 try dg.writeCValue(writer, c_value);2275 try dg.writeCValue(w, c_value);
2275 try writer.writeByte('.');2276 try w.writeByte('.');
2276 try dg.writeCValue(writer, member);2277 try dg.writeCValue(w, member);
2277 }2278 }
22782279
2279 fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void {2280 fn writeCValueDerefMember(dg: *DeclGen, w: *Writer, c_value: CValue, member: CValue) !void {
2280 switch (c_value) {2281 switch (c_value) {
2281 .none,2282 .none,
2282 .new_local,2283 .new_local,
...@@ -2290,15 +2291,15 @@ pub const DeclGen = struct {...@@ -2290,15 +2291,15 @@ pub const DeclGen = struct {
2290 .ctype_pool_string,2291 .ctype_pool_string,
2291 => unreachable,2292 => unreachable,
2292 .nav, .identifier, .payload_identifier => {2293 .nav, .identifier, .payload_identifier => {
2293 try dg.writeCValue(writer, c_value);2294 try dg.writeCValue(w, c_value);
2294 try writer.writeAll("->");2295 try w.writeAll("->");
2295 },2296 },
2296 .nav_ref => {2297 .nav_ref => {
2297 try dg.writeCValueDeref(writer, c_value);2298 try dg.writeCValueDeref(w, c_value);
2298 try writer.writeByte('.');2299 try w.writeByte('.');
2299 },2300 },
2300 }2301 }
2301 try dg.writeCValue(writer, member);2302 try dg.writeCValue(w, member);
2302 }2303 }
23032304
2304 fn renderFwdDecl(2305 fn renderFwdDecl(
...@@ -2340,36 +2341,36 @@ pub const DeclGen = struct {...@@ -2340,36 +2341,36 @@ pub const DeclGen = struct {
2340 try fwd.writeAll(";\n");2341 try fwd.writeAll(";\n");
2341 }2342 }
23422343
2343 fn renderNavName(dg: *DeclGen, writer: anytype, nav_index: InternPool.Nav.Index) !void {2344 fn renderNavName(dg: *DeclGen, w: *Writer, nav_index: InternPool.Nav.Index) !void {
2344 const zcu = dg.pt.zcu;2345 const zcu = dg.pt.zcu;
2345 const ip = &zcu.intern_pool;2346 const ip = &zcu.intern_pool;
2346 const nav = ip.getNav(nav_index);2347 const nav = ip.getNav(nav_index);
2347 if (nav.getExtern(ip)) |@"extern"| {2348 if (nav.getExtern(ip)) |@"extern"| {
2348 try writer.print("{f}", .{2349 try w.print("{f}", .{
2349 fmtIdentSolo(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),2350 fmtIdentSolo(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
2350 });2351 });
2351 } else {2352 } else {
2352 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),2353 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2353 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.2354 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2354 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);2355 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2355 try writer.print("{}__{d}", .{2356 try w.print("{}__{d}", .{
2356 fmtIdentUnsolo(fqn_slice[0..@min(fqn_slice.len, 100)]),2357 fmtIdentUnsolo(fqn_slice[0..@min(fqn_slice.len, 100)]),
2357 @intFromEnum(nav_index),2358 @intFromEnum(nav_index),
2358 });2359 });
2359 }2360 }
2360 }2361 }
23612362
2362 fn renderUavName(writer: anytype, uav: Value) !void {2363 fn renderUavName(w: *Writer, uav: Value) !void {
2363 try writer.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});2364 try w.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
2364 }2365 }
23652366
2366 fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void {2367 fn renderTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ty: Type) !void {
2367 try dg.renderCTypeForBuiltinFnName(writer, try dg.ctypeFromType(ty, .complete));2368 try dg.renderCTypeForBuiltinFnName(w, try dg.ctypeFromType(ty, .complete));
2368 }2369 }
23692370
2370 fn renderCTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ctype: CType) !void {2371 fn renderCTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ctype: CType) !void {
2371 switch (ctype.info(&dg.ctype_pool)) {2372 switch (ctype.info(&dg.ctype_pool)) {
2372 else => |ctype_info| try writer.print("{c}{d}", .{2373 else => |ctype_info| try w.print("{c}{d}", .{
2373 if (ctype.isBool())2374 if (ctype.isBool())
2374 signAbbrev(.unsigned)2375 signAbbrev(.unsigned)
2375 else if (ctype.isInteger())2376 else if (ctype.isInteger())
...@@ -2382,11 +2383,11 @@ pub const DeclGen = struct {...@@ -2382,11 +2383,11 @@ pub const DeclGen = struct {
2382 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),2383 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),
2383 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,2384 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,
2384 }),2385 }),
2385 .array => try writer.writeAll("big"),2386 .array => try w.writeAll("big"),
2386 }2387 }
2387 }2388 }
23882389
2389 fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void {2390 fn renderBuiltinInfo(dg: *DeclGen, w: *Writer, ty: Type, info: BuiltinInfo) !void {
2390 const ctype = try dg.ctypeFromType(ty, .complete);2391 const ctype = try dg.ctypeFromType(ty, .complete);
2391 const is_big = ctype.info(&dg.ctype_pool) == .array;2392 const is_big = ctype.info(&dg.ctype_pool) == .array;
2392 switch (info) {2393 switch (info) {
...@@ -2401,8 +2402,8 @@ pub const DeclGen = struct {...@@ -2401,8 +2402,8 @@ pub const DeclGen = struct {
2401 .bits = @intCast(ty.bitSize(zcu)),2402 .bits = @intCast(ty.bitSize(zcu)),
2402 };2403 };
24032404
2404 if (is_big) try writer.print(", {}", .{int_info.signedness == .signed});2405 if (is_big) try w.print(", {}", .{int_info.signedness == .signed});
2405 try writer.print(", {f}", .{try dg.fmtIntLiteralDec(2406 try w.print(", {f}", .{try dg.fmtIntLiteralDec(
2406 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),2407 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),
2407 .FunctionArgument,2408 .FunctionArgument,
2408 )});2409 )});
...@@ -2457,7 +2458,7 @@ const RenderCTypeTrailing = enum {...@@ -2457,7 +2458,7 @@ const RenderCTypeTrailing = enum {
2457 self: @This(),2458 self: @This(),
2458 comptime fmt: []const u8,2459 comptime fmt: []const u8,
2459 _: std.fmt.FormatOptions,2460 _: std.fmt.FormatOptions,
2460 w: anytype,2461 w: *Writer,
2461 ) @TypeOf(w).Error!void {2462 ) @TypeOf(w).Error!void {
2462 if (fmt.len != 0)2463 if (fmt.len != 0)
2463 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++2464 @compileError("invalid format string '" ++ fmt ++ "' for type '" ++
...@@ -2469,12 +2470,12 @@ const RenderCTypeTrailing = enum {...@@ -2469,12 +2470,12 @@ const RenderCTypeTrailing = enum {
2469 }2470 }
2470 }2471 }
2471};2472};
2472fn renderAlignedTypeName(w: anytype, ctype: CType) !void {2473fn renderAlignedTypeName(w: *Writer, ctype: CType) !void {
2473 try w.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});2474 try w.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
2474}2475}
2475fn renderFwdDeclTypeName(2476fn renderFwdDeclTypeName(
2476 zcu: *Zcu,2477 zcu: *Zcu,
2477 w: anytype,2478 w: *Writer,
2478 ctype: CType,2479 ctype: CType,
2479 fwd_decl: CType.Info.FwdDecl,2480 fwd_decl: CType.Info.FwdDecl,
2480 attributes: []const u8,2481 attributes: []const u8,
...@@ -2493,7 +2494,7 @@ fn renderTypePrefix(...@@ -2493,7 +2494,7 @@ fn renderTypePrefix(
2493 pass: DeclGen.Pass,2494 pass: DeclGen.Pass,
2494 ctype_pool: *const CType.Pool,2495 ctype_pool: *const CType.Pool,
2495 zcu: *Zcu,2496 zcu: *Zcu,
2496 w: anytype,2497 w: *Writer,
2497 ctype: CType,2498 ctype: CType,
2498 parent_fix: CTypeFix,2499 parent_fix: CTypeFix,
2499 qualifiers: CQualifiers,2500 qualifiers: CQualifiers,
...@@ -2610,7 +2611,7 @@ fn renderTypeSuffix(...@@ -2610,7 +2611,7 @@ fn renderTypeSuffix(
2610 pass: DeclGen.Pass,2611 pass: DeclGen.Pass,
2611 ctype_pool: *const CType.Pool,2612 ctype_pool: *const CType.Pool,
2612 zcu: *Zcu,2613 zcu: *Zcu,
2613 w: anytype,2614 w: *Writer,
2614 ctype: CType,2615 ctype: CType,
2615 parent_fix: CTypeFix,2616 parent_fix: CTypeFix,
2616 qualifiers: CQualifiers,2617 qualifiers: CQualifiers,
...@@ -2666,49 +2667,49 @@ fn renderTypeSuffix(...@@ -2666,49 +2667,49 @@ fn renderTypeSuffix(
2666}2667}
2667fn renderFields(2668fn renderFields(
2668 zcu: *Zcu,2669 zcu: *Zcu,
2669 writer: anytype,2670 w: *Writer,
2670 ctype_pool: *const CType.Pool,2671 ctype_pool: *const CType.Pool,
2671 aggregate_info: CType.Info.Aggregate,2672 aggregate_info: CType.Info.Aggregate,
2672 indent: usize,2673 indent: usize,
2673) !void {2674) !void {
2674 try writer.writeAll("{\n");2675 try w.writeAll("{\n");
2675 for (0..aggregate_info.fields.len) |field_index| {2676 for (0..aggregate_info.fields.len) |field_index| {
2676 const field_info = aggregate_info.fields.at(field_index, ctype_pool);2677 const field_info = aggregate_info.fields.at(field_index, ctype_pool);
2677 try writer.writeByteNTimes(' ', indent + 1);2678 try w.writeByteNTimes(' ', indent + 1);
2678 switch (field_info.alignas.abiOrder()) {2679 switch (field_info.alignas.abiOrder()) {
2679 .lt => {2680 .lt => {
2680 std.debug.assert(aggregate_info.@"packed");2681 std.debug.assert(aggregate_info.@"packed");
2681 if (field_info.alignas.@"align" != .@"1") try writer.print("zig_under_align({}) ", .{2682 if (field_info.alignas.@"align" != .@"1") try w.print("zig_under_align({}) ", .{
2682 field_info.alignas.toByteUnits(),2683 field_info.alignas.toByteUnits(),
2683 });2684 });
2684 },2685 },
2685 .eq => if (aggregate_info.@"packed" and field_info.alignas.@"align" != .@"1")2686 .eq => if (aggregate_info.@"packed" and field_info.alignas.@"align" != .@"1")
2686 try writer.print("zig_align({}) ", .{field_info.alignas.toByteUnits()}),2687 try w.print("zig_align({}) ", .{field_info.alignas.toByteUnits()}),
2687 .gt => {2688 .gt => {
2688 std.debug.assert(field_info.alignas.@"align" != .@"1");2689 std.debug.assert(field_info.alignas.@"align" != .@"1");
2689 try writer.print("zig_align({}) ", .{field_info.alignas.toByteUnits()});2690 try w.print("zig_align({}) ", .{field_info.alignas.toByteUnits()});
2690 },2691 },
2691 }2692 }
2692 const trailing = try renderTypePrefix(2693 const trailing = try renderTypePrefix(
2693 .flush,2694 .flush,
2694 ctype_pool,2695 ctype_pool,
2695 zcu,2696 zcu,
2696 writer,2697 w,
2697 field_info.ctype,2698 field_info.ctype,
2698 .suffix,2699 .suffix,
2699 .{},2700 .{},
2700 );2701 );
2701 try writer.print("{}{f}", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool, true) });2702 try w.print("{}{f}", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool, true) });
2702 try renderTypeSuffix(.flush, ctype_pool, zcu, writer, field_info.ctype, .suffix, .{});2703 try renderTypeSuffix(.flush, ctype_pool, zcu, w, field_info.ctype, .suffix, .{});
2703 try writer.writeAll(";\n");2704 try w.writeAll(";\n");
2704 }2705 }
2705 try writer.writeByteNTimes(' ', indent);2706 try w.writeByteNTimes(' ', indent);
2706 try writer.writeByte('}');2707 try w.writeByte('}');
2707}2708}
27082709
2709pub fn genTypeDecl(2710pub fn genTypeDecl(
2710 zcu: *Zcu,2711 zcu: *Zcu,
2711 writer: anytype,2712 w: *Writer,
2712 global_ctype_pool: *const CType.Pool,2713 global_ctype_pool: *const CType.Pool,
2713 global_ctype: CType,2714 global_ctype: CType,
2714 pass: DeclGen.Pass,2715 pass: DeclGen.Pass,
...@@ -2721,27 +2722,27 @@ pub fn genTypeDecl(...@@ -2721,27 +2722,27 @@ pub fn genTypeDecl(
2721 .aligned => |aligned_info| {2722 .aligned => |aligned_info| {
2722 if (!found_existing) {2723 if (!found_existing) {
2723 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));2724 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));
2724 try writer.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});2725 try w.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2725 try writer.print("{}", .{try renderTypePrefix(2726 try w.print("{}", .{try renderTypePrefix(
2726 .flush,2727 .flush,
2727 global_ctype_pool,2728 global_ctype_pool,
2728 zcu,2729 zcu,
2729 writer,2730 w,
2730 aligned_info.ctype,2731 aligned_info.ctype,
2731 .suffix,2732 .suffix,
2732 .{},2733 .{},
2733 )});2734 )});
2734 try renderAlignedTypeName(writer, global_ctype);2735 try renderAlignedTypeName(w, global_ctype);
2735 try renderTypeSuffix(.flush, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{});2736 try renderTypeSuffix(.flush, global_ctype_pool, zcu, w, aligned_info.ctype, .suffix, .{});
2736 try writer.writeAll(";\n");2737 try w.writeAll(";\n");
2737 }2738 }
2738 switch (pass) {2739 switch (pass) {
2739 .nav, .uav => {2740 .nav, .uav => {
2740 try writer.writeAll("typedef ");2741 try w.writeAll("typedef ");
2741 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2742 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2742 try writer.writeByte(' ');2743 try w.writeByte(' ');
2743 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});2744 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, w, decl_ctype, .suffix, .{});
2744 try writer.writeAll(";\n");2745 try w.writeAll(";\n");
2745 },2746 },
2746 .flush => {},2747 .flush => {},
2747 }2748 }
...@@ -2749,24 +2750,24 @@ pub fn genTypeDecl(...@@ -2749,24 +2750,24 @@ pub fn genTypeDecl(
2749 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {2750 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2750 .anon => switch (pass) {2751 .anon => switch (pass) {
2751 .nav, .uav => {2752 .nav, .uav => {
2752 try writer.writeAll("typedef ");2753 try w.writeAll("typedef ");
2753 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2754 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2754 try writer.writeByte(' ');2755 try w.writeByte(' ');
2755 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, writer, decl_ctype, .suffix, .{});2756 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, w, decl_ctype, .suffix, .{});
2756 try writer.writeAll(";\n");2757 try w.writeAll(";\n");
2757 },2758 },
2758 .flush => {},2759 .flush => {},
2759 },2760 },
2760 .index => |index| if (!found_existing) {2761 .index => |index| if (!found_existing) {
2761 const ip = &zcu.intern_pool;2762 const ip = &zcu.intern_pool;
2762 const ty: Type = .fromInterned(index);2763 const ty: Type = .fromInterned(index);
2763 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{});2764 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2764 try writer.writeByte(';');2765 try w.writeByte(';');
2765 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);2766 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);
2766 if (!zcu.fileByIndex(file_scope).mod.?.strip) try writer.print(" /* {} */", .{2767 if (!zcu.fileByIndex(file_scope).mod.?.strip) try w.print(" /* {} */", .{
2767 ty.containerTypeName(ip).fmt(ip),2768 ty.containerTypeName(ip).fmt(ip),
2768 });2769 });
2769 try writer.writeByte('\n');2770 try w.writeByte('\n');
2770 },2771 },
2771 },2772 },
2772 .aggregate => |aggregate_info| switch (aggregate_info.name) {2773 .aggregate => |aggregate_info| switch (aggregate_info.name) {
...@@ -2774,23 +2775,23 @@ pub fn genTypeDecl(...@@ -2774,23 +2775,23 @@ pub fn genTypeDecl(
2774 .fwd_decl => |fwd_decl| if (!found_existing) {2775 .fwd_decl => |fwd_decl| if (!found_existing) {
2775 try renderFwdDeclTypeName(2776 try renderFwdDeclTypeName(
2776 zcu,2777 zcu,
2777 writer,2778 w,
2778 fwd_decl,2779 fwd_decl,
2779 fwd_decl.info(global_ctype_pool).fwd_decl,2780 fwd_decl.info(global_ctype_pool).fwd_decl,
2780 if (aggregate_info.@"packed") "zig_packed(" else "",2781 if (aggregate_info.@"packed") "zig_packed(" else "",
2781 );2782 );
2782 try writer.writeByte(' ');2783 try w.writeByte(' ');
2783 try renderFields(zcu, writer, global_ctype_pool, aggregate_info, 0);2784 try renderFields(zcu, w, global_ctype_pool, aggregate_info, 0);
2784 if (aggregate_info.@"packed") try writer.writeByte(')');2785 if (aggregate_info.@"packed") try w.writeByte(')');
2785 try writer.writeAll(";\n");2786 try w.writeAll(";\n");
2786 },2787 },
2787 },2788 },
2788 }2789 }
2789}2790}
27902791
2791pub fn genGlobalAsm(zcu: *Zcu, writer: anytype) !void {2792pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
2792 for (zcu.global_assembly.values()) |asm_source| {2793 for (zcu.global_assembly.values()) |asm_source| {
2793 try writer.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)});2794 try w.print("__asm({f});\n", .{fmtStringLiteral(asm_source, null)});
2794 }2795 }
2795}2796}
27962797
...@@ -2798,13 +2799,13 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2798,13 +2799,13 @@ pub fn genErrDecls(o: *Object) !void {
2798 const pt = o.dg.pt;2799 const pt = o.dg.pt;
2799 const zcu = pt.zcu;2800 const zcu = pt.zcu;
2800 const ip = &zcu.intern_pool;2801 const ip = &zcu.intern_pool;
2801 const writer = o.writer();2802 const w = o.writer();
28022803
2803 var max_name_len: usize = 0;2804 var max_name_len: usize = 0;
2804 // do not generate an invalid empty enum when the global error set is empty2805 // do not generate an invalid empty enum when the global error set is empty
2805 const names = ip.global_error_set.getNamesFromMainThread();2806 const names = ip.global_error_set.getNamesFromMainThread();
2806 if (names.len > 0) {2807 if (names.len > 0) {
2807 try writer.writeAll("enum {\n");2808 try w.writeAll("enum {\n");
2808 o.indent_writer.pushIndent();2809 o.indent_writer.pushIndent();
2809 for (names, 1..) |name_nts, value| {2810 for (names, 1..) |name_nts, value| {
2810 const name = name_nts.toSlice(ip);2811 const name = name_nts.toSlice(ip);
...@@ -2813,11 +2814,11 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2813,11 +2814,11 @@ pub fn genErrDecls(o: *Object) !void {
2813 .ty = .anyerror_type,2814 .ty = .anyerror_type,
2814 .name = name_nts,2815 .name = name_nts,
2815 } });2816 } });
2816 try o.dg.renderValue(writer, Value.fromInterned(err_val), .Other);2817 try o.dg.renderValue(w, Value.fromInterned(err_val), .Other);
2817 try writer.print(" = {d}u,\n", .{value});2818 try w.print(" = {d}u,\n", .{value});
2818 }2819 }
2819 o.indent_writer.popIndent();2820 o.indent_writer.popIndent();
2820 try writer.writeAll("};\n");2821 try w.writeAll("};\n");
2821 }2822 }
2822 const array_identifier = "zig_errorName";2823 const array_identifier = "zig_errorName";
2823 const name_prefix = array_identifier ++ "_";2824 const name_prefix = array_identifier ++ "_";
...@@ -2840,18 +2841,18 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2840,18 +2841,18 @@ pub fn genErrDecls(o: *Object) !void {
2840 .storage = .{ .bytes = name.toString() },2841 .storage = .{ .bytes = name.toString() },
2841 } });2842 } });
28422843
2843 try writer.writeAll("static ");2844 try w.writeAll("static ");
2844 try o.dg.renderTypeAndName(2845 try o.dg.renderTypeAndName(
2845 writer,2846 w,
2846 name_ty,2847 name_ty,
2847 .{ .identifier = identifier },2848 .{ .identifier = identifier },
2848 Const,2849 Const,
2849 .none,2850 .none,
2850 .complete,2851 .complete,
2851 );2852 );
2852 try writer.writeAll(" = ");2853 try w.writeAll(" = ");
2853 try o.dg.renderValue(writer, Value.fromInterned(name_val), .StaticInitializer);2854 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);
2854 try writer.writeAll(";\n");2855 try w.writeAll(";\n");
2855 }2856 }
28562857
2857 const name_array_ty = try pt.arrayType(.{2858 const name_array_ty = try pt.arrayType(.{
...@@ -2859,25 +2860,25 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2859,25 +2860,25 @@ pub fn genErrDecls(o: *Object) !void {
2859 .child = .slice_const_u8_sentinel_0_type,2860 .child = .slice_const_u8_sentinel_0_type,
2860 });2861 });
28612862
2862 try writer.writeAll("static ");2863 try w.writeAll("static ");
2863 try o.dg.renderTypeAndName(2864 try o.dg.renderTypeAndName(
2864 writer,2865 w,
2865 name_array_ty,2866 name_array_ty,
2866 .{ .identifier = array_identifier },2867 .{ .identifier = array_identifier },
2867 Const,2868 Const,
2868 .none,2869 .none,
2869 .complete,2870 .complete,
2870 );2871 );
2871 try writer.writeAll(" = {");2872 try w.writeAll(" = {");
2872 for (names, 1..) |name_nts, val| {2873 for (names, 1..) |name_nts, val| {
2873 const name = name_nts.toSlice(ip);2874 const name = name_nts.toSlice(ip);
2874 if (val > 1) try writer.writeAll(", ");2875 if (val > 1) try w.writeAll(", ");
2875 try writer.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{2876 try w.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{
2876 fmtIdentUnsolo(name),2877 fmtIdentUnsolo(name),
2877 try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, name.len), .StaticInitializer),2878 try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, name.len), .StaticInitializer),
2878 });2879 });
2879 }2880 }
2880 try writer.writeAll("};\n");2881 try w.writeAll("};\n");
2881}2882}
28822883
2883pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void {2884pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) !void {
...@@ -3305,15 +3306,15 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const...@@ -3305,15 +3306,15 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
3305/// have been added to `free_locals_map`. For a version of this function that restores this state,3306/// have been added to `free_locals_map`. For a version of this function that restores this state,
3306/// see `genBodyResolveState`.3307/// see `genBodyResolveState`.
3307fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {3308fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutOfMemory }!void {
3308 const writer = f.object.writer();3309 const w = f.object.writer();
3309 if (body.len == 0) {3310 if (body.len == 0) {
3310 try writer.writeAll("{}");3311 try w.writeAll("{}");
3311 } else {3312 } else {
3312 try writer.writeAll("{\n");3313 try w.writeAll("{\n");
3313 f.object.indent_writer.pushIndent();3314 f.object.indent_writer.pushIndent();
3314 try genBodyInner(f, body);3315 try genBodyInner(f, body);
3315 f.object.indent_writer.popIndent();3316 f.object.indent_writer.popIndent();
3316 try writer.writeByte('}');3317 try w.writeByte('}');
3317 }3318 }
3318}3319}
33193320
...@@ -3687,16 +3688,16 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [...@@ -3687,16 +3688,16 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
3687 const operand = try f.resolveInst(ty_op.operand);3688 const operand = try f.resolveInst(ty_op.operand);
3688 try reap(f, inst, &.{ty_op.operand});3689 try reap(f, inst, &.{ty_op.operand});
36893690
3690 const writer = f.object.writer();3691 const w = f.object.writer();
3691 const local = try f.allocLocal(inst, inst_ty);3692 const local = try f.allocLocal(inst, inst_ty);
3692 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3693 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3693 try f.writeCValue(writer, local, .Other);3694 try f.writeCValue(w, local, .Other);
3694 try a.assign(f, writer);3695 try a.assign(f, w);
3695 if (is_ptr) {3696 if (is_ptr) {
3696 try writer.writeByte('&');3697 try w.writeByte('&');
3697 try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name });3698 try f.writeCValueDerefMember(w, operand, .{ .identifier = field_name });
3698 } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name });3699 } else try f.writeCValueMember(w, operand, .{ .identifier = field_name });
3699 try a.end(f, writer);3700 try a.end(f, w);
3700 return local;3701 return local;
3701}3702}
37023703
...@@ -3713,16 +3714,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3713,16 +3714,16 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3713 const index = try f.resolveInst(bin_op.rhs);3714 const index = try f.resolveInst(bin_op.rhs);
3714 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3715 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37153716
3716 const writer = f.object.writer();3717 const w = f.object.writer();
3717 const local = try f.allocLocal(inst, inst_ty);3718 const local = try f.allocLocal(inst, inst_ty);
3718 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3719 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3719 try f.writeCValue(writer, local, .Other);3720 try f.writeCValue(w, local, .Other);
3720 try a.assign(f, writer);3721 try a.assign(f, w);
3721 try f.writeCValue(writer, ptr, .Other);3722 try f.writeCValue(w, ptr, .Other);
3722 try writer.writeByte('[');3723 try w.writeByte('[');
3723 try f.writeCValue(writer, index, .Other);3724 try f.writeCValue(w, index, .Other);
3724 try writer.writeByte(']');3725 try w.writeByte(']');
3725 try a.end(f, writer);3726 try a.end(f, w);
3726 return local;3727 return local;
3727}3728}
37283729
...@@ -3740,25 +3741,25 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3740,25 +3741,25 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3740 const index = try f.resolveInst(bin_op.rhs);3741 const index = try f.resolveInst(bin_op.rhs);
3741 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3742 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37423743
3743 const writer = f.object.writer();3744 const w = f.object.writer();
3744 const local = try f.allocLocal(inst, inst_ty);3745 const local = try f.allocLocal(inst, inst_ty);
3745 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3746 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3746 try f.writeCValue(writer, local, .Other);3747 try f.writeCValue(w, local, .Other);
3747 try a.assign(f, writer);3748 try a.assign(f, w);
3748 try writer.writeByte('(');3749 try w.writeByte('(');
3749 try f.renderType(writer, inst_ty);3750 try f.renderType(w, inst_ty);
3750 try writer.writeByte(')');3751 try w.writeByte(')');
3751 if (elem_has_bits) try writer.writeByte('&');3752 if (elem_has_bits) try w.writeByte('&');
3752 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {3753 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {
3753 // It's a pointer to an array, so we need to de-reference.3754 // It's a pointer to an array, so we need to de-reference.
3754 try f.writeCValueDeref(writer, ptr);3755 try f.writeCValueDeref(w, ptr);
3755 } else try f.writeCValue(writer, ptr, .Other);3756 } else try f.writeCValue(w, ptr, .Other);
3756 if (elem_has_bits) {3757 if (elem_has_bits) {
3757 try writer.writeByte('[');3758 try w.writeByte('[');
3758 try f.writeCValue(writer, index, .Other);3759 try f.writeCValue(w, index, .Other);
3759 try writer.writeByte(']');3760 try w.writeByte(']');
3760 }3761 }
3761 try a.end(f, writer);3762 try a.end(f, w);
3762 return local;3763 return local;
3763}3764}
37643765
...@@ -3775,16 +3776,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3775,16 +3776,16 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3775 const index = try f.resolveInst(bin_op.rhs);3776 const index = try f.resolveInst(bin_op.rhs);
3776 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3777 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37773778
3778 const writer = f.object.writer();3779 const w = f.object.writer();
3779 const local = try f.allocLocal(inst, inst_ty);3780 const local = try f.allocLocal(inst, inst_ty);
3780 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3781 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3781 try f.writeCValue(writer, local, .Other);3782 try f.writeCValue(w, local, .Other);
3782 try a.assign(f, writer);3783 try a.assign(f, w);
3783 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });3784 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
3784 try writer.writeByte('[');3785 try w.writeByte('[');
3785 try f.writeCValue(writer, index, .Other);3786 try f.writeCValue(w, index, .Other);
3786 try writer.writeByte(']');3787 try w.writeByte(']');
3787 try a.end(f, writer);3788 try a.end(f, w);
3788 return local;3789 return local;
3789}3790}
37903791
...@@ -3803,19 +3804,19 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3803,19 +3804,19 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3803 const index = try f.resolveInst(bin_op.rhs);3804 const index = try f.resolveInst(bin_op.rhs);
3804 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3805 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
38053806
3806 const writer = f.object.writer();3807 const w = f.object.writer();
3807 const local = try f.allocLocal(inst, inst_ty);3808 const local = try f.allocLocal(inst, inst_ty);
3808 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3809 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3809 try f.writeCValue(writer, local, .Other);3810 try f.writeCValue(w, local, .Other);
3810 try a.assign(f, writer);3811 try a.assign(f, w);
3811 if (elem_has_bits) try writer.writeByte('&');3812 if (elem_has_bits) try w.writeByte('&');
3812 try f.writeCValueMember(writer, slice, .{ .identifier = "ptr" });3813 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
3813 if (elem_has_bits) {3814 if (elem_has_bits) {
3814 try writer.writeByte('[');3815 try w.writeByte('[');
3815 try f.writeCValue(writer, index, .Other);3816 try f.writeCValue(w, index, .Other);
3816 try writer.writeByte(']');3817 try w.writeByte(']');
3817 }3818 }
3818 try a.end(f, writer);3819 try a.end(f, w);
3819 return local;3820 return local;
3820}3821}
38213822
...@@ -3832,16 +3833,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3832,16 +3833,16 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3832 const index = try f.resolveInst(bin_op.rhs);3833 const index = try f.resolveInst(bin_op.rhs);
3833 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });3834 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
38343835
3835 const writer = f.object.writer();3836 const w = f.object.writer();
3836 const local = try f.allocLocal(inst, inst_ty);3837 const local = try f.allocLocal(inst, inst_ty);
3837 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));3838 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3838 try f.writeCValue(writer, local, .Other);3839 try f.writeCValue(w, local, .Other);
3839 try a.assign(f, writer);3840 try a.assign(f, w);
3840 try f.writeCValue(writer, array, .Other);3841 try f.writeCValue(w, array, .Other);
3841 try writer.writeByte('[');3842 try w.writeByte('[');
3842 try f.writeCValue(writer, index, .Other);3843 try f.writeCValue(w, index, .Other);
3843 try writer.writeByte(']');3844 try w.writeByte(']');
3844 try a.end(f, writer);3845 try a.end(f, w);
3845 return local;3846 return local;
3846}3847}
38473848
...@@ -3895,12 +3896,12 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3895,12 +3896,12 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3895 .{ .arg_array = i };3896 .{ .arg_array = i };
38963897
3897 if (f.liveness.isUnused(inst)) {3898 if (f.liveness.isUnused(inst)) {
3898 const writer = f.object.writer();3899 const w = f.object.writer();
3899 try writer.writeByte('(');3900 try w.writeByte('(');
3900 try f.renderType(writer, .void);3901 try f.renderType(w, .void);
3901 try writer.writeByte(')');3902 try w.writeByte(')');
3902 try f.writeCValue(writer, result, .Other);3903 try f.writeCValue(w, result, .Other);
3903 try writer.writeAll(";\n");3904 try w.writeAll(";\n");
3904 return .none;3905 return .none;
3905 }3906 }
39063907
...@@ -3933,21 +3934,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3933,21 +3934,21 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3933 const is_array = lowersToArray(src_ty, pt);3934 const is_array = lowersToArray(src_ty, pt);
3934 const need_memcpy = !is_aligned or is_array;3935 const need_memcpy = !is_aligned or is_array;
39353936
3936 const writer = f.object.writer();3937 const w = f.object.writer();
3937 const local = try f.allocLocal(inst, src_ty);3938 const local = try f.allocLocal(inst, src_ty);
3938 const v = try Vectorize.start(f, inst, writer, ptr_ty);3939 const v = try Vectorize.start(f, inst, w, ptr_ty);
39393940
3940 if (need_memcpy) {3941 if (need_memcpy) {
3941 try writer.writeAll("memcpy(");3942 try w.writeAll("memcpy(");
3942 if (!is_array) try writer.writeByte('&');3943 if (!is_array) try w.writeByte('&');
3943 try f.writeCValue(writer, local, .Other);3944 try f.writeCValue(w, local, .Other);
3944 try v.elem(f, writer);3945 try v.elem(f, w);
3945 try writer.writeAll(", (const char *)");3946 try w.writeAll(", (const char *)");
3946 try f.writeCValue(writer, operand, .Other);3947 try f.writeCValue(w, operand, .Other);
3947 try v.elem(f, writer);3948 try v.elem(f, w);
3948 try writer.writeAll(", sizeof(");3949 try w.writeAll(", sizeof(");
3949 try f.renderType(writer, src_ty);3950 try f.renderType(w, src_ty);
3950 try writer.writeAll("))");3951 try w.writeAll("))");
3951 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {3952 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
3952 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;3953 const host_bits: u16 = ptr_info.packed_offset.host_size * 8;
3953 const host_ty = try pt.intType(.unsigned, host_bits);3954 const host_ty = try pt.intType(.unsigned, host_bits);
...@@ -3957,40 +3958,40 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3957,40 +3958,40 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39573958
3958 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));3959 const field_ty = try pt.intType(.unsigned, @as(u16, @intCast(src_ty.bitSize(zcu))));
39593960
3960 try f.writeCValue(writer, local, .Other);3961 try f.writeCValue(w, local, .Other);
3961 try v.elem(f, writer);3962 try v.elem(f, w);
3962 try writer.writeAll(" = (");3963 try w.writeAll(" = (");
3963 try f.renderType(writer, src_ty);3964 try f.renderType(w, src_ty);
3964 try writer.writeAll(")zig_wrap_");3965 try w.writeAll(")zig_wrap_");
3965 try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty);3966 try f.object.dg.renderTypeForBuiltinFnName(w, field_ty);
3966 try writer.writeAll("((");3967 try w.writeAll("((");
3967 try f.renderType(writer, field_ty);3968 try f.renderType(w, field_ty);
3968 try writer.writeByte(')');3969 try w.writeByte(')');
3969 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;3970 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
3970 if (cant_cast) {3971 if (cant_cast) {
3971 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});3972 if (field_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
3972 try writer.writeAll("zig_lo_");3973 try w.writeAll("zig_lo_");
3973 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3974 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
3974 try writer.writeByte('(');3975 try w.writeByte('(');
3975 }3976 }
3976 try writer.writeAll("zig_shr_");3977 try w.writeAll("zig_shr_");
3977 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);3978 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
3978 try writer.writeByte('(');3979 try w.writeByte('(');
3979 try f.writeCValueDeref(writer, operand);3980 try f.writeCValueDeref(w, operand);
3980 try v.elem(f, writer);3981 try v.elem(f, w);
3981 try writer.print(", {f})", .{try f.fmtIntLiteralDec(bit_offset_val)});3982 try w.print(", {f})", .{try f.fmtIntLiteralDec(bit_offset_val)});
3982 if (cant_cast) try writer.writeByte(')');3983 if (cant_cast) try w.writeByte(')');
3983 try f.object.dg.renderBuiltinInfo(writer, field_ty, .bits);3984 try f.object.dg.renderBuiltinInfo(w, field_ty, .bits);
3984 try writer.writeByte(')');3985 try w.writeByte(')');
3985 } else {3986 } else {
3986 try f.writeCValue(writer, local, .Other);3987 try f.writeCValue(w, local, .Other);
3987 try v.elem(f, writer);3988 try v.elem(f, w);
3988 try writer.writeAll(" = ");3989 try w.writeAll(" = ");
3989 try f.writeCValueDeref(writer, operand);3990 try f.writeCValueDeref(w, operand);
3990 try v.elem(f, writer);3991 try v.elem(f, w);
3991 }3992 }
3992 try writer.writeAll(";\n");3993 try w.writeAll(";\n");
3993 try v.end(f, inst, writer);3994 try v.end(f, inst, w);
39943995
3995 return local;3996 return local;
3996}3997}
...@@ -3999,7 +4000,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -3999,7 +4000,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3999 const pt = f.object.dg.pt;4000 const pt = f.object.dg.pt;
4000 const zcu = pt.zcu;4001 const zcu = pt.zcu;
4001 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;4002 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
4002 const writer = f.object.writer();4003 const w = f.object.writer();
4003 const op_inst = un_op.toIndex();4004 const op_inst = un_op.toIndex();
4004 const op_ty = f.typeOf(un_op);4005 const op_ty = f.typeOf(un_op);
4005 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;4006 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;
...@@ -4018,33 +4019,33 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {...@@ -4018,33 +4019,33 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
4018 .ctype = ret_ctype,4019 .ctype = ret_ctype,
4019 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),4020 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
4020 });4021 });
4021 try writer.writeAll("memcpy(");4022 try w.writeAll("memcpy(");
4022 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });4023 try f.writeCValueMember(w, array_local, .{ .identifier = "array" });
4023 try writer.writeAll(", ");4024 try w.writeAll(", ");
4024 if (deref)4025 if (deref)
4025 try f.writeCValueDeref(writer, operand)4026 try f.writeCValueDeref(w, operand)
4026 else4027 else
4027 try f.writeCValue(writer, operand, .FunctionArgument);4028 try f.writeCValue(w, operand, .FunctionArgument);
4028 deref = false;4029 deref = false;
4029 try writer.writeAll(", sizeof(");4030 try w.writeAll(", sizeof(");
4030 try f.renderType(writer, ret_ty);4031 try f.renderType(w, ret_ty);
4031 try writer.writeAll("));\n");4032 try w.writeAll("));\n");
4032 break :ret_val array_local;4033 break :ret_val array_local;
4033 } else operand;4034 } else operand;
40344035
4035 try writer.writeAll("return ");4036 try w.writeAll("return ");
4036 if (deref)4037 if (deref)
4037 try f.writeCValueDeref(writer, ret_val)4038 try f.writeCValueDeref(w, ret_val)
4038 else4039 else
4039 try f.writeCValue(writer, ret_val, .Other);4040 try f.writeCValue(w, ret_val, .Other);
4040 try writer.writeAll(";\n");4041 try w.writeAll(";\n");
4041 if (is_array) {4042 if (is_array) {
4042 try freeLocal(f, inst, ret_val.new_local, null);4043 try freeLocal(f, inst, ret_val.new_local, null);
4043 }4044 }
4044 } else {4045 } else {
4045 try reap(f, inst, &.{un_op});4046 try reap(f, inst, &.{un_op});
4046 // Not even allowed to return void in a naked function.4047 // Not even allowed to return void in a naked function.
4047 if (!f.object.dg.is_naked_fn) try writer.writeAll("return;\n");4048 if (!f.object.dg.is_naked_fn) try w.writeAll("return;\n");
4048 }4049 }
4049}4050}
40504051
...@@ -4063,16 +4064,16 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4063,16 +4064,16 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
40634064
4064 if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);4065 if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);
40654066
4066 const writer = f.object.writer();4067 const w = f.object.writer();
4067 const local = try f.allocLocal(inst, inst_ty);4068 const local = try f.allocLocal(inst, inst_ty);
4068 const v = try Vectorize.start(f, inst, writer, operand_ty);4069 const v = try Vectorize.start(f, inst, w, operand_ty);
4069 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));4070 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
4070 try f.writeCValue(writer, local, .Other);4071 try f.writeCValue(w, local, .Other);
4071 try v.elem(f, writer);4072 try v.elem(f, w);
4072 try a.assign(f, writer);4073 try a.assign(f, w);
4073 try f.renderIntCast(writer, inst_scalar_ty, operand, v, scalar_ty, .Other);4074 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .Other);
4074 try a.end(f, writer);4075 try a.end(f, w);
4075 try v.end(f, inst, writer);4076 try v.end(f, inst, w);
4076 return local;4077 return local;
4077}4078}
40784079
...@@ -4099,34 +4100,34 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4099,34 +4100,34 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4099 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);4100 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
4100 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);4101 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
41014102
4102 const writer = f.object.writer();4103 const w = f.object.writer();
4103 const local = try f.allocLocal(inst, inst_ty);4104 const local = try f.allocLocal(inst, inst_ty);
4104 const v = try Vectorize.start(f, inst, writer, operand_ty);4105 const v = try Vectorize.start(f, inst, w, operand_ty);
4105 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));4106 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_scalar_ty, .complete));
4106 try f.writeCValue(writer, local, .Other);4107 try f.writeCValue(w, local, .Other);
4107 try v.elem(f, writer);4108 try v.elem(f, w);
4108 try a.assign(f, writer);4109 try a.assign(f, w);
4109 if (need_cast) {4110 if (need_cast) {
4110 try writer.writeByte('(');4111 try w.writeByte('(');
4111 try f.renderType(writer, inst_scalar_ty);4112 try f.renderType(w, inst_scalar_ty);
4112 try writer.writeByte(')');4113 try w.writeByte(')');
4113 }4114 }
4114 if (need_lo) {4115 if (need_lo) {
4115 try writer.writeAll("zig_lo_");4116 try w.writeAll("zig_lo_");
4116 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4117 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4117 try writer.writeByte('(');4118 try w.writeByte('(');
4118 }4119 }
4119 if (!need_mask) {4120 if (!need_mask) {
4120 try f.writeCValue(writer, operand, .Other);4121 try f.writeCValue(w, operand, .Other);
4121 try v.elem(f, writer);4122 try v.elem(f, w);
4122 } else switch (dest_int_info.signedness) {4123 } else switch (dest_int_info.signedness) {
4123 .unsigned => {4124 .unsigned => {
4124 try writer.writeAll("zig_and_");4125 try w.writeAll("zig_and_");
4125 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4126 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4126 try writer.writeByte('(');4127 try w.writeByte('(');
4127 try f.writeCValue(writer, operand, .FunctionArgument);4128 try f.writeCValue(w, operand, .FunctionArgument);
4128 try v.elem(f, writer);4129 try v.elem(f, w);
4129 try writer.print(", {f})", .{4130 try w.print(", {f})", .{
4130 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),4131 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
4131 });4132 });
4132 },4133 },
...@@ -4135,30 +4136,30 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4135,30 +4136,30 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4135 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});4136 return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{});
4136 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);4137 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
41374138
4138 try writer.writeAll("zig_shr_");4139 try w.writeAll("zig_shr_");
4139 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);4140 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
4140 if (c_bits == 128) {4141 if (c_bits == 128) {
4141 try writer.print("(zig_bitCast_i{d}(", .{c_bits});4142 try w.print("(zig_bitCast_i{d}(", .{c_bits});
4142 } else {4143 } else {
4143 try writer.print("((int{d}_t)", .{c_bits});4144 try w.print("((int{d}_t)", .{c_bits});
4144 }4145 }
4145 try writer.print("zig_shl_u{d}(", .{c_bits});4146 try w.print("zig_shl_u{d}(", .{c_bits});
4146 if (c_bits == 128) {4147 if (c_bits == 128) {
4147 try writer.print("zig_bitCast_u{d}(", .{c_bits});4148 try w.print("zig_bitCast_u{d}(", .{c_bits});
4148 } else {4149 } else {
4149 try writer.print("(uint{d}_t)", .{c_bits});4150 try w.print("(uint{d}_t)", .{c_bits});
4150 }4151 }
4151 try f.writeCValue(writer, operand, .FunctionArgument);4152 try f.writeCValue(w, operand, .FunctionArgument);
4152 try v.elem(f, writer);4153 try v.elem(f, w);
4153 if (c_bits == 128) try writer.writeByte(')');4154 if (c_bits == 128) try w.writeByte(')');
4154 try writer.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});4155 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
4155 if (c_bits == 128) try writer.writeByte(')');4156 if (c_bits == 128) try w.writeByte(')');
4156 try writer.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});4157 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
4157 },4158 },
4158 }4159 }
4159 if (need_lo) try writer.writeByte(')');4160 if (need_lo) try w.writeByte(')');
4160 try a.end(f, writer);4161 try a.end(f, w);
4161 try v.end(f, inst, writer);4162 try v.end(f, inst, w);
4162 return local;4163 return local;
4163}4164}
41644165
...@@ -4180,12 +4181,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4180,12 +4181,12 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4180 if (val_is_undef) {4181 if (val_is_undef) {
4181 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4182 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
4182 if (safety and ptr_info.packed_offset.host_size == 0) {4183 if (safety and ptr_info.packed_offset.host_size == 0) {
4183 const writer = f.object.writer();4184 const w = f.object.writer();
4184 try writer.writeAll("memset(");4185 try w.writeAll("memset(");
4185 try f.writeCValue(writer, ptr_val, .FunctionArgument);4186 try f.writeCValue(w, ptr_val, .FunctionArgument);
4186 try writer.writeAll(", 0xaa, sizeof(");4187 try w.writeAll(", 0xaa, sizeof(");
4187 try f.renderType(writer, .fromInterned(ptr_info.child));4188 try f.renderType(w, .fromInterned(ptr_info.child));
4188 try writer.writeAll("));\n");4189 try w.writeAll("));\n");
4189 }4190 }
4190 return .none;4191 return .none;
4191 }4192 }
...@@ -4201,7 +4202,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4201,7 +4202,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4201 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4202 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
42024203
4203 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);4204 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);
4204 const writer = f.object.writer();4205 const w = f.object.writer();
4205 if (need_memcpy) {4206 if (need_memcpy) {
4206 // For this memcpy to safely work we need the rhs to have the same4207 // For this memcpy to safely work we need the rhs to have the same
4207 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).4208 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
...@@ -4212,28 +4213,28 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4212,28 +4213,28 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4212 // TODO this should be done by manually initializing elements of the dest array4213 // TODO this should be done by manually initializing elements of the dest array
4213 const array_src = if (src_val == .constant) blk: {4214 const array_src = if (src_val == .constant) blk: {
4214 const new_local = try f.allocLocal(inst, src_ty);4215 const new_local = try f.allocLocal(inst, src_ty);
4215 try f.writeCValue(writer, new_local, .Other);4216 try f.writeCValue(w, new_local, .Other);
4216 try writer.writeAll(" = ");4217 try w.writeAll(" = ");
4217 try f.writeCValue(writer, src_val, .Other);4218 try f.writeCValue(w, src_val, .Other);
4218 try writer.writeAll(";\n");4219 try w.writeAll(";\n");
42194220
4220 break :blk new_local;4221 break :blk new_local;
4221 } else src_val;4222 } else src_val;
42224223
4223 const v = try Vectorize.start(f, inst, writer, ptr_ty);4224 const v = try Vectorize.start(f, inst, w, ptr_ty);
4224 try writer.writeAll("memcpy((char *)");4225 try w.writeAll("memcpy((char *)");
4225 try f.writeCValue(writer, ptr_val, .FunctionArgument);4226 try f.writeCValue(w, ptr_val, .FunctionArgument);
4226 try v.elem(f, writer);4227 try v.elem(f, w);
4227 try writer.writeAll(", ");4228 try w.writeAll(", ");
4228 if (!is_array) try writer.writeByte('&');4229 if (!is_array) try w.writeByte('&');
4229 try f.writeCValue(writer, array_src, .FunctionArgument);4230 try f.writeCValue(w, array_src, .FunctionArgument);
4230 try v.elem(f, writer);4231 try v.elem(f, w);
4231 try writer.writeAll(", sizeof(");4232 try w.writeAll(", sizeof(");
4232 try f.renderType(writer, src_ty);4233 try f.renderType(w, src_ty);
4233 try writer.writeAll("))");4234 try w.writeAll("))");
4234 try f.freeCValue(inst, array_src);4235 try f.freeCValue(inst, array_src);
4235 try writer.writeAll(";\n");4236 try w.writeAll(";\n");
4236 try v.end(f, inst, writer);4237 try v.end(f, inst, w);
4237 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {4238 } else if (ptr_info.packed_offset.host_size > 0 and ptr_info.flags.vector_index == .none) {
4238 const host_bits = ptr_info.packed_offset.host_size * 8;4239 const host_bits = ptr_info.packed_offset.host_size * 8;
4239 const host_ty = try pt.intType(.unsigned, host_bits);4240 const host_ty = try pt.intType(.unsigned, host_bits);
...@@ -4256,44 +4257,44 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4256,44 +4257,44 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
42564257
4257 const mask_val = try pt.intValue_big(host_ty, mask.toConst());4258 const mask_val = try pt.intValue_big(host_ty, mask.toConst());
42584259
4259 const v = try Vectorize.start(f, inst, writer, ptr_ty);4260 const v = try Vectorize.start(f, inst, w, ptr_ty);
4260 const a = try Assignment.start(f, writer, src_scalar_ctype);4261 const a = try Assignment.start(f, w, src_scalar_ctype);
4261 try f.writeCValueDeref(writer, ptr_val);4262 try f.writeCValueDeref(w, ptr_val);
4262 try v.elem(f, writer);4263 try v.elem(f, w);
4263 try a.assign(f, writer);4264 try a.assign(f, w);
4264 try writer.writeAll("zig_or_");4265 try w.writeAll("zig_or_");
4265 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4266 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
4266 try writer.writeAll("(zig_and_");4267 try w.writeAll("(zig_and_");
4267 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4268 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
4268 try writer.writeByte('(');4269 try w.writeByte('(');
4269 try f.writeCValueDeref(writer, ptr_val);4270 try f.writeCValueDeref(w, ptr_val);
4270 try v.elem(f, writer);4271 try v.elem(f, w);
4271 try writer.print(", {f}), zig_shl_", .{try f.fmtIntLiteralHex(mask_val)});4272 try w.print(", {f}), zig_shl_", .{try f.fmtIntLiteralHex(mask_val)});
4272 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4273 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
4273 try writer.writeByte('(');4274 try w.writeByte('(');
4274 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;4275 const cant_cast = host_ty.isInt(zcu) and host_ty.bitSize(zcu) > 64;
4275 if (cant_cast) {4276 if (cant_cast) {
4276 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});4277 if (src_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
4277 try writer.writeAll("zig_make_");4278 try w.writeAll("zig_make_");
4278 try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty);4279 try f.object.dg.renderTypeForBuiltinFnName(w, host_ty);
4279 try writer.writeAll("(0, ");4280 try w.writeAll("(0, ");
4280 } else {4281 } else {
4281 try writer.writeByte('(');4282 try w.writeByte('(');
4282 try f.renderType(writer, host_ty);4283 try f.renderType(w, host_ty);
4283 try writer.writeByte(')');4284 try w.writeByte(')');
4284 }4285 }
42854286
4286 if (src_ty.isPtrAtRuntime(zcu)) {4287 if (src_ty.isPtrAtRuntime(zcu)) {
4287 try writer.writeByte('(');4288 try w.writeByte('(');
4288 try f.renderType(writer, .usize);4289 try f.renderType(w, .usize);
4289 try writer.writeByte(')');4290 try w.writeByte(')');
4290 }4291 }
4291 try f.writeCValue(writer, src_val, .Other);4292 try f.writeCValue(w, src_val, .Other);
4292 try v.elem(f, writer);4293 try v.elem(f, w);
4293 if (cant_cast) try writer.writeByte(')');4294 if (cant_cast) try w.writeByte(')');
4294 try writer.print(", {f}))", .{try f.fmtIntLiteralDec(bit_offset_val)});4295 try w.print(", {f}))", .{try f.fmtIntLiteralDec(bit_offset_val)});
4295 try a.end(f, writer);4296 try a.end(f, w);
4296 try v.end(f, inst, writer);4297 try v.end(f, inst, w);
4297 } else {4298 } else {
4298 switch (ptr_val) {4299 switch (ptr_val) {
4299 .local_ref => |ptr_local_index| switch (src_val) {4300 .local_ref => |ptr_local_index| switch (src_val) {
...@@ -4303,15 +4304,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -4303,15 +4304,15 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4303 },4304 },
4304 else => {},4305 else => {},
4305 }4306 }
4306 const v = try Vectorize.start(f, inst, writer, ptr_ty);4307 const v = try Vectorize.start(f, inst, w, ptr_ty);
4307 const a = try Assignment.start(f, writer, src_scalar_ctype);4308 const a = try Assignment.start(f, w, src_scalar_ctype);
4308 try f.writeCValueDeref(writer, ptr_val);4309 try f.writeCValueDeref(w, ptr_val);
4309 try v.elem(f, writer);4310 try v.elem(f, w);
4310 try a.assign(f, writer);4311 try a.assign(f, w);
4311 try f.writeCValue(writer, src_val, .Other);4312 try f.writeCValue(w, src_val, .Other);
4312 try v.elem(f, writer);4313 try v.elem(f, w);
4313 try a.end(f, writer);4314 try a.end(f, w);
4314 try v.end(f, inst, writer);4315 try v.end(f, inst, w);
4315 }4316 }
4316 return .none;4317 return .none;
4317}4318}
...@@ -4368,17 +4369,17 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4368,17 +4369,17 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
43684369
4369 const inst_ty = f.typeOfIndex(inst);4370 const inst_ty = f.typeOfIndex(inst);
43704371
4371 const writer = f.object.writer();4372 const w = f.object.writer();
4372 const local = try f.allocLocal(inst, inst_ty);4373 const local = try f.allocLocal(inst, inst_ty);
4373 const v = try Vectorize.start(f, inst, writer, operand_ty);4374 const v = try Vectorize.start(f, inst, w, operand_ty);
4374 try f.writeCValue(writer, local, .Other);4375 try f.writeCValue(w, local, .Other);
4375 try v.elem(f, writer);4376 try v.elem(f, w);
4376 try writer.writeAll(" = ");4377 try w.writeAll(" = ");
4377 try writer.writeByte('!');4378 try w.writeByte('!');
4378 try f.writeCValue(writer, op, .Other);4379 try f.writeCValue(w, op, .Other);
4379 try v.elem(f, writer);4380 try v.elem(f, w);
4380 try writer.writeAll(";\n");4381 try w.writeAll(";\n");
4381 try v.end(f, inst, writer);4382 try v.end(f, inst, w);
43824383
4383 return local;4384 return local;
4384}4385}
...@@ -4404,21 +4405,21 @@ fn airBinOp(...@@ -4404,21 +4405,21 @@ fn airBinOp(
44044405
4405 const inst_ty = f.typeOfIndex(inst);4406 const inst_ty = f.typeOfIndex(inst);
44064407
4407 const writer = f.object.writer();4408 const w = f.object.writer();
4408 const local = try f.allocLocal(inst, inst_ty);4409 const local = try f.allocLocal(inst, inst_ty);
4409 const v = try Vectorize.start(f, inst, writer, operand_ty);4410 const v = try Vectorize.start(f, inst, w, operand_ty);
4410 try f.writeCValue(writer, local, .Other);4411 try f.writeCValue(w, local, .Other);
4411 try v.elem(f, writer);4412 try v.elem(f, w);
4412 try writer.writeAll(" = ");4413 try w.writeAll(" = ");
4413 try f.writeCValue(writer, lhs, .Other);4414 try f.writeCValue(w, lhs, .Other);
4414 try v.elem(f, writer);4415 try v.elem(f, w);
4415 try writer.writeByte(' ');4416 try w.writeByte(' ');
4416 try writer.writeAll(operator);4417 try w.writeAll(operator);
4417 try writer.writeByte(' ');4418 try w.writeByte(' ');
4418 try f.writeCValue(writer, rhs, .Other);4419 try f.writeCValue(w, rhs, .Other);
4419 try v.elem(f, writer);4420 try v.elem(f, w);
4420 try writer.writeAll(";\n");4421 try w.writeAll(";\n");
4421 try v.end(f, inst, writer);4422 try v.end(f, inst, w);
44224423
4423 return local;4424 return local;
4424}4425}
...@@ -4454,27 +4455,27 @@ fn airCmpOp(...@@ -4454,27 +4455,27 @@ fn airCmpOp(
44544455
4455 const rhs_ty = f.typeOf(data.rhs);4456 const rhs_ty = f.typeOf(data.rhs);
4456 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);4457 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);
4457 const writer = f.object.writer();4458 const w = f.object.writer();
4458 const local = try f.allocLocal(inst, inst_ty);4459 const local = try f.allocLocal(inst, inst_ty);
4459 const v = try Vectorize.start(f, inst, writer, lhs_ty);4460 const v = try Vectorize.start(f, inst, w, lhs_ty);
4460 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));4461 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
4461 try f.writeCValue(writer, local, .Other);4462 try f.writeCValue(w, local, .Other);
4462 try v.elem(f, writer);4463 try v.elem(f, w);
4463 try a.assign(f, writer);4464 try a.assign(f, w);
4464 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {4465 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {
4465 .lt, .neq, .gt => "false",4466 .lt, .neq, .gt => "false",
4466 .lte, .eq, .gte => "true",4467 .lte, .eq, .gte => "true",
4467 }) else {4468 }) else {
4468 if (need_cast) try writer.writeAll("(void*)");4469 if (need_cast) try w.writeAll("(void*)");
4469 try f.writeCValue(writer, lhs, .Other);4470 try f.writeCValue(w, lhs, .Other);
4470 try v.elem(f, writer);4471 try v.elem(f, w);
4471 try writer.writeAll(compareOperatorC(operator));4472 try w.writeAll(compareOperatorC(operator));
4472 if (need_cast) try writer.writeAll("(void*)");4473 if (need_cast) try w.writeAll("(void*)");
4473 try f.writeCValue(writer, rhs, .Other);4474 try f.writeCValue(w, rhs, .Other);
4474 try v.elem(f, writer);4475 try v.elem(f, w);
4475 }4476 }
4476 try a.end(f, writer);4477 try a.end(f, w);
4477 try v.end(f, inst, writer);4478 try v.end(f, inst, w);
44784479
4479 return local;4480 return local;
4480}4481}
...@@ -4507,41 +4508,41 @@ fn airEquality(...@@ -4507,41 +4508,41 @@ fn airEquality(
4507 const rhs = try f.resolveInst(bin_op.rhs);4508 const rhs = try f.resolveInst(bin_op.rhs);
4508 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4509 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
45094510
4510 const writer = f.object.writer();4511 const w = f.object.writer();
4511 const local = try f.allocLocal(inst, .bool);4512 const local = try f.allocLocal(inst, .bool);
4512 const a = try Assignment.start(f, writer, .bool);4513 const a = try Assignment.start(f, w, .bool);
4513 try f.writeCValue(writer, local, .Other);4514 try f.writeCValue(w, local, .Other);
4514 try a.assign(f, writer);4515 try a.assign(f, w);
45154516
4516 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);4517 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
4517 if (lhs != .undef and lhs.eql(rhs)) try writer.writeAll(switch (operator) {4518 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {
4518 .lt, .lte, .gte, .gt => unreachable,4519 .lt, .lte, .gte, .gt => unreachable,
4519 .neq => "false",4520 .neq => "false",
4520 .eq => "true",4521 .eq => "true",
4521 }) else switch (operand_ctype.info(ctype_pool)) {4522 }) else switch (operand_ctype.info(ctype_pool)) {
4522 .basic, .pointer => {4523 .basic, .pointer => {
4523 try f.writeCValue(writer, lhs, .Other);4524 try f.writeCValue(w, lhs, .Other);
4524 try writer.writeAll(compareOperatorC(operator));4525 try w.writeAll(compareOperatorC(operator));
4525 try f.writeCValue(writer, rhs, .Other);4526 try f.writeCValue(w, rhs, .Other);
4526 },4527 },
4527 .aligned, .array, .vector, .fwd_decl, .function => unreachable,4528 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
4528 .aggregate => |aggregate| if (aggregate.fields.len == 2 and4529 .aggregate => |aggregate| if (aggregate.fields.len == 2 and
4529 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or4530 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
4530 aggregate.fields.at(1, ctype_pool).name.index == .is_null))4531 aggregate.fields.at(1, ctype_pool).name.index == .is_null))
4531 {4532 {
4532 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });4533 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4533 try writer.writeAll(" || ");4534 try w.writeAll(" || ");
4534 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });4535 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4535 try writer.writeAll(" ? ");4536 try w.writeAll(" ? ");
4536 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });4537 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4537 try writer.writeAll(compareOperatorC(operator));4538 try w.writeAll(compareOperatorC(operator));
4538 try f.writeCValueMember(writer, rhs, .{ .identifier = "is_null" });4539 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4539 try writer.writeAll(" : ");4540 try w.writeAll(" : ");
4540 try f.writeCValueMember(writer, lhs, .{ .identifier = "payload" });4541 try f.writeCValueMember(w, lhs, .{ .identifier = "payload" });
4541 try writer.writeAll(compareOperatorC(operator));4542 try w.writeAll(compareOperatorC(operator));
4542 try f.writeCValueMember(writer, rhs, .{ .identifier = "payload" });4543 try f.writeCValueMember(w, rhs, .{ .identifier = "payload" });
4543 } else for (0..aggregate.fields.len) |field_index| {4544 } else for (0..aggregate.fields.len) |field_index| {
4544 if (field_index > 0) try writer.writeAll(switch (operator) {4545 if (field_index > 0) try w.writeAll(switch (operator) {
4545 .lt, .lte, .gte, .gt => unreachable,4546 .lt, .lte, .gte, .gt => unreachable,
4546 .eq => " && ",4547 .eq => " && ",
4547 .neq => " || ",4548 .neq => " || ",
...@@ -4549,12 +4550,12 @@ fn airEquality(...@@ -4549,12 +4550,12 @@ fn airEquality(
4549 const field_name: CValue = .{4550 const field_name: CValue = .{
4550 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,4551 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,
4551 };4552 };
4552 try f.writeCValueMember(writer, lhs, field_name);4553 try f.writeCValueMember(w, lhs, field_name);
4553 try writer.writeAll(compareOperatorC(operator));4554 try w.writeAll(compareOperatorC(operator));
4554 try f.writeCValueMember(writer, rhs, field_name);4555 try f.writeCValueMember(w, rhs, field_name);
4555 },4556 },
4556 }4557 }
4557 try a.end(f, writer);4558 try a.end(f, w);
45584559
4559 return local;4560 return local;
4560}4561}
...@@ -4565,12 +4566,12 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4565,12 +4566,12 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
4565 const operand = try f.resolveInst(un_op);4566 const operand = try f.resolveInst(un_op);
4566 try reap(f, inst, &.{un_op});4567 try reap(f, inst, &.{un_op});
45674568
4568 const writer = f.object.writer();4569 const w = f.object.writer();
4569 const local = try f.allocLocal(inst, .bool);4570 const local = try f.allocLocal(inst, .bool);
4570 try f.writeCValue(writer, local, .Other);4571 try f.writeCValue(w, local, .Other);
4571 try writer.writeAll(" = ");4572 try w.writeAll(" = ");
4572 try f.writeCValue(writer, operand, .Other);4573 try f.writeCValue(w, operand, .Other);
4573 try writer.print(" < sizeof({f}) / sizeof(*{0f});\n", .{fmtIdentSolo("zig_errorName")});4574 try w.print(" < sizeof({f}) / sizeof(*{0f});\n", .{fmtIdentSolo("zig_errorName")});
4574 return local;4575 return local;
4575}4576}
45764577
...@@ -4591,30 +4592,30 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {...@@ -4591,30 +4592,30 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4591 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);4592 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
45924593
4593 const local = try f.allocLocal(inst, inst_ty);4594 const local = try f.allocLocal(inst, inst_ty);
4594 const writer = f.object.writer();4595 const w = f.object.writer();
4595 const v = try Vectorize.start(f, inst, writer, inst_ty);4596 const v = try Vectorize.start(f, inst, w, inst_ty);
4596 const a = try Assignment.start(f, writer, inst_scalar_ctype);4597 const a = try Assignment.start(f, w, inst_scalar_ctype);
4597 try f.writeCValue(writer, local, .Other);4598 try f.writeCValue(w, local, .Other);
4598 try v.elem(f, writer);4599 try v.elem(f, w);
4599 try a.assign(f, writer);4600 try a.assign(f, w);
4600 // We must convert to and from integer types to prevent UB if the operation4601 // We must convert to and from integer types to prevent UB if the operation
4601 // results in a NULL pointer, or if LHS is NULL. The operation is only UB4602 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
4602 // if the result is NULL and then dereferenced.4603 // if the result is NULL and then dereferenced.
4603 try writer.writeByte('(');4604 try w.writeByte('(');
4604 try f.renderCType(writer, inst_scalar_ctype);4605 try f.renderCType(w, inst_scalar_ctype);
4605 try writer.writeAll(")(((uintptr_t)");4606 try w.writeAll(")(((uintptr_t)");
4606 try f.writeCValue(writer, lhs, .Other);4607 try f.writeCValue(w, lhs, .Other);
4607 try v.elem(f, writer);4608 try v.elem(f, w);
4608 try writer.writeAll(") ");4609 try w.writeAll(") ");
4609 try writer.writeByte(operator);4610 try w.writeByte(operator);
4610 try writer.writeAll(" (");4611 try w.writeAll(" (");
4611 try f.writeCValue(writer, rhs, .Other);4612 try f.writeCValue(w, rhs, .Other);
4612 try v.elem(f, writer);4613 try v.elem(f, w);
4613 try writer.writeAll("*sizeof(");4614 try w.writeAll("*sizeof(");
4614 try f.renderType(writer, elem_ty);4615 try f.renderType(w, elem_ty);
4615 try writer.writeAll(")))");4616 try w.writeAll(")))");
4616 try a.end(f, writer);4617 try a.end(f, w);
4617 try v.end(f, inst, writer);4618 try v.end(f, inst, w);
4618 return local;4619 return local;
4619}4620}
46204621
...@@ -4633,28 +4634,28 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons...@@ -4633,28 +4634,28 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
4633 const rhs = try f.resolveInst(bin_op.rhs);4634 const rhs = try f.resolveInst(bin_op.rhs);
4634 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });4635 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
46354636
4636 const writer = f.object.writer();4637 const w = f.object.writer();
4637 const local = try f.allocLocal(inst, inst_ty);4638 const local = try f.allocLocal(inst, inst_ty);
4638 const v = try Vectorize.start(f, inst, writer, inst_ty);4639 const v = try Vectorize.start(f, inst, w, inst_ty);
4639 try f.writeCValue(writer, local, .Other);4640 try f.writeCValue(w, local, .Other);
4640 try v.elem(f, writer);4641 try v.elem(f, w);
4641 // (lhs <> rhs) ? lhs : rhs4642 // (lhs <> rhs) ? lhs : rhs
4642 try writer.writeAll(" = (");4643 try w.writeAll(" = (");
4643 try f.writeCValue(writer, lhs, .Other);4644 try f.writeCValue(w, lhs, .Other);
4644 try v.elem(f, writer);4645 try v.elem(f, w);
4645 try writer.writeByte(' ');4646 try w.writeByte(' ');
4646 try writer.writeByte(operator);4647 try w.writeByte(operator);
4647 try writer.writeByte(' ');4648 try w.writeByte(' ');
4648 try f.writeCValue(writer, rhs, .Other);4649 try f.writeCValue(w, rhs, .Other);
4649 try v.elem(f, writer);4650 try v.elem(f, w);
4650 try writer.writeAll(") ? ");4651 try w.writeAll(") ? ");
4651 try f.writeCValue(writer, lhs, .Other);4652 try f.writeCValue(w, lhs, .Other);
4652 try v.elem(f, writer);4653 try v.elem(f, w);
4653 try writer.writeAll(" : ");4654 try w.writeAll(" : ");
4654 try f.writeCValue(writer, rhs, .Other);4655 try f.writeCValue(w, rhs, .Other);
4655 try v.elem(f, writer);4656 try v.elem(f, w);
4656 try writer.writeAll(";\n");4657 try w.writeAll(";\n");
4657 try v.end(f, inst, writer);4658 try v.end(f, inst, w);
46584659
4659 return local;4660 return local;
4660}4661}
...@@ -4672,21 +4673,21 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4672,21 +4673,21 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4672 const inst_ty = f.typeOfIndex(inst);4673 const inst_ty = f.typeOfIndex(inst);
4673 const ptr_ty = inst_ty.slicePtrFieldType(zcu);4674 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
46744675
4675 const writer = f.object.writer();4676 const w = f.object.writer();
4676 const local = try f.allocLocal(inst, inst_ty);4677 const local = try f.allocLocal(inst, inst_ty);
4677 {4678 {
4678 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));4679 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));
4679 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });4680 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
4680 try a.assign(f, writer);4681 try a.assign(f, w);
4681 try f.writeCValue(writer, ptr, .Other);4682 try f.writeCValue(w, ptr, .Other);
4682 try a.end(f, writer);4683 try a.end(f, w);
4683 }4684 }
4684 {4685 {
4685 const a = try Assignment.start(f, writer, .usize);4686 const a = try Assignment.start(f, w, .usize);
4686 try f.writeCValueMember(writer, local, .{ .identifier = "len" });4687 try f.writeCValueMember(w, local, .{ .identifier = "len" });
4687 try a.assign(f, writer);4688 try a.assign(f, w);
4688 try f.writeCValue(writer, len, .Other);4689 try f.writeCValue(w, len, .Other);
4689 try a.end(f, writer);4690 try a.end(f, w);
4690 }4691 }
4691 return local;4692 return local;
4692}4693}
...@@ -4703,7 +4704,7 @@ fn airCall(...@@ -4703,7 +4704,7 @@ fn airCall(
4703 if (f.object.dg.is_naked_fn) return .none;4704 if (f.object.dg.is_naked_fn) return .none;
47044705
4705 const gpa = f.object.dg.gpa;4706 const gpa = f.object.dg.gpa;
4706 const writer = f.object.writer();4707 const w = f.object.writer();
47074708
4708 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;4709 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
4709 const extra = f.air.extraData(Air.Call, pl_op.payload);4710 const extra = f.air.extraData(Air.Call, pl_op.payload);
...@@ -4724,13 +4725,13 @@ fn airCall(...@@ -4724,13 +4725,13 @@ fn airCall(
4724 .ctype = arg_ctype,4725 .ctype = arg_ctype,
4725 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),4726 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),
4726 });4727 });
4727 try writer.writeAll("memcpy(");4728 try w.writeAll("memcpy(");
4728 try f.writeCValueMember(writer, array_local, .{ .identifier = "array" });4729 try f.writeCValueMember(w, array_local, .{ .identifier = "array" });
4729 try writer.writeAll(", ");4730 try w.writeAll(", ");
4730 try f.writeCValue(writer, resolved_arg.*, .FunctionArgument);4731 try f.writeCValue(w, resolved_arg.*, .FunctionArgument);
4731 try writer.writeAll(", sizeof(");4732 try w.writeAll(", sizeof(");
4732 try f.renderCType(writer, arg_ctype);4733 try f.renderCType(w, arg_ctype);
4733 try writer.writeAll("));\n");4734 try w.writeAll("));\n");
4734 resolved_arg.* = array_local;4735 resolved_arg.* = array_local;
4735 }4736 }
4736 }4737 }
...@@ -4758,22 +4759,22 @@ fn airCall(...@@ -4758,22 +4759,22 @@ fn airCall(
47584759
4759 const result_local = result: {4760 const result_local = result: {
4760 if (modifier == .always_tail) {4761 if (modifier == .always_tail) {
4761 try writer.writeAll("zig_always_tail return ");4762 try w.writeAll("zig_always_tail return ");
4762 break :result .none;4763 break :result .none;
4763 } else if (ret_ctype.index == .void) {4764 } else if (ret_ctype.index == .void) {
4764 break :result .none;4765 break :result .none;
4765 } else if (f.liveness.isUnused(inst)) {4766 } else if (f.liveness.isUnused(inst)) {
4766 try writer.writeByte('(');4767 try w.writeByte('(');
4767 try f.renderCType(writer, .void);4768 try f.renderCType(w, .void);
4768 try writer.writeByte(')');4769 try w.writeByte(')');
4769 break :result .none;4770 break :result .none;
4770 } else {4771 } else {
4771 const local = try f.allocAlignedLocal(inst, .{4772 const local = try f.allocAlignedLocal(inst, .{
4772 .ctype = ret_ctype,4773 .ctype = ret_ctype,
4773 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),4774 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
4774 });4775 });
4775 try f.writeCValue(writer, local, .Other);4776 try f.writeCValue(w, local, .Other);
4776 try writer.writeAll(" = ");4777 try w.writeAll(" = ");
4777 break :result local;4778 break :result local;
4778 }4779 }
4779 };4780 };
...@@ -4793,17 +4794,17 @@ fn airCall(...@@ -4793,17 +4794,17 @@ fn airCall(
4793 else => break :known,4794 else => break :known,
4794 };4795 };
4795 if (need_cast) {4796 if (need_cast) {
4796 try writer.writeAll("((");4797 try w.writeAll("((");
4797 try f.renderType(writer, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));4798 try f.renderType(w, if (callee_is_ptr) callee_ty else try pt.singleConstPtrType(callee_ty));
4798 try writer.writeByte(')');4799 try w.writeByte(')');
4799 if (!callee_is_ptr) try writer.writeByte('&');4800 if (!callee_is_ptr) try w.writeByte('&');
4800 }4801 }
4801 switch (modifier) {4802 switch (modifier) {
4802 .auto, .always_tail => try f.object.dg.renderNavName(writer, fn_nav),4803 .auto, .always_tail => try f.object.dg.renderNavName(w, fn_nav),
4803 inline .never_tail, .never_inline => |m| try writer.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),4804 inline .never_tail, .never_inline => |m| try w.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
4804 else => unreachable,4805 else => unreachable,
4805 }4806 }
4806 if (need_cast) try writer.writeByte(')');4807 if (need_cast) try w.writeByte(')');
4807 break :callee;4808 break :callee;
4808 }4809 }
4809 switch (modifier) {4810 switch (modifier) {
...@@ -4813,32 +4814,32 @@ fn airCall(...@@ -4813,32 +4814,32 @@ fn airCall(
4813 else => unreachable,4814 else => unreachable,
4814 }4815 }
4815 // Fall back to function pointer call.4816 // Fall back to function pointer call.
4816 try f.writeCValue(writer, callee, .Other);4817 try f.writeCValue(w, callee, .Other);
4817 }4818 }
48184819
4819 try writer.writeByte('(');4820 try w.writeByte('(');
4820 var need_comma = false;4821 var need_comma = false;
4821 for (resolved_args) |resolved_arg| {4822 for (resolved_args) |resolved_arg| {
4822 if (resolved_arg == .none) continue;4823 if (resolved_arg == .none) continue;
4823 if (need_comma) try writer.writeAll(", ");4824 if (need_comma) try w.writeAll(", ");
4824 need_comma = true;4825 need_comma = true;
4825 try f.writeCValue(writer, resolved_arg, .FunctionArgument);4826 try f.writeCValue(w, resolved_arg, .FunctionArgument);
4826 try f.freeCValue(inst, resolved_arg);4827 try f.freeCValue(inst, resolved_arg);
4827 }4828 }
4828 try writer.writeAll(");\n");4829 try w.writeAll(");\n");
48294830
4830 const result = result: {4831 const result = result: {
4831 if (result_local == .none or !lowersToArray(ret_ty, pt))4832 if (result_local == .none or !lowersToArray(ret_ty, pt))
4832 break :result result_local;4833 break :result result_local;
48334834
4834 const array_local = try f.allocLocal(inst, ret_ty);4835 const array_local = try f.allocLocal(inst, ret_ty);
4835 try writer.writeAll("memcpy(");4836 try w.writeAll("memcpy(");
4836 try f.writeCValue(writer, array_local, .FunctionArgument);4837 try f.writeCValue(w, array_local, .FunctionArgument);
4837 try writer.writeAll(", ");4838 try w.writeAll(", ");
4838 try f.writeCValueMember(writer, result_local, .{ .identifier = "array" });4839 try f.writeCValueMember(w, result_local, .{ .identifier = "array" });
4839 try writer.writeAll(", sizeof(");4840 try w.writeAll(", sizeof(");
4840 try f.renderType(writer, ret_ty);4841 try f.renderType(w, ret_ty);
4841 try writer.writeAll("));\n");4842 try w.writeAll("));\n");
4842 try freeLocal(f, inst, result_local.new_local, null);4843 try freeLocal(f, inst, result_local.new_local, null);
4843 break :result array_local;4844 break :result array_local;
4844 };4845 };
...@@ -4848,7 +4849,7 @@ fn airCall(...@@ -4848,7 +4849,7 @@ fn airCall(
48484849
4849fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {4850fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4850 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;4851 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
4851 const writer = f.object.writer();4852 const w = f.object.writer();
4852 // TODO re-evaluate whether to emit these or not. If we naively emit4853 // TODO re-evaluate whether to emit these or not. If we naively emit
4853 // these directives, the output file will report bogus line numbers because4854 // these directives, the output file will report bogus line numbers because
4854 // every newline after the #line directive adds one to the line.4855 // every newline after the #line directive adds one to the line.
...@@ -4856,8 +4857,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4856,8 +4857,8 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
4856 // If we wanted to go this route, we would need to go all the way and not output4857 // If we wanted to go this route, we would need to go all the way and not output
4857 // newlines until the next dbg_stmt occurs.4858 // newlines until the next dbg_stmt occurs.
4858 // Perhaps an additional compilation option is in order?4859 // Perhaps an additional compilation option is in order?
4859 //try writer.print("#line {d}\n", .{dbg_stmt.line + 1});4860 //try w.print("#line {d}\n", .{dbg_stmt.line + 1});
4860 try writer.print("/* file:{d}:{d} */\n", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });4861 try w.print("/* file:{d}:{d} */\n", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4861 return .none;4862 return .none;
4862}4863}
48634864
...@@ -4873,8 +4874,8 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4873,8 +4874,8 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4873 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;4874 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
4874 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4875 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4875 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);4876 const owner_nav = ip.getNav(zcu.funcInfo(extra.data.func).owner_nav);
4876 const writer = f.object.writer();4877 const w = f.object.writer();
4877 try writer.print("/* inline:{} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)});4878 try w.print("/* inline:{} */\n", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
4878 return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]));4879 return lowerBlock(f, inst, @ptrCast(f.air.extra.items[extra.end..][0..extra.data.body_len]));
4879}4880}
48804881
...@@ -4888,8 +4889,8 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4888,8 +4889,8 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4888 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);4889 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
48894890
4890 try reap(f, inst, &.{pl_op.operand});4891 try reap(f, inst, &.{pl_op.operand});
4891 const writer = f.object.writer();4892 const w = f.object.writer();
4892 try writer.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) });4893 try w.print("/* {s}:{s} */\n", .{ @tagName(tag), name.toSlice(f.air) });
4893 return .none;4894 return .none;
4894}4895}
48954896
...@@ -4906,7 +4907,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4906,7 +4907,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
49064907
4907 const block_id = f.next_block_index;4908 const block_id = f.next_block_index;
4908 f.next_block_index += 1;4909 f.next_block_index += 1;
4909 const writer = f.object.writer();4910 const w = f.object.writer();
49104911
4911 const inst_ty = f.typeOfIndex(inst);4912 const inst_ty = f.typeOfIndex(inst);
4912 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))4913 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))
...@@ -4939,7 +4940,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)...@@ -4939,7 +4940,7 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
4939 }4940 }
4940 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {4941 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
4941 // label must be followed by an expression, include an empty one.4942 // label must be followed by an expression, include an empty one.
4942 try writer.print("zig_block_{d}:;\n", .{block_id});4943 try w.print("zig_block_{d}:;\n", .{block_id});
4943 }4944 }
49444945
4945 return result;4946 return result;
...@@ -4976,28 +4977,28 @@ fn lowerTry(...@@ -4976,28 +4977,28 @@ fn lowerTry(
4976 const err_union = try f.resolveInst(operand);4977 const err_union = try f.resolveInst(operand);
4977 const inst_ty = f.typeOfIndex(inst);4978 const inst_ty = f.typeOfIndex(inst);
4978 const liveness_condbr = f.liveness.getCondBr(inst);4979 const liveness_condbr = f.liveness.getCondBr(inst);
4979 const writer = f.object.writer();4980 const w = f.object.writer();
4980 const payload_ty = err_union_ty.errorUnionPayload(zcu);4981 const payload_ty = err_union_ty.errorUnionPayload(zcu);
4981 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);4982 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
49824983
4983 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {4984 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4984 try writer.writeAll("if (");4985 try w.writeAll("if (");
4985 if (!payload_has_bits) {4986 if (!payload_has_bits) {
4986 if (is_ptr)4987 if (is_ptr)
4987 try f.writeCValueDeref(writer, err_union)4988 try f.writeCValueDeref(w, err_union)
4988 else4989 else
4989 try f.writeCValue(writer, err_union, .Other);4990 try f.writeCValue(w, err_union, .Other);
4990 } else {4991 } else {
4991 // Reap the operand so that it can be reused inside genBody.4992 // Reap the operand so that it can be reused inside genBody.
4992 // Remember we must avoid calling reap() twice for the same operand4993 // Remember we must avoid calling reap() twice for the same operand
4993 // in this function.4994 // in this function.
4994 try reap(f, inst, &.{operand});4995 try reap(f, inst, &.{operand});
4995 if (is_ptr)4996 if (is_ptr)
4996 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" })4997 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "error" })
4997 else4998 else
4998 try f.writeCValueMember(writer, err_union, .{ .identifier = "error" });4999 try f.writeCValueMember(w, err_union, .{ .identifier = "error" });
4999 }5000 }
5000 try writer.writeAll(") ");5001 try w.writeAll(") ");
50015002
5002 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);5003 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);
5003 try f.object.indent_writer.insertNewline();5004 try f.object.indent_writer.insertNewline();
...@@ -5023,14 +5024,14 @@ fn lowerTry(...@@ -5023,14 +5024,14 @@ fn lowerTry(
5023 if (f.liveness.isUnused(inst)) return .none;5024 if (f.liveness.isUnused(inst)) return .none;
50245025
5025 const local = try f.allocLocal(inst, inst_ty);5026 const local = try f.allocLocal(inst, inst_ty);
5026 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));5027 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
5027 try f.writeCValue(writer, local, .Other);5028 try f.writeCValue(w, local, .Other);
5028 try a.assign(f, writer);5029 try a.assign(f, w);
5029 if (is_ptr) {5030 if (is_ptr) {
5030 try writer.writeByte('&');5031 try w.writeByte('&');
5031 try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" });5032 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "payload" });
5032 } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" });5033 } else try f.writeCValueMember(w, err_union, .{ .identifier = "payload" });
5033 try a.end(f, writer);5034 try a.end(f, w);
5034 return local;5035 return local;
5035}5036}
50365037
...@@ -5038,7 +5039,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5038,7 +5039,7 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
5038 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;5039 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
5039 const block = f.blocks.get(branch.block_inst).?;5040 const block = f.blocks.get(branch.block_inst).?;
5040 const result = block.result;5041 const result = block.result;
5041 const writer = f.object.writer();5042 const w = f.object.writer();
50425043
5043 if (f.object.dg.is_naked_fn) {5044 if (f.object.dg.is_naked_fn) {
5044 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});5045 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});
...@@ -5052,27 +5053,27 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5052,27 +5053,27 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
5052 const operand = try f.resolveInst(branch.operand);5053 const operand = try f.resolveInst(branch.operand);
5053 try reap(f, inst, &.{branch.operand});5054 try reap(f, inst, &.{branch.operand});
50545055
5055 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));5056 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));
5056 try f.writeCValue(writer, result, .Other);5057 try f.writeCValue(w, result, .Other);
5057 try a.assign(f, writer);5058 try a.assign(f, w);
5058 try f.writeCValue(writer, operand, .Other);5059 try f.writeCValue(w, operand, .Other);
5059 try a.end(f, writer);5060 try a.end(f, w);
5060 }5061 }
50615062
5062 try writer.print("goto zig_block_{d};\n", .{block.block_id});5063 try w.print("goto zig_block_{d};\n", .{block.block_id});
5063}5064}
50645065
5065fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {5066fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {
5066 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;5067 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
5067 const writer = f.object.writer();5068 const w = f.object.writer();
5068 try writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});5069 try w.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});
5069}5070}
50705071
5071fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {5072fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
5072 const pt = f.object.dg.pt;5073 const pt = f.object.dg.pt;
5073 const zcu = pt.zcu;5074 const zcu = pt.zcu;
5074 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;5075 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
5075 const writer = f.object.writer();5076 const w = f.object.writer();
50765077
5077 if (try f.air.value(br.operand, pt)) |cond_val| {5078 if (try f.air.value(br.operand, pt)) |cond_val| {
5078 // Comptime-known dispatch. Iterate the cases to find the correct5079 // Comptime-known dispatch. Iterate the cases to find the correct
...@@ -5094,18 +5095,18 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {...@@ -5094,18 +5095,18 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
5094 }5095 }
5095 }5096 }
5096 } else switch_br.cases_len;5097 } else switch_br.cases_len;
5097 try writer.print("goto zig_switch_{d}_dispatch_{d};\n", .{ @intFromEnum(br.block_inst), target_case_idx });5098 try w.print("goto zig_switch_{d}_dispatch_{d};\n", .{ @intFromEnum(br.block_inst), target_case_idx });
5098 return;5099 return;
5099 }5100 }
51005101
5101 // Runtime-known dispatch. Set the switch condition, and branch back.5102 // Runtime-known dispatch. Set the switch condition, and branch back.
5102 const cond = try f.resolveInst(br.operand);5103 const cond = try f.resolveInst(br.operand);
5103 const cond_local = f.loop_switch_conds.get(br.block_inst).?;5104 const cond_local = f.loop_switch_conds.get(br.block_inst).?;
5104 try f.writeCValue(writer, .{ .local = cond_local }, .Other);5105 try f.writeCValue(w, .{ .local = cond_local }, .Other);
5105 try writer.writeAll(" = ");5106 try w.writeAll(" = ");
5106 try f.writeCValue(writer, cond, .Other);5107 try f.writeCValue(w, cond, .Other);
5107 try writer.writeAll(";\n");5108 try w.writeAll(";\n");
5108 try writer.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});5109 try w.print("goto zig_switch_{d}_loop;", .{@intFromEnum(br.block_inst)});
5109}5110}
51105111
5111fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {5112fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
...@@ -5125,7 +5126,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5125,7 +5126,7 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5125 const zcu = pt.zcu;5126 const zcu = pt.zcu;
5126 const target = &f.object.dg.mod.resolved_target.result;5127 const target = &f.object.dg.mod.resolved_target.result;
5127 const ctype_pool = &f.object.dg.ctype_pool;5128 const ctype_pool = &f.object.dg.ctype_pool;
5128 const writer = f.object.writer();5129 const w = f.object.writer();
51295130
5130 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {5131 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
5131 const src_info = dest_ty.intInfo(zcu);5132 const src_info = dest_ty.intInfo(zcu);
...@@ -5136,35 +5137,35 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5136,35 +5137,35 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
51365137
5137 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {5138 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {
5138 const local = try f.allocLocal(null, dest_ty);5139 const local = try f.allocLocal(null, dest_ty);
5139 try f.writeCValue(writer, local, .Other);5140 try f.writeCValue(w, local, .Other);
5140 try writer.writeAll(" = (");5141 try w.writeAll(" = (");
5141 try f.renderType(writer, dest_ty);5142 try f.renderType(w, dest_ty);
5142 try writer.writeByte(')');5143 try w.writeByte(')');
5143 try f.writeCValue(writer, operand, .Other);5144 try f.writeCValue(w, operand, .Other);
5144 try writer.writeAll(";\n");5145 try w.writeAll(";\n");
5145 return local;5146 return local;
5146 }5147 }
51475148
5148 const operand_lval = if (operand == .constant) blk: {5149 const operand_lval = if (operand == .constant) blk: {
5149 const operand_local = try f.allocLocal(null, operand_ty);5150 const operand_local = try f.allocLocal(null, operand_ty);
5150 try f.writeCValue(writer, operand_local, .Other);5151 try f.writeCValue(w, operand_local, .Other);
5151 try writer.writeAll(" = ");5152 try w.writeAll(" = ");
5152 try f.writeCValue(writer, operand, .Other);5153 try f.writeCValue(w, operand, .Other);
5153 try writer.writeAll(";\n");5154 try w.writeAll(";\n");
5154 break :blk operand_local;5155 break :blk operand_local;
5155 } else operand;5156 } else operand;
51565157
5157 const local = try f.allocLocal(null, dest_ty);5158 const local = try f.allocLocal(null, dest_ty);
5158 try writer.writeAll("memcpy(&");5159 try w.writeAll("memcpy(&");
5159 try f.writeCValue(writer, local, .Other);5160 try f.writeCValue(w, local, .Other);
5160 try writer.writeAll(", &");5161 try w.writeAll(", &");
5161 try f.writeCValue(writer, operand_lval, .Other);5162 try f.writeCValue(w, operand_lval, .Other);
5162 try writer.writeAll(", sizeof(");5163 try w.writeAll(", sizeof(");
5163 try f.renderType(5164 try f.renderType(
5164 writer,5165 w,
5165 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,5166 if (dest_ty.abiSize(zcu) <= operand_ty.abiSize(zcu)) dest_ty else operand_ty,
5166 );5167 );
5167 try writer.writeAll("));\n");5168 try w.writeAll("));\n");
51685169
5169 // Ensure padding bits have the expected value.5170 // Ensure padding bits have the expected value.
5170 if (dest_ty.isAbiInt(zcu)) {5171 if (dest_ty.isAbiInt(zcu)) {
...@@ -5174,11 +5175,11 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5174,11 +5175,11 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5174 var wrap_ctype: ?CType = null;5175 var wrap_ctype: ?CType = null;
5175 var need_bitcasts = false;5176 var need_bitcasts = false;
51765177
5177 try f.writeCValue(writer, local, .Other);5178 try f.writeCValue(w, local, .Other);
5178 switch (dest_ctype.info(ctype_pool)) {5179 switch (dest_ctype.info(ctype_pool)) {
5179 else => {},5180 else => {},
5180 .array => |array_info| {5181 .array => |array_info| {
5181 try writer.print("[{d}]", .{switch (target.cpu.arch.endian()) {5182 try w.print("[{d}]", .{switch (target.cpu.arch.endian()) {
5182 .little => array_info.len - 1,5183 .little => array_info.len - 1,
5183 .big => 0,5184 .big => 0,
5184 }});5185 }});
...@@ -5189,72 +5190,72 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal...@@ -5189,72 +5190,72 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
5189 bits += 1;5190 bits += 1;
5190 },5191 },
5191 }5192 }
5192 try writer.writeAll(" = ");5193 try w.writeAll(" = ");
5193 if (need_bitcasts) {5194 if (need_bitcasts) {
5194 try writer.writeAll("zig_bitCast_");5195 try w.writeAll("zig_bitCast_");
5195 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?.toUnsigned());5196 try f.object.dg.renderCTypeForBuiltinFnName(w, wrap_ctype.?.toUnsigned());
5196 try writer.writeByte('(');5197 try w.writeByte('(');
5197 }5198 }
5198 try writer.writeAll("zig_wrap_");5199 try w.writeAll("zig_wrap_");
5199 const info_ty = try pt.intType(dest_info.signedness, bits);5200 const info_ty = try pt.intType(dest_info.signedness, bits);
5200 if (wrap_ctype) |ctype|5201 if (wrap_ctype) |ctype|
5201 try f.object.dg.renderCTypeForBuiltinFnName(writer, ctype)5202 try f.object.dg.renderCTypeForBuiltinFnName(w, ctype)
5202 else5203 else
5203 try f.object.dg.renderTypeForBuiltinFnName(writer, info_ty);5204 try f.object.dg.renderTypeForBuiltinFnName(w, info_ty);
5204 try writer.writeByte('(');5205 try w.writeByte('(');
5205 if (need_bitcasts) {5206 if (need_bitcasts) {
5206 try writer.writeAll("zig_bitCast_");5207 try w.writeAll("zig_bitCast_");
5207 try f.object.dg.renderCTypeForBuiltinFnName(writer, wrap_ctype.?);5208 try f.object.dg.renderCTypeForBuiltinFnName(w, wrap_ctype.?);
5208 try writer.writeByte('(');5209 try w.writeByte('(');
5209 }5210 }
5210 try f.writeCValue(writer, local, .Other);5211 try f.writeCValue(w, local, .Other);
5211 switch (dest_ctype.info(ctype_pool)) {5212 switch (dest_ctype.info(ctype_pool)) {
5212 else => {},5213 else => {},
5213 .array => |array_info| try writer.print("[{d}]", .{5214 .array => |array_info| try w.print("[{d}]", .{
5214 switch (target.cpu.arch.endian()) {5215 switch (target.cpu.arch.endian()) {
5215 .little => array_info.len - 1,5216 .little => array_info.len - 1,
5216 .big => 0,5217 .big => 0,
5217 },5218 },
5218 }),5219 }),
5219 }5220 }
5220 if (need_bitcasts) try writer.writeByte(')');5221 if (need_bitcasts) try w.writeByte(')');
5221 try f.object.dg.renderBuiltinInfo(writer, info_ty, .bits);5222 try f.object.dg.renderBuiltinInfo(w, info_ty, .bits);
5222 if (need_bitcasts) try writer.writeByte(')');5223 if (need_bitcasts) try w.writeByte(')');
5223 try writer.writeAll(");\n");5224 try w.writeAll(");\n");
5224 }5225 }
52255226
5226 try f.freeCValue(null, operand_lval);5227 try f.freeCValue(null, operand_lval);
5227 return local;5228 return local;
5228}5229}
52295230
5230fn airTrap(f: *Function, writer: anytype) !void {5231fn airTrap(f: *Function, w: *Writer) !void {
5231 // Not even allowed to call trap in a naked function.5232 // Not even allowed to call trap in a naked function.
5232 if (f.object.dg.is_naked_fn) return;5233 if (f.object.dg.is_naked_fn) return;
5233 try writer.writeAll("zig_trap();\n");5234 try w.writeAll("zig_trap();\n");
5234}5235}
52355236
5236fn airBreakpoint(writer: anytype) !CValue {5237fn airBreakpoint(w: *Writer) !CValue {
5237 try writer.writeAll("zig_breakpoint();\n");5238 try w.writeAll("zig_breakpoint();\n");
5238 return .none;5239 return .none;
5239}5240}
52405241
5241fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {5242fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
5242 const writer = f.object.writer();5243 const w = f.object.writer();
5243 const local = try f.allocLocal(inst, .usize);5244 const local = try f.allocLocal(inst, .usize);
5244 try f.writeCValue(writer, local, .Other);5245 try f.writeCValue(w, local, .Other);
5245 try writer.writeAll(" = (");5246 try w.writeAll(" = (");
5246 try f.renderType(writer, .usize);5247 try f.renderType(w, .usize);
5247 try writer.writeAll(")zig_return_address();\n");5248 try w.writeAll(")zig_return_address();\n");
5248 return local;5249 return local;
5249}5250}
52505251
5251fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {5252fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
5252 const writer = f.object.writer();5253 const w = f.object.writer();
5253 const local = try f.allocLocal(inst, .usize);5254 const local = try f.allocLocal(inst, .usize);
5254 try f.writeCValue(writer, local, .Other);5255 try f.writeCValue(w, local, .Other);
5255 try writer.writeAll(" = (");5256 try w.writeAll(" = (");
5256 try f.renderType(writer, .usize);5257 try f.renderType(w, .usize);
5257 try writer.writeAll(")zig_frame_address();\n");5258 try w.writeAll(")zig_frame_address();\n");
5258 return local;5259 return local;
5259}5260}
52605261
...@@ -5268,13 +5269,13 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !void {...@@ -5268,13 +5269,13 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !void {
5268 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;5269 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
5269 const loop = f.air.extraData(Air.Block, ty_pl.payload);5270 const loop = f.air.extraData(Air.Block, ty_pl.payload);
5270 const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[loop.end..][0..loop.data.body_len]);5271 const body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[loop.end..][0..loop.data.body_len]);
5271 const writer = f.object.writer();5272 const w = f.object.writer();
52725273
5273 // `repeat` instructions matching this loop will branch to5274 // `repeat` instructions matching this loop will branch to
5274 // this label. Since we need a label for arbitrary `repeat`5275 // this label. Since we need a label for arbitrary `repeat`
5275 // anyway, there's actually no need to use a "real" looping5276 // anyway, there's actually no need to use a "real" looping
5276 // construct at all!5277 // construct at all!
5277 try writer.print("zig_loop_{d}:\n", .{@intFromEnum(inst)});5278 try w.print("zig_loop_{d}:\n", .{@intFromEnum(inst)});
5278 try genBodyInner(f, body); // no need to restore state, we're noreturn5279 try genBodyInner(f, body); // no need to restore state, we're noreturn
5279}5280}
52805281
...@@ -5286,14 +5287,14 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {...@@ -5286,14 +5287,14 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
5286 const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]);5287 const then_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end..][0..extra.data.then_body_len]);
5287 const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);5288 const else_body: []const Air.Inst.Index = @ptrCast(f.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);
5288 const liveness_condbr = f.liveness.getCondBr(inst);5289 const liveness_condbr = f.liveness.getCondBr(inst);
5289 const writer = f.object.writer();5290 const w = f.object.writer();
52905291
5291 try writer.writeAll("if (");5292 try w.writeAll("if (");
5292 try f.writeCValue(writer, cond, .Other);5293 try f.writeCValue(w, cond, .Other);
5293 try writer.writeAll(") ");5294 try w.writeAll(") ");
52945295
5295 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);5296 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
5296 try writer.writeByte('\n');5297 try w.writeByte('\n');
5297 if (else_body.len > 0) if (f.object.dg.expected_block) |_|5298 if (else_body.len > 0) if (f.object.dg.expected_block) |_|
5298 return f.fail("runtime code not allowed in naked function", .{});5299 return f.fail("runtime code not allowed in naked function", .{});
52995300
...@@ -5319,7 +5320,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5319,7 +5320,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5319 const init_condition = try f.resolveInst(switch_br.operand);5320 const init_condition = try f.resolveInst(switch_br.operand);
5320 try reap(f, inst, &.{switch_br.operand});5321 try reap(f, inst, &.{switch_br.operand});
5321 const condition_ty = f.typeOf(switch_br.operand);5322 const condition_ty = f.typeOf(switch_br.operand);
5322 const writer = f.object.writer();5323 const w = f.object.writer();
53235324
5324 // For dispatches, we will create a local alloc to contain the condition value.5325 // For dispatches, we will create a local alloc to contain the condition value.
5325 // This may not result in optimal codegen for switch loops, but it minimizes the5326 // This may not result in optimal codegen for switch loops, but it minimizes the
...@@ -5327,7 +5328,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5327,7 +5328,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5327 const condition = if (is_dispatch_loop) cond: {5328 const condition = if (is_dispatch_loop) cond: {
5328 const new_local = try f.allocLocal(inst, condition_ty);5329 const new_local = try f.allocLocal(inst, condition_ty);
5329 try f.copyCValue(try f.ctypeFromType(condition_ty, .complete), new_local, init_condition);5330 try f.copyCValue(try f.ctypeFromType(condition_ty, .complete), new_local, init_condition);
5330 try writer.print("zig_switch_{d}_loop:\n", .{@intFromEnum(inst)});5331 try w.print("zig_switch_{d}_loop:\n", .{@intFromEnum(inst)});
5331 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);5332 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);
5332 break :cond new_local;5333 break :cond new_local;
5333 } else init_condition;5334 } else init_condition;
...@@ -5336,7 +5337,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5336,7 +5337,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5336 assert(f.loop_switch_conds.remove(inst));5337 assert(f.loop_switch_conds.remove(inst));
5337 };5338 };
53385339
5339 try writer.writeAll("switch (");5340 try w.writeAll("switch (");
53405341
5341 const lowered_condition_ty: Type = if (condition_ty.toIntern() == .bool_type)5342 const lowered_condition_ty: Type = if (condition_ty.toIntern() == .bool_type)
5342 .u15343 .u1
...@@ -5345,12 +5346,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5345,12 +5346,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5345 else5346 else
5346 condition_ty;5347 condition_ty;
5347 if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {5348 if (condition_ty.toIntern() != lowered_condition_ty.toIntern()) {
5348 try writer.writeByte('(');5349 try w.writeByte('(');
5349 try f.renderType(writer, lowered_condition_ty);5350 try f.renderType(w, lowered_condition_ty);
5350 try writer.writeByte(')');5351 try w.writeByte(')');
5351 }5352 }
5352 try f.writeCValue(writer, condition, .Other);5353 try f.writeCValue(w, condition, .Other);
5353 try writer.writeAll(") {");5354 try w.writeAll(") {");
5354 f.object.indent_writer.pushIndent();5355 f.object.indent_writer.pushIndent();
53555356
5356 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);5357 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);
...@@ -5365,34 +5366,34 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5365,34 +5366,34 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5365 }5366 }
5366 for (case.items) |item| {5367 for (case.items) |item| {
5367 try f.object.indent_writer.insertNewline();5368 try f.object.indent_writer.insertNewline();
5368 try writer.writeAll("case ");5369 try w.writeAll("case ");
5369 const item_value = try f.air.value(item, pt);5370 const item_value = try f.air.value(item, pt);
5370 // If `item_value` is a pointer with a known integer address, print the address5371 // If `item_value` is a pointer with a known integer address, print the address
5371 // with no cast to avoid a warning.5372 // with no cast to avoid a warning.
5372 write_val: {5373 write_val: {
5373 if (condition_ty.isPtrAtRuntime(zcu)) {5374 if (condition_ty.isPtrAtRuntime(zcu)) {
5374 if (item_value.?.getUnsignedInt(zcu)) |item_int| {5375 if (item_value.?.getUnsignedInt(zcu)) |item_int| {
5375 try writer.print("{f}", .{try f.fmtIntLiteralDec(try pt.intValue(lowered_condition_ty, item_int))});5376 try w.print("{f}", .{try f.fmtIntLiteralDec(try pt.intValue(lowered_condition_ty, item_int))});
5376 break :write_val;5377 break :write_val;
5377 }5378 }
5378 }5379 }
5379 if (condition_ty.isPtrAtRuntime(zcu)) {5380 if (condition_ty.isPtrAtRuntime(zcu)) {
5380 try writer.writeByte('(');5381 try w.writeByte('(');
5381 try f.renderType(writer, .usize);5382 try f.renderType(w, .usize);
5382 try writer.writeByte(')');5383 try w.writeByte(')');
5383 }5384 }
5384 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);5385 try f.object.dg.renderValue(w, (try f.air.value(item, pt)).?, .Other);
5385 }5386 }
5386 try writer.writeByte(':');5387 try w.writeByte(':');
5387 }5388 }
5388 try writer.writeAll(" {\n");5389 try w.writeAll(" {\n");
5389 f.object.indent_writer.pushIndent();5390 f.object.indent_writer.pushIndent();
5390 if (is_dispatch_loop) {5391 if (is_dispatch_loop) {
5391 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });5392 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
5392 }5393 }
5393 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);5394 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5394 f.object.indent_writer.popIndent();5395 f.object.indent_writer.popIndent();
5395 try writer.writeByte('}');5396 try w.writeByte('}');
5396 if (f.object.dg.expected_block) |_|5397 if (f.object.dg.expected_block) |_|
5397 return f.fail("runtime code not allowed in naked function", .{});5398 return f.fail("runtime code not allowed in naked function", .{});
53985399
...@@ -5402,7 +5403,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5402,7 +5403,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5402 const else_body = it.elseBody();5403 const else_body = it.elseBody();
5403 try f.object.indent_writer.insertNewline();5404 try f.object.indent_writer.insertNewline();
54045405
5405 try writer.writeAll("default: ");5406 try w.writeAll("default: ");
5406 if (any_range_cases) {5407 if (any_range_cases) {
5407 // We will iterate the cases again to handle those with ranges, and generate5408 // We will iterate the cases again to handle those with ranges, and generate
5408 // code using conditions rather than switch cases for such cases.5409 // code using conditions rather than switch cases for such cases.
...@@ -5410,40 +5411,40 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5410,40 +5411,40 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5410 while (it.next()) |case| {5411 while (it.next()) |case| {
5411 if (case.ranges.len == 0) continue; // handled above5412 if (case.ranges.len == 0) continue; // handled above
54125413
5413 try writer.writeAll("if (");5414 try w.writeAll("if (");
5414 for (case.items, 0..) |item, item_i| {5415 for (case.items, 0..) |item, item_i| {
5415 if (item_i != 0) try writer.writeAll(" || ");5416 if (item_i != 0) try w.writeAll(" || ");
5416 try f.writeCValue(writer, condition, .Other);5417 try f.writeCValue(w, condition, .Other);
5417 try writer.writeAll(" == ");5418 try w.writeAll(" == ");
5418 try f.object.dg.renderValue(writer, (try f.air.value(item, pt)).?, .Other);5419 try f.object.dg.renderValue(w, (try f.air.value(item, pt)).?, .Other);
5419 }5420 }
5420 for (case.ranges, 0..) |range, range_i| {5421 for (case.ranges, 0..) |range, range_i| {
5421 if (case.items.len != 0 or range_i != 0) try writer.writeAll(" || ");5422 if (case.items.len != 0 or range_i != 0) try w.writeAll(" || ");
5422 // "(x >= lower && x <= upper)"5423 // "(x >= lower && x <= upper)"
5423 try writer.writeByte('(');5424 try w.writeByte('(');
5424 try f.writeCValue(writer, condition, .Other);5425 try f.writeCValue(w, condition, .Other);
5425 try writer.writeAll(" >= ");5426 try w.writeAll(" >= ");
5426 try f.object.dg.renderValue(writer, (try f.air.value(range[0], pt)).?, .Other);5427 try f.object.dg.renderValue(w, (try f.air.value(range[0], pt)).?, .Other);
5427 try writer.writeAll(" && ");5428 try w.writeAll(" && ");
5428 try f.writeCValue(writer, condition, .Other);5429 try f.writeCValue(w, condition, .Other);
5429 try writer.writeAll(" <= ");5430 try w.writeAll(" <= ");
5430 try f.object.dg.renderValue(writer, (try f.air.value(range[1], pt)).?, .Other);5431 try f.object.dg.renderValue(w, (try f.air.value(range[1], pt)).?, .Other);
5431 try writer.writeByte(')');5432 try w.writeByte(')');
5432 }5433 }
5433 try writer.writeAll(") {\n");5434 try w.writeAll(") {\n");
5434 f.object.indent_writer.pushIndent();5435 f.object.indent_writer.pushIndent();
5435 if (is_dispatch_loop) {5436 if (is_dispatch_loop) {
5436 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });5437 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
5437 }5438 }
5438 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);5439 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5439 f.object.indent_writer.popIndent();5440 f.object.indent_writer.popIndent();
5440 try writer.writeByte('}');5441 try w.writeByte('}');
5441 if (f.object.dg.expected_block) |_|5442 if (f.object.dg.expected_block) |_|
5442 return f.fail("runtime code not allowed in naked function", .{});5443 return f.fail("runtime code not allowed in naked function", .{});
5443 }5444 }
5444 }5445 }
5445 if (is_dispatch_loop) {5446 if (is_dispatch_loop) {
5446 try writer.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), switch_br.cases_len });5447 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), switch_br.cases_len });
5447 }5448 }
5448 if (else_body.len > 0) {5449 if (else_body.len > 0) {
5449 // Note that this must be the last case, so we do not need to use `genBodyResolveState` since5450 // Note that this must be the last case, so we do not need to use `genBodyResolveState` since
...@@ -5455,12 +5456,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void...@@ -5455,12 +5456,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
5455 if (f.object.dg.expected_block) |_|5456 if (f.object.dg.expected_block) |_|
5456 return f.fail("runtime code not allowed in naked function", .{});5457 return f.fail("runtime code not allowed in naked function", .{});
5457 } else {5458 } else {
5458 try writer.writeAll("zig_unreachable();");5459 try w.writeAll("zig_unreachable();");
5459 }5460 }
5460 try f.object.indent_writer.insertNewline();5461 try f.object.indent_writer.insertNewline();
54615462
5462 f.object.indent_writer.popIndent();5463 f.object.indent_writer.popIndent();
5463 try writer.writeAll("}\n");5464 try w.writeAll("}\n");
5464}5465}
54655466
5466fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {5467fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
...@@ -5498,7 +5499,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5498,7 +5499,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5498 extra_i += inputs.len;5499 extra_i += inputs.len;
54995500
5500 const result = result: {5501 const result = result: {
5501 const writer = f.object.writer();5502 const w = f.object.writer();
5502 const inst_ty = f.typeOfIndex(inst);5503 const inst_ty = f.typeOfIndex(inst);
5503 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {5504 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
5504 const inst_local = try f.allocLocalValue(.{5505 const inst_local = try f.allocLocalValue(.{
...@@ -5506,10 +5507,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5506,10 +5507,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5506 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),5507 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
5507 });5508 });
5508 if (f.wantSafety()) {5509 if (f.wantSafety()) {
5509 try f.writeCValue(writer, inst_local, .Other);5510 try f.writeCValue(w, inst_local, .Other);
5510 try writer.writeAll(" = ");5511 try w.writeAll(" = ");
5511 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);5512 try f.writeCValue(w, .{ .undef = inst_ty }, .Other);
5512 try writer.writeAll(";\n");5513 try w.writeAll(";\n");
5513 }5514 }
5514 break :local inst_local;5515 break :local inst_local;
5515 } else .none;5516 } else .none;
...@@ -5533,21 +5534,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5533,21 +5534,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5533 const is_reg = constraint[1] == '{';5534 const is_reg = constraint[1] == '{';
5534 if (is_reg) {5535 if (is_reg) {
5535 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);5536 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
5536 try writer.writeAll("register ");5537 try w.writeAll("register ");
5537 const output_local = try f.allocLocalValue(.{5538 const output_local = try f.allocLocalValue(.{
5538 .ctype = try f.ctypeFromType(output_ty, .complete),5539 .ctype = try f.ctypeFromType(output_ty, .complete),
5539 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),5540 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
5540 });5541 });
5541 try f.allocs.put(gpa, output_local.new_local, false);5542 try f.allocs.put(gpa, output_local.new_local, false);
5542 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);5543 try f.object.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none, .complete);
5543 try writer.writeAll(" __asm(\"");5544 try w.writeAll(" __asm(\"");
5544 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);5545 try w.writeAll(constraint["={".len .. constraint.len - "}".len]);
5545 try writer.writeAll("\")");5546 try w.writeAll("\")");
5546 if (f.wantSafety()) {5547 if (f.wantSafety()) {
5547 try writer.writeAll(" = ");5548 try w.writeAll(" = ");
5548 try f.writeCValue(writer, .{ .undef = output_ty }, .Other);5549 try f.writeCValue(w, .{ .undef = output_ty }, .Other);
5549 }5550 }
5550 try writer.writeAll(";\n");5551 try w.writeAll(";\n");
5551 }5552 }
5552 }5553 }
5553 for (inputs) |input| {5554 for (inputs) |input| {
...@@ -5568,21 +5569,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5568,21 +5569,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5568 const input_val = try f.resolveInst(input);5569 const input_val = try f.resolveInst(input);
5569 if (asmInputNeedsLocal(f, constraint, input_val)) {5570 if (asmInputNeedsLocal(f, constraint, input_val)) {
5570 const input_ty = f.typeOf(input);5571 const input_ty = f.typeOf(input);
5571 if (is_reg) try writer.writeAll("register ");5572 if (is_reg) try w.writeAll("register ");
5572 const input_local = try f.allocLocalValue(.{5573 const input_local = try f.allocLocalValue(.{
5573 .ctype = try f.ctypeFromType(input_ty, .complete),5574 .ctype = try f.ctypeFromType(input_ty, .complete),
5574 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),5575 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
5575 });5576 });
5576 try f.allocs.put(gpa, input_local.new_local, false);5577 try f.allocs.put(gpa, input_local.new_local, false);
5577 try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);5578 try f.object.dg.renderTypeAndName(w, input_ty, input_local, Const, .none, .complete);
5578 if (is_reg) {5579 if (is_reg) {
5579 try writer.writeAll(" __asm(\"");5580 try w.writeAll(" __asm(\"");
5580 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);5581 try w.writeAll(constraint["{".len .. constraint.len - "}".len]);
5581 try writer.writeAll("\")");5582 try w.writeAll("\")");
5582 }5583 }
5583 try writer.writeAll(" = ");5584 try w.writeAll(" = ");
5584 try f.writeCValue(writer, input_val, .Other);5585 try f.writeCValue(w, input_val, .Other);
5585 try writer.writeAll(";\n");5586 try w.writeAll(";\n");
5586 }5587 }
5587 }5588 }
5588 for (0..clobbers_len) |_| {5589 for (0..clobbers_len) |_| {
...@@ -5642,14 +5643,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5642,14 +5643,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5642 }5643 }
5643 }5644 }
56445645
5645 try writer.writeAll("__asm");5646 try w.writeAll("__asm");
5646 if (is_volatile) try writer.writeAll(" volatile");5647 if (is_volatile) try w.writeAll(" volatile");
5647 try writer.print("({f}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});5648 try w.print("({f}", .{fmtStringLiteral(fixed_asm_source[0..dst_i], null)});
5648 }5649 }
56495650
5650 extra_i = constraints_extra_begin;5651 extra_i = constraints_extra_begin;
5651 var locals_index = locals_begin;5652 var locals_index = locals_begin;
5652 try writer.writeByte(':');5653 try w.writeByte(':');
5653 for (outputs, 0..) |output, index| {5654 for (outputs, 0..) |output, index| {
5654 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);5655 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
5655 const constraint = mem.sliceTo(extra_bytes, 0);5656 const constraint = mem.sliceTo(extra_bytes, 0);
...@@ -5658,22 +5659,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5658,22 +5659,22 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5658 // for the string, we still use the next u32 for the null terminator.5659 // for the string, we still use the next u32 for the null terminator.
5659 extra_i += (constraint.len + name.len + (2 + 3)) / 4;5660 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56605661
5661 if (index > 0) try writer.writeByte(',');5662 if (index > 0) try w.writeByte(',');
5662 try writer.writeByte(' ');5663 try w.writeByte(' ');
5663 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});5664 if (!mem.eql(u8, name, "_")) try w.print("[{s}]", .{name});
5664 const is_reg = constraint[1] == '{';5665 const is_reg = constraint[1] == '{';
5665 try writer.print("{f}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});5666 try w.print("{f}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
5666 if (is_reg) {5667 if (is_reg) {
5667 try f.writeCValue(writer, .{ .local = locals_index }, .Other);5668 try f.writeCValue(w, .{ .local = locals_index }, .Other);
5668 locals_index += 1;5669 locals_index += 1;
5669 } else if (output == .none) {5670 } else if (output == .none) {
5670 try f.writeCValue(writer, inst_local, .FunctionArgument);5671 try f.writeCValue(w, inst_local, .FunctionArgument);
5671 } else {5672 } else {
5672 try f.writeCValueDeref(writer, try f.resolveInst(output));5673 try f.writeCValueDeref(w, try f.resolveInst(output));
5673 }5674 }
5674 try writer.writeByte(')');5675 try w.writeByte(')');
5675 }5676 }
5676 try writer.writeByte(':');5677 try w.writeByte(':');
5677 for (inputs, 0..) |input, index| {5678 for (inputs, 0..) |input, index| {
5678 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);5679 const extra_bytes = mem.sliceAsBytes(f.air.extra.items[extra_i..]);
5679 const constraint = mem.sliceTo(extra_bytes, 0);5680 const constraint = mem.sliceTo(extra_bytes, 0);
...@@ -5682,21 +5683,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5682,21 +5683,21 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5682 // for the string, we still use the next u32 for the null terminator.5683 // for the string, we still use the next u32 for the null terminator.
5683 extra_i += (constraint.len + name.len + (2 + 3)) / 4;5684 extra_i += (constraint.len + name.len + (2 + 3)) / 4;
56845685
5685 if (index > 0) try writer.writeByte(',');5686 if (index > 0) try w.writeByte(',');
5686 try writer.writeByte(' ');5687 try w.writeByte(' ');
5687 if (!mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name});5688 if (!mem.eql(u8, name, "_")) try w.print("[{s}]", .{name});
56885689
5689 const is_reg = constraint[0] == '{';5690 const is_reg = constraint[0] == '{';
5690 const input_val = try f.resolveInst(input);5691 const input_val = try f.resolveInst(input);
5691 try writer.print("{f}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});5692 try w.print("{f}(", .{fmtStringLiteral(if (is_reg) "r" else constraint, null)});
5692 try f.writeCValue(writer, if (asmInputNeedsLocal(f, constraint, input_val)) local: {5693 try f.writeCValue(w, if (asmInputNeedsLocal(f, constraint, input_val)) local: {
5693 const input_local_idx = locals_index;5694 const input_local_idx = locals_index;
5694 locals_index += 1;5695 locals_index += 1;
5695 break :local .{ .local = input_local_idx };5696 break :local .{ .local = input_local_idx };
5696 } else input_val, .Other);5697 } else input_val, .Other);
5697 try writer.writeByte(')');5698 try w.writeByte(')');
5698 }5699 }
5699 try writer.writeByte(':');5700 try w.writeByte(':');
5700 for (0..clobbers_len) |clobber_i| {5701 for (0..clobbers_len) |clobber_i| {
5701 const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0);5702 const clobber = mem.sliceTo(mem.sliceAsBytes(f.air.extra.items[extra_i..]), 0);
5702 // This equation accounts for the fact that even if we have exactly 4 bytes5703 // This equation accounts for the fact that even if we have exactly 4 bytes
...@@ -5705,10 +5706,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5705,10 +5706,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
57055706
5706 if (clobber.len == 0) continue;5707 if (clobber.len == 0) continue;
57075708
5708 if (clobber_i > 0) try writer.writeByte(',');5709 if (clobber_i > 0) try w.writeByte(',');
5709 try writer.print(" {f}", .{fmtStringLiteral(clobber, null)});5710 try w.print(" {f}", .{fmtStringLiteral(clobber, null)});
5710 }5711 }
5711 try writer.writeAll(");\n");5712 try w.writeAll(");\n");
57125713
5713 extra_i = constraints_extra_begin;5714 extra_i = constraints_extra_begin;
5714 locals_index = locals_begin;5715 locals_index = locals_begin;
...@@ -5722,14 +5723,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5722,14 +5723,14 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
57225723
5723 const is_reg = constraint[1] == '{';5724 const is_reg = constraint[1] == '{';
5724 if (is_reg) {5725 if (is_reg) {
5725 try f.writeCValueDeref(writer, if (output == .none)5726 try f.writeCValueDeref(w, if (output == .none)
5726 .{ .local_ref = inst_local.new_local }5727 .{ .local_ref = inst_local.new_local }
5727 else5728 else
5728 try f.resolveInst(output));5729 try f.resolveInst(output));
5729 try writer.writeAll(" = ");5730 try w.writeAll(" = ");
5730 try f.writeCValue(writer, .{ .local = locals_index }, .Other);5731 try f.writeCValue(w, .{ .local = locals_index }, .Other);
5731 locals_index += 1;5732 locals_index += 1;
5732 try writer.writeAll(";\n");5733 try w.writeAll(";\n");
5733 }5734 }
5734 }5735 }
57355736
...@@ -5759,14 +5760,14 @@ fn airIsNull(...@@ -5759,14 +5760,14 @@ fn airIsNull(
5759 const ctype_pool = &f.object.dg.ctype_pool;5760 const ctype_pool = &f.object.dg.ctype_pool;
5760 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5761 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
57615762
5762 const writer = f.object.writer();5763 const w = f.object.writer();
5763 const operand = try f.resolveInst(un_op);5764 const operand = try f.resolveInst(un_op);
5764 try reap(f, inst, &.{un_op});5765 try reap(f, inst, &.{un_op});
57655766
5766 const local = try f.allocLocal(inst, .bool);5767 const local = try f.allocLocal(inst, .bool);
5767 const a = try Assignment.start(f, writer, .bool);5768 const a = try Assignment.start(f, w, .bool);
5768 try f.writeCValue(writer, local, .Other);5769 try f.writeCValue(w, local, .Other);
5769 try a.assign(f, writer);5770 try a.assign(f, w);
57705771
5771 const operand_ty = f.typeOf(un_op);5772 const operand_ty = f.typeOf(un_op);
5772 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;5773 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
...@@ -5774,9 +5775,9 @@ fn airIsNull(...@@ -5774,9 +5775,9 @@ fn airIsNull(
5774 const rhs = switch (opt_ctype.info(ctype_pool)) {5775 const rhs = switch (opt_ctype.info(ctype_pool)) {
5775 .basic, .pointer => rhs: {5776 .basic, .pointer => rhs: {
5776 if (is_ptr)5777 if (is_ptr)
5777 try f.writeCValueDeref(writer, operand)5778 try f.writeCValueDeref(w, operand)
5778 else5779 else
5779 try f.writeCValue(writer, operand, .Other);5780 try f.writeCValue(w, operand, .Other);
5780 break :rhs if (opt_ctype.isBool())5781 break :rhs if (opt_ctype.isBool())
5781 "true"5782 "true"
5782 else if (opt_ctype.isInteger())5783 else if (opt_ctype.isInteger())
...@@ -5788,24 +5789,24 @@ fn airIsNull(...@@ -5788,24 +5789,24 @@ fn airIsNull(
5788 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {5789 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5789 .is_null, .payload => rhs: {5790 .is_null, .payload => rhs: {
5790 if (is_ptr)5791 if (is_ptr)
5791 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" })5792 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" })
5792 else5793 else
5793 try f.writeCValueMember(writer, operand, .{ .identifier = "is_null" });5794 try f.writeCValueMember(w, operand, .{ .identifier = "is_null" });
5794 break :rhs "true";5795 break :rhs "true";
5795 },5796 },
5796 .ptr, .len => rhs: {5797 .ptr, .len => rhs: {
5797 if (is_ptr)5798 if (is_ptr)
5798 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "ptr" })5799 try f.writeCValueDerefMember(w, operand, .{ .identifier = "ptr" })
5799 else5800 else
5800 try f.writeCValueMember(writer, operand, .{ .identifier = "ptr" });5801 try f.writeCValueMember(w, operand, .{ .identifier = "ptr" });
5801 break :rhs "NULL";5802 break :rhs "NULL";
5802 },5803 },
5803 else => unreachable,5804 else => unreachable,
5804 },5805 },
5805 };5806 };
5806 try writer.writeAll(compareOperatorC(operator));5807 try w.writeAll(compareOperatorC(operator));
5807 try writer.writeAll(rhs);5808 try w.writeAll(rhs);
5808 try a.end(f, writer);5809 try a.end(f, w);
5809 return local;5810 return local;
5810}5811}
58115812
...@@ -5827,16 +5828,16 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue...@@ -5827,16 +5828,16 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue
5827 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5828 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5828 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {5829 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5829 .is_null, .payload => {5830 .is_null, .payload => {
5830 const writer = f.object.writer();5831 const w = f.object.writer();
5831 const local = try f.allocLocal(inst, inst_ty);5832 const local = try f.allocLocal(inst, inst_ty);
5832 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));5833 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
5833 try f.writeCValue(writer, local, .Other);5834 try f.writeCValue(w, local, .Other);
5834 try a.assign(f, writer);5835 try a.assign(f, w);
5835 if (is_ptr) {5836 if (is_ptr) {
5836 try writer.writeByte('&');5837 try w.writeByte('&');
5837 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });5838 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
5838 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });5839 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
5839 try a.end(f, writer);5840 try a.end(f, w);
5840 return local;5841 return local;
5841 },5842 },
5842 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),5843 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
...@@ -5849,7 +5850,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5849,7 +5850,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5849 const pt = f.object.dg.pt;5850 const pt = f.object.dg.pt;
5850 const zcu = pt.zcu;5851 const zcu = pt.zcu;
5851 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5852 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5852 const writer = f.object.writer();5853 const w = f.object.writer();
5853 const operand = try f.resolveInst(ty_op.operand);5854 const operand = try f.resolveInst(ty_op.operand);
5854 try reap(f, inst, &.{ty_op.operand});5855 try reap(f, inst, &.{ty_op.operand});
5855 const operand_ty = f.typeOf(ty_op.operand);5856 const operand_ty = f.typeOf(ty_op.operand);
...@@ -5858,40 +5859,40 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5858,40 +5859,40 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5858 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);5859 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);
5859 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {5860 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {
5860 .basic => {5861 .basic => {
5861 const a = try Assignment.start(f, writer, opt_ctype);5862 const a = try Assignment.start(f, w, opt_ctype);
5862 try f.writeCValueDeref(writer, operand);5863 try f.writeCValueDeref(w, operand);
5863 try a.assign(f, writer);5864 try a.assign(f, w);
5864 try f.object.dg.renderValue(writer, Value.false, .Other);5865 try f.object.dg.renderValue(w, Value.false, .Other);
5865 try a.end(f, writer);5866 try a.end(f, w);
5866 return .none;5867 return .none;
5867 },5868 },
5868 .pointer => {5869 .pointer => {
5869 if (f.liveness.isUnused(inst)) return .none;5870 if (f.liveness.isUnused(inst)) return .none;
5870 const local = try f.allocLocal(inst, inst_ty);5871 const local = try f.allocLocal(inst, inst_ty);
5871 const a = try Assignment.start(f, writer, opt_ctype);5872 const a = try Assignment.start(f, w, opt_ctype);
5872 try f.writeCValue(writer, local, .Other);5873 try f.writeCValue(w, local, .Other);
5873 try a.assign(f, writer);5874 try a.assign(f, w);
5874 try f.writeCValue(writer, operand, .Other);5875 try f.writeCValue(w, operand, .Other);
5875 try a.end(f, writer);5876 try a.end(f, w);
5876 return local;5877 return local;
5877 },5878 },
5878 .aligned, .array, .vector, .fwd_decl, .function => unreachable,5879 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5879 .aggregate => {5880 .aggregate => {
5880 {5881 {
5881 const a = try Assignment.start(f, writer, opt_ctype);5882 const a = try Assignment.start(f, w, opt_ctype);
5882 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "is_null" });5883 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5883 try a.assign(f, writer);5884 try a.assign(f, w);
5884 try f.object.dg.renderValue(writer, Value.false, .Other);5885 try f.object.dg.renderValue(w, Value.false, .Other);
5885 try a.end(f, writer);5886 try a.end(f, w);
5886 }5887 }
5887 if (f.liveness.isUnused(inst)) return .none;5888 if (f.liveness.isUnused(inst)) return .none;
5888 const local = try f.allocLocal(inst, inst_ty);5889 const local = try f.allocLocal(inst, inst_ty);
5889 const a = try Assignment.start(f, writer, opt_ctype);5890 const a = try Assignment.start(f, w, opt_ctype);
5890 try f.writeCValue(writer, local, .Other);5891 try f.writeCValue(w, local, .Other);
5891 try a.assign(f, writer);5892 try a.assign(f, w);
5892 try writer.writeByte('&');5893 try w.writeByte('&');
5893 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });5894 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
5894 try a.end(f, writer);5895 try a.end(f, w);
5895 return local;5896 return local;
5896 },5897 },
5897 }5898 }
...@@ -5999,42 +6000,42 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5999,42 +6000,42 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5999 const field_ptr_val = try f.resolveInst(extra.field_ptr);6000 const field_ptr_val = try f.resolveInst(extra.field_ptr);
6000 try reap(f, inst, &.{extra.field_ptr});6001 try reap(f, inst, &.{extra.field_ptr});
60016002
6002 const writer = f.object.writer();6003 const w = f.object.writer();
6003 const local = try f.allocLocal(inst, container_ptr_ty);6004 const local = try f.allocLocal(inst, container_ptr_ty);
6004 try f.writeCValue(writer, local, .Other);6005 try f.writeCValue(w, local, .Other);
6005 try writer.writeAll(" = (");6006 try w.writeAll(" = (");
6006 try f.renderType(writer, container_ptr_ty);6007 try f.renderType(w, container_ptr_ty);
6007 try writer.writeByte(')');6008 try w.writeByte(')');
60086009
6009 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) {6010 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, pt)) {
6010 .begin => try f.writeCValue(writer, field_ptr_val, .Other),6011 .begin => try f.writeCValue(w, field_ptr_val, .Other),
6011 .field => |field| {6012 .field => |field| {
6012 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6013 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
60136014
6014 try writer.writeAll("((");6015 try w.writeAll("((");
6015 try f.renderType(writer, u8_ptr_ty);6016 try f.renderType(w, u8_ptr_ty);
6016 try writer.writeByte(')');6017 try w.writeByte(')');
6017 try f.writeCValue(writer, field_ptr_val, .Other);6018 try f.writeCValue(w, field_ptr_val, .Other);
6018 try writer.writeAll(" - offsetof(");6019 try w.writeAll(" - offsetof(");
6019 try f.renderType(writer, container_ty);6020 try f.renderType(w, container_ty);
6020 try writer.writeAll(", ");6021 try w.writeAll(", ");
6021 try f.writeCValue(writer, field, .Other);6022 try f.writeCValue(w, field, .Other);
6022 try writer.writeAll("))");6023 try w.writeAll("))");
6023 },6024 },
6024 .byte_offset => |byte_offset| {6025 .byte_offset => |byte_offset| {
6025 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6026 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
60266027
6027 try writer.writeAll("((");6028 try w.writeAll("((");
6028 try f.renderType(writer, u8_ptr_ty);6029 try f.renderType(w, u8_ptr_ty);
6029 try writer.writeByte(')');6030 try w.writeByte(')');
6030 try f.writeCValue(writer, field_ptr_val, .Other);6031 try f.writeCValue(w, field_ptr_val, .Other);
6031 try writer.print(" - {f})", .{6032 try w.print(" - {f})", .{
6032 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),6033 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
6033 });6034 });
6034 },6035 },
6035 }6036 }
60366037
6037 try writer.writeAll(";\n");6038 try w.writeAll(";\n");
6038 return local;6039 return local;
6039}6040}
60406041
...@@ -6053,33 +6054,33 @@ fn fieldPtr(...@@ -6053,33 +6054,33 @@ fn fieldPtr(
6053 // Ensure complete type definition is visible before accessing fields.6054 // Ensure complete type definition is visible before accessing fields.
6054 _ = try f.ctypeFromType(container_ty, .complete);6055 _ = try f.ctypeFromType(container_ty, .complete);
60556056
6056 const writer = f.object.writer();6057 const w = f.object.writer();
6057 const local = try f.allocLocal(inst, field_ptr_ty);6058 const local = try f.allocLocal(inst, field_ptr_ty);
6058 try f.writeCValue(writer, local, .Other);6059 try f.writeCValue(w, local, .Other);
6059 try writer.writeAll(" = (");6060 try w.writeAll(" = (");
6060 try f.renderType(writer, field_ptr_ty);6061 try f.renderType(w, field_ptr_ty);
6061 try writer.writeByte(')');6062 try w.writeByte(')');
60626063
6063 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) {6064 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, pt)) {
6064 .begin => try f.writeCValue(writer, container_ptr_val, .Other),6065 .begin => try f.writeCValue(w, container_ptr_val, .Other),
6065 .field => |field| {6066 .field => |field| {
6066 try writer.writeByte('&');6067 try w.writeByte('&');
6067 try f.writeCValueDerefMember(writer, container_ptr_val, field);6068 try f.writeCValueDerefMember(w, container_ptr_val, field);
6068 },6069 },
6069 .byte_offset => |byte_offset| {6070 .byte_offset => |byte_offset| {
6070 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);6071 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
60716072
6072 try writer.writeAll("((");6073 try w.writeAll("((");
6073 try f.renderType(writer, u8_ptr_ty);6074 try f.renderType(w, u8_ptr_ty);
6074 try writer.writeByte(')');6075 try w.writeByte(')');
6075 try f.writeCValue(writer, container_ptr_val, .Other);6076 try f.writeCValue(w, container_ptr_val, .Other);
6076 try writer.print(" + {f})", .{6077 try w.print(" + {f})", .{
6077 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),6078 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
6078 });6079 });
6079 },6080 },
6080 }6081 }
60816082
6082 try writer.writeAll(";\n");6083 try w.writeAll(";\n");
6083 return local;6084 return local;
6084}6085}
60856086
...@@ -6099,7 +6100,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6099,7 +6100,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6099 const struct_byval = try f.resolveInst(extra.struct_operand);6100 const struct_byval = try f.resolveInst(extra.struct_operand);
6100 try reap(f, inst, &.{extra.struct_operand});6101 try reap(f, inst, &.{extra.struct_operand});
6101 const struct_ty = f.typeOf(extra.struct_operand);6102 const struct_ty = f.typeOf(extra.struct_operand);
6102 const writer = f.object.writer();6103 const w = f.object.writer();
61036104
6104 // Ensure complete type definition is visible before accessing fields.6105 // Ensure complete type definition is visible before accessing fields.
6105 _ = try f.ctypeFromType(struct_ty, .complete);6106 _ = try f.ctypeFromType(struct_ty, .complete);
...@@ -6126,42 +6127,42 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6126,42 +6127,42 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6126 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));6127 const field_int_ty = try pt.intType(field_int_signedness, @as(u16, @intCast(inst_ty.bitSize(zcu))));
61276128
6128 const temp_local = try f.allocLocal(inst, field_int_ty);6129 const temp_local = try f.allocLocal(inst, field_int_ty);
6129 try f.writeCValue(writer, temp_local, .Other);6130 try f.writeCValue(w, temp_local, .Other);
6130 try writer.writeAll(" = zig_wrap_");6131 try w.writeAll(" = zig_wrap_");
6131 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);6132 try f.object.dg.renderTypeForBuiltinFnName(w, field_int_ty);
6132 try writer.writeAll("((");6133 try w.writeAll("((");
6133 try f.renderType(writer, field_int_ty);6134 try f.renderType(w, field_int_ty);
6134 try writer.writeByte(')');6135 try w.writeByte(')');
6135 const cant_cast = int_info.bits > 64;6136 const cant_cast = int_info.bits > 64;
6136 if (cant_cast) {6137 if (cant_cast) {
6137 if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});6138 if (field_int_ty.bitSize(zcu) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
6138 try writer.writeAll("zig_lo_");6139 try w.writeAll("zig_lo_");
6139 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);6140 try f.object.dg.renderTypeForBuiltinFnName(w, struct_ty);
6140 try writer.writeByte('(');6141 try w.writeByte('(');
6141 }6142 }
6142 if (bit_offset > 0) {6143 if (bit_offset > 0) {
6143 try writer.writeAll("zig_shr_");6144 try w.writeAll("zig_shr_");
6144 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);6145 try f.object.dg.renderTypeForBuiltinFnName(w, struct_ty);
6145 try writer.writeByte('(');6146 try w.writeByte('(');
6146 }6147 }
6147 try f.writeCValue(writer, struct_byval, .Other);6148 try f.writeCValue(w, struct_byval, .Other);
6148 if (bit_offset > 0) try writer.print(", {f})", .{6149 if (bit_offset > 0) try w.print(", {f})", .{
6149 try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)),6150 try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)),
6150 });6151 });
6151 if (cant_cast) try writer.writeByte(')');6152 if (cant_cast) try w.writeByte(')');
6152 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);6153 try f.object.dg.renderBuiltinInfo(w, field_int_ty, .bits);
6153 try writer.writeAll(");\n");6154 try w.writeAll(");\n");
6154 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;6155 if (inst_ty.eql(field_int_ty, zcu)) return temp_local;
61556156
6156 const local = try f.allocLocal(inst, inst_ty);6157 const local = try f.allocLocal(inst, inst_ty);
6157 if (local.new_local != temp_local.new_local) {6158 if (local.new_local != temp_local.new_local) {
6158 try writer.writeAll("memcpy(");6159 try w.writeAll("memcpy(");
6159 try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);6160 try f.writeCValue(w, .{ .local_ref = local.new_local }, .FunctionArgument);
6160 try writer.writeAll(", ");6161 try w.writeAll(", ");
6161 try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);6162 try f.writeCValue(w, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
6162 try writer.writeAll(", sizeof(");6163 try w.writeAll(", sizeof(");
6163 try f.renderType(writer, inst_ty);6164 try f.renderType(w, inst_ty);
6164 try writer.writeAll("));\n");6165 try w.writeAll("));\n");
6165 }6166 }
6166 try freeLocal(f, inst, temp_local.new_local, null);6167 try freeLocal(f, inst, temp_local.new_local, null);
6167 return local;6168 return local;
...@@ -6182,10 +6183,10 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6182,10 +6183,10 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6182 .@"packed" => {6183 .@"packed" => {
6183 const operand_lval = if (struct_byval == .constant) blk: {6184 const operand_lval = if (struct_byval == .constant) blk: {
6184 const operand_local = try f.allocLocal(inst, struct_ty);6185 const operand_local = try f.allocLocal(inst, struct_ty);
6185 try f.writeCValue(writer, operand_local, .Other);6186 try f.writeCValue(w, operand_local, .Other);
6186 try writer.writeAll(" = ");6187 try w.writeAll(" = ");
6187 try f.writeCValue(writer, struct_byval, .Other);6188 try f.writeCValue(w, struct_byval, .Other);
6188 try writer.writeAll(";\n");6189 try w.writeAll(";\n");
6189 break :blk operand_local;6190 break :blk operand_local;
6190 } else struct_byval;6191 } else struct_byval;
6191 const local = try f.allocLocal(inst, inst_ty);6192 const local = try f.allocLocal(inst, inst_ty);
...@@ -6196,13 +6197,13 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6196,13 +6197,13 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6196 },6197 },
6197 else => true,6198 else => true,
6198 }) {6199 }) {
6199 try writer.writeAll("memcpy(&");6200 try w.writeAll("memcpy(&");
6200 try f.writeCValue(writer, local, .Other);6201 try f.writeCValue(w, local, .Other);
6201 try writer.writeAll(", &");6202 try w.writeAll(", &");
6202 try f.writeCValue(writer, operand_lval, .Other);6203 try f.writeCValue(w, operand_lval, .Other);
6203 try writer.writeAll(", sizeof(");6204 try w.writeAll(", sizeof(");
6204 try f.renderType(writer, inst_ty);6205 try f.renderType(w, inst_ty);
6205 try writer.writeAll("));\n");6206 try w.writeAll("));\n");
6206 }6207 }
6207 try f.freeCValue(inst, operand_lval);6208 try f.freeCValue(inst, operand_lval);
6208 return local;6209 return local;
...@@ -6213,11 +6214,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6213,11 +6214,11 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6213 };6214 };
62146215
6215 const local = try f.allocLocal(inst, inst_ty);6216 const local = try f.allocLocal(inst, inst_ty);
6216 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6217 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6217 try f.writeCValue(writer, local, .Other);6218 try f.writeCValue(w, local, .Other);
6218 try a.assign(f, writer);6219 try a.assign(f, w);
6219 try f.writeCValueMember(writer, struct_byval, field_name);6220 try f.writeCValueMember(w, struct_byval, field_name);
6220 try a.end(f, writer);6221 try a.end(f, w);
6221 return local;6222 return local;
6222}6223}
62236224
...@@ -6244,21 +6245,21 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6244,21 +6245,21 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6244 return local;6245 return local;
6245 }6246 }
62466247
6247 const writer = f.object.writer();6248 const w = f.object.writer();
6248 try f.writeCValue(writer, local, .Other);6249 try f.writeCValue(w, local, .Other);
6249 try writer.writeAll(" = ");6250 try w.writeAll(" = ");
62506251
6251 if (!payload_ty.hasRuntimeBits(zcu))6252 if (!payload_ty.hasRuntimeBits(zcu))
6252 try f.writeCValue(writer, operand, .Other)6253 try f.writeCValue(w, operand, .Other)
6253 else if (error_ty.errorSetIsEmpty(zcu))6254 else if (error_ty.errorSetIsEmpty(zcu))
6254 try writer.print("{f}", .{6255 try w.print("{f}", .{
6255 try f.fmtIntLiteralDec(try pt.intValue(try pt.errorIntType(), 0)),6256 try f.fmtIntLiteralDec(try pt.intValue(try pt.errorIntType(), 0)),
6256 })6257 })
6257 else if (operand_is_ptr)6258 else if (operand_is_ptr)
6258 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })6259 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
6259 else6260 else
6260 try f.writeCValueMember(writer, operand, .{ .identifier = "error" });6261 try f.writeCValueMember(w, operand, .{ .identifier = "error" });
6261 try writer.writeAll(";\n");6262 try w.writeAll(";\n");
6262 return local;6263 return local;
6263}6264}
62646265
...@@ -6273,29 +6274,29 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu...@@ -6273,29 +6274,29 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
6273 const operand_ty = f.typeOf(ty_op.operand);6274 const operand_ty = f.typeOf(ty_op.operand);
6274 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;6275 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
62756276
6276 const writer = f.object.writer();6277 const w = f.object.writer();
6277 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {6278 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
6278 if (!is_ptr) return .none;6279 if (!is_ptr) return .none;
62796280
6280 const local = try f.allocLocal(inst, inst_ty);6281 const local = try f.allocLocal(inst, inst_ty);
6281 try f.writeCValue(writer, local, .Other);6282 try f.writeCValue(w, local, .Other);
6282 try writer.writeAll(" = (");6283 try w.writeAll(" = (");
6283 try f.renderType(writer, inst_ty);6284 try f.renderType(w, inst_ty);
6284 try writer.writeByte(')');6285 try w.writeByte(')');
6285 try f.writeCValue(writer, operand, .Other);6286 try f.writeCValue(w, operand, .Other);
6286 try writer.writeAll(";\n");6287 try w.writeAll(";\n");
6287 return local;6288 return local;
6288 }6289 }
62896290
6290 const local = try f.allocLocal(inst, inst_ty);6291 const local = try f.allocLocal(inst, inst_ty);
6291 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6292 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6292 try f.writeCValue(writer, local, .Other);6293 try f.writeCValue(w, local, .Other);
6293 try a.assign(f, writer);6294 try a.assign(f, w);
6294 if (is_ptr) {6295 if (is_ptr) {
6295 try writer.writeByte('&');6296 try w.writeByte('&');
6296 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });6297 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
6297 } else try f.writeCValueMember(writer, operand, .{ .identifier = "payload" });6298 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
6298 try a.end(f, writer);6299 try a.end(f, w);
6299 return local;6300 return local;
6300}6301}
63016302
...@@ -6314,21 +6315,21 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6314,21 +6315,21 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
6314 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {6315 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
6315 .is_null, .payload => {6316 .is_null, .payload => {
6316 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);6317 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);
6317 const writer = f.object.writer();6318 const w = f.object.writer();
6318 const local = try f.allocLocal(inst, inst_ty);6319 const local = try f.allocLocal(inst, inst_ty);
6319 {6320 {
6320 const a = try Assignment.start(f, writer, .bool);6321 const a = try Assignment.start(f, w, .bool);
6321 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });6322 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6322 try a.assign(f, writer);6323 try a.assign(f, w);
6323 try writer.writeAll("false");6324 try w.writeAll("false");
6324 try a.end(f, writer);6325 try a.end(f, w);
6325 }6326 }
6326 {6327 {
6327 const a = try Assignment.start(f, writer, operand_ctype);6328 const a = try Assignment.start(f, w, operand_ctype);
6328 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6329 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6329 try a.assign(f, writer);6330 try a.assign(f, w);
6330 try f.writeCValue(writer, operand, .Other);6331 try f.writeCValue(w, operand, .Other);
6331 try a.end(f, writer);6332 try a.end(f, w);
6332 }6333 }
6333 return local;6334 return local;
6334 },6335 },
...@@ -6350,7 +6351,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6350,7 +6351,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6350 const err = try f.resolveInst(ty_op.operand);6351 const err = try f.resolveInst(ty_op.operand);
6351 try reap(f, inst, &.{ty_op.operand});6352 try reap(f, inst, &.{ty_op.operand});
63526353
6353 const writer = f.object.writer();6354 const w = f.object.writer();
6354 const local = try f.allocLocal(inst, inst_ty);6355 const local = try f.allocLocal(inst, inst_ty);
63556356
6356 if (repr_is_err and err == .local and err.local == local.new_local) {6357 if (repr_is_err and err == .local and err.local == local.new_local) {
...@@ -6359,21 +6360,21 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6359,21 +6360,21 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6359 }6360 }
63606361
6361 if (!repr_is_err) {6362 if (!repr_is_err) {
6362 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));6363 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
6363 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6364 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6364 try a.assign(f, writer);6365 try a.assign(f, w);
6365 try f.object.dg.renderUndefValue(writer, payload_ty, .Other);6366 try f.object.dg.renderUndefValue(w, payload_ty, .Other);
6366 try a.end(f, writer);6367 try a.end(f, w);
6367 }6368 }
6368 {6369 {
6369 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));6370 const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));
6370 if (repr_is_err)6371 if (repr_is_err)
6371 try f.writeCValue(writer, local, .Other)6372 try f.writeCValue(w, local, .Other)
6372 else6373 else
6373 try f.writeCValueMember(writer, local, .{ .identifier = "error" });6374 try f.writeCValueMember(w, local, .{ .identifier = "error" });
6374 try a.assign(f, writer);6375 try a.assign(f, w);
6375 try f.writeCValue(writer, err, .Other);6376 try f.writeCValue(w, err, .Other);
6376 try a.end(f, writer);6377 try a.end(f, w);
6377 }6378 }
6378 return local;6379 return local;
6379}6380}
...@@ -6381,7 +6382,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6381,7 +6382,7 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6381fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {6382fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
6382 const pt = f.object.dg.pt;6383 const pt = f.object.dg.pt;
6383 const zcu = pt.zcu;6384 const zcu = pt.zcu;
6384 const writer = f.object.writer();6385 const w = f.object.writer();
6385 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;6386 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
6386 const inst_ty = f.typeOfIndex(inst);6387 const inst_ty = f.typeOfIndex(inst);
6387 const operand = try f.resolveInst(ty_op.operand);6388 const operand = try f.resolveInst(ty_op.operand);
...@@ -6395,31 +6396,31 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6395,31 +6396,31 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
63956396
6396 // First, set the non-error value.6397 // First, set the non-error value.
6397 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {6398 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
6398 const a = try Assignment.start(f, writer, try f.ctypeFromType(operand_ty, .complete));6399 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));
6399 try f.writeCValueDeref(writer, operand);6400 try f.writeCValueDeref(w, operand);
6400 try a.assign(f, writer);6401 try a.assign(f, w);
6401 try writer.print("{f}", .{try f.fmtIntLiteralDec(no_err)});6402 try w.print("{f}", .{try f.fmtIntLiteralDec(no_err)});
6402 try a.end(f, writer);6403 try a.end(f, w);
6403 return .none;6404 return .none;
6404 }6405 }
6405 {6406 {
6406 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_int_ty, .complete));6407 const a = try Assignment.start(f, w, try f.ctypeFromType(err_int_ty, .complete));
6407 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" });6408 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" });
6408 try a.assign(f, writer);6409 try a.assign(f, w);
6409 try writer.print("{f}", .{try f.fmtIntLiteralDec(no_err)});6410 try w.print("{f}", .{try f.fmtIntLiteralDec(no_err)});
6410 try a.end(f, writer);6411 try a.end(f, w);
6411 }6412 }
64126413
6413 // Then return the payload pointer (only if it is used)6414 // Then return the payload pointer (only if it is used)
6414 if (f.liveness.isUnused(inst)) return .none;6415 if (f.liveness.isUnused(inst)) return .none;
64156416
6416 const local = try f.allocLocal(inst, inst_ty);6417 const local = try f.allocLocal(inst, inst_ty);
6417 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));6418 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6418 try f.writeCValue(writer, local, .Other);6419 try f.writeCValue(w, local, .Other);
6419 try a.assign(f, writer);6420 try a.assign(f, w);
6420 try writer.writeByte('&');6421 try w.writeByte('&');
6421 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" });6422 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
6422 try a.end(f, writer);6423 try a.end(f, w);
6423 return local;6424 return local;
6424}6425}
64256426
...@@ -6450,24 +6451,24 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6450,24 +6451,24 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
6450 const err_ty = inst_ty.errorUnionSet(zcu);6451 const err_ty = inst_ty.errorUnionSet(zcu);
6451 try reap(f, inst, &.{ty_op.operand});6452 try reap(f, inst, &.{ty_op.operand});
64526453
6453 const writer = f.object.writer();6454 const w = f.object.writer();
6454 const local = try f.allocLocal(inst, inst_ty);6455 const local = try f.allocLocal(inst, inst_ty);
6455 if (!repr_is_err) {6456 if (!repr_is_err) {
6456 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));6457 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
6457 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6458 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6458 try a.assign(f, writer);6459 try a.assign(f, w);
6459 try f.writeCValue(writer, payload, .Other);6460 try f.writeCValue(w, payload, .Other);
6460 try a.end(f, writer);6461 try a.end(f, w);
6461 }6462 }
6462 {6463 {
6463 const a = try Assignment.start(f, writer, try f.ctypeFromType(err_ty, .complete));6464 const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));
6464 if (repr_is_err)6465 if (repr_is_err)
6465 try f.writeCValue(writer, local, .Other)6466 try f.writeCValue(w, local, .Other)
6466 else6467 else
6467 try f.writeCValueMember(writer, local, .{ .identifier = "error" });6468 try f.writeCValueMember(w, local, .{ .identifier = "error" });
6468 try a.assign(f, writer);6469 try a.assign(f, w);
6469 try f.object.dg.renderValue(writer, try pt.intValue(try pt.errorIntType(), 0), .Other);6470 try f.object.dg.renderValue(w, try pt.intValue(try pt.errorIntType(), 0), .Other);
6470 try a.end(f, writer);6471 try a.end(f, w);
6471 }6472 }
6472 return local;6473 return local;
6473}6474}
...@@ -6477,7 +6478,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6477,7 +6478,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6477 const zcu = pt.zcu;6478 const zcu = pt.zcu;
6478 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;6479 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
64796480
6480 const writer = f.object.writer();6481 const w = f.object.writer();
6481 const operand = try f.resolveInst(un_op);6482 const operand = try f.resolveInst(un_op);
6482 try reap(f, inst, &.{un_op});6483 try reap(f, inst, &.{un_op});
6483 const operand_ty = f.typeOf(un_op);6484 const operand_ty = f.typeOf(un_op);
...@@ -6486,25 +6487,25 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -6486,25 +6487,25 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
6486 const payload_ty = err_union_ty.errorUnionPayload(zcu);6487 const payload_ty = err_union_ty.errorUnionPayload(zcu);
6487 const error_ty = err_union_ty.errorUnionSet(zcu);6488 const error_ty = err_union_ty.errorUnionSet(zcu);
64886489
6489 const a = try Assignment.start(f, writer, .bool);6490 const a = try Assignment.start(f, w, .bool);
6490 try f.writeCValue(writer, local, .Other);6491 try f.writeCValue(w, local, .Other);
6491 try a.assign(f, writer);6492 try a.assign(f, w);
6492 const err_int_ty = try pt.errorIntType();6493 const err_int_ty = try pt.errorIntType();
6493 if (!error_ty.errorSetIsEmpty(zcu))6494 if (!error_ty.errorSetIsEmpty(zcu))
6494 if (payload_ty.hasRuntimeBits(zcu))6495 if (payload_ty.hasRuntimeBits(zcu))
6495 if (is_ptr)6496 if (is_ptr)
6496 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })6497 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
6497 else6498 else
6498 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })6499 try f.writeCValueMember(w, operand, .{ .identifier = "error" })
6499 else6500 else
6500 try f.writeCValue(writer, operand, .Other)6501 try f.writeCValue(w, operand, .Other)
6501 else6502 else
6502 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);6503 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);
6503 try writer.writeByte(' ');6504 try w.writeByte(' ');
6504 try writer.writeAll(operator);6505 try w.writeAll(operator);
6505 try writer.writeByte(' ');6506 try w.writeByte(' ');
6506 try f.object.dg.renderValue(writer, try pt.intValue(err_int_ty, 0), .Other);6507 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);
6507 try a.end(f, writer);6508 try a.end(f, w);
6508 return local;6509 return local;
6509}6510}
65106511
...@@ -6518,45 +6519,45 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6518,45 +6519,45 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6518 try reap(f, inst, &.{ty_op.operand});6519 try reap(f, inst, &.{ty_op.operand});
6519 const inst_ty = f.typeOfIndex(inst);6520 const inst_ty = f.typeOfIndex(inst);
6520 const ptr_ty = inst_ty.slicePtrFieldType(zcu);6521 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
6521 const writer = f.object.writer();6522 const w = f.object.writer();
6522 const local = try f.allocLocal(inst, inst_ty);6523 const local = try f.allocLocal(inst, inst_ty);
6523 const operand_ty = f.typeOf(ty_op.operand);6524 const operand_ty = f.typeOf(ty_op.operand);
6524 const array_ty = operand_ty.childType(zcu);6525 const array_ty = operand_ty.childType(zcu);
65256526
6526 {6527 {
6527 const a = try Assignment.start(f, writer, try f.ctypeFromType(ptr_ty, .complete));6528 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));
6528 try f.writeCValueMember(writer, local, .{ .identifier = "ptr" });6529 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
6529 try a.assign(f, writer);6530 try a.assign(f, w);
6530 if (operand == .undef) {6531 if (operand == .undef) {
6531 try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);6532 try f.writeCValue(w, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);
6532 } else {6533 } else {
6533 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);6534 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);
6534 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;6535 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
6535 const elem_ty = array_ty.childType(zcu);6536 const elem_ty = array_ty.childType(zcu);
6536 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);6537 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);
6537 if (!ptr_child_ctype.eql(elem_ctype)) {6538 if (!ptr_child_ctype.eql(elem_ctype)) {
6538 try writer.writeByte('(');6539 try w.writeByte('(');
6539 try f.renderCType(writer, ptr_ctype);6540 try f.renderCType(w, ptr_ctype);
6540 try writer.writeByte(')');6541 try w.writeByte(')');
6541 }6542 }
6542 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);6543 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
6543 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;6544 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;
6544 if (operand_child_ctype.info(ctype_pool) == .array) {6545 if (operand_child_ctype.info(ctype_pool) == .array) {
6545 try writer.writeByte('&');6546 try w.writeByte('&');
6546 try f.writeCValueDeref(writer, operand);6547 try f.writeCValueDeref(w, operand);
6547 try writer.print("[{f}]", .{try f.fmtIntLiteralDec(.zero_usize)});6548 try w.print("[{f}]", .{try f.fmtIntLiteralDec(.zero_usize)});
6548 } else try f.writeCValue(writer, operand, .Other);6549 } else try f.writeCValue(w, operand, .Other);
6549 }6550 }
6550 try a.end(f, writer);6551 try a.end(f, w);
6551 }6552 }
6552 {6553 {
6553 const a = try Assignment.start(f, writer, .usize);6554 const a = try Assignment.start(f, w, .usize);
6554 try f.writeCValueMember(writer, local, .{ .identifier = "len" });6555 try f.writeCValueMember(w, local, .{ .identifier = "len" });
6555 try a.assign(f, writer);6556 try a.assign(f, w);
6556 try writer.print("{f}", .{6557 try w.print("{f}", .{
6557 try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))),6558 try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
6558 });6559 });
6559 try a.end(f, writer);6560 try a.end(f, w);
6560 }6561 }
65616562
6562 return local;6563 return local;
...@@ -6583,32 +6584,32 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6583,32 +6584,32 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6583 else6584 else
6584 unreachable;6585 unreachable;
65856586
6586 const writer = f.object.writer();6587 const w = f.object.writer();
6587 const local = try f.allocLocal(inst, inst_ty);6588 const local = try f.allocLocal(inst, inst_ty);
6588 const v = try Vectorize.start(f, inst, writer, operand_ty);6589 const v = try Vectorize.start(f, inst, w, operand_ty);
6589 const a = try Assignment.start(f, writer, try f.ctypeFromType(scalar_ty, .complete));6590 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
6590 try f.writeCValue(writer, local, .Other);6591 try f.writeCValue(w, local, .Other);
6591 try v.elem(f, writer);6592 try v.elem(f, w);
6592 try a.assign(f, writer);6593 try a.assign(f, w);
6593 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {6594 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6594 try writer.writeAll("zig_wrap_");6595 try w.writeAll("zig_wrap_");
6595 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);6596 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
6596 try writer.writeByte('(');6597 try w.writeByte('(');
6597 }6598 }
6598 try writer.writeAll("zig_");6599 try w.writeAll("zig_");
6599 try writer.writeAll(operation);6600 try w.writeAll(operation);
6600 try writer.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));6601 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
6601 try writer.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));6602 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
6602 try writer.writeByte('(');6603 try w.writeByte('(');
6603 try f.writeCValue(writer, operand, .FunctionArgument);6604 try f.writeCValue(w, operand, .FunctionArgument);
6604 try v.elem(f, writer);6605 try v.elem(f, w);
6605 try writer.writeByte(')');6606 try w.writeByte(')');
6606 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {6607 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6607 try f.object.dg.renderBuiltinInfo(writer, inst_scalar_ty, .bits);6608 try f.object.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits);
6608 try writer.writeByte(')');6609 try w.writeByte(')');
6609 }6610 }
6610 try a.end(f, writer);6611 try a.end(f, w);
6611 try v.end(f, inst, writer);6612 try v.end(f, inst, w);
66126613
6613 return local;6614 return local;
6614}6615}
...@@ -6633,27 +6634,27 @@ fn airUnBuiltinCall(...@@ -6633,27 +6634,27 @@ fn airUnBuiltinCall(
6633 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6634 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6634 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6635 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
66356636
6636 const writer = f.object.writer();6637 const w = f.object.writer();
6637 const local = try f.allocLocal(inst, inst_ty);6638 const local = try f.allocLocal(inst, inst_ty);
6638 const v = try Vectorize.start(f, inst, writer, operand_ty);6639 const v = try Vectorize.start(f, inst, w, operand_ty);
6639 if (!ref_ret) {6640 if (!ref_ret) {
6640 try f.writeCValue(writer, local, .Other);6641 try f.writeCValue(w, local, .Other);
6641 try v.elem(f, writer);6642 try v.elem(f, w);
6642 try writer.writeAll(" = ");6643 try w.writeAll(" = ");
6643 }6644 }
6644 try writer.print("zig_{s}_", .{operation});6645 try w.print("zig_{s}_", .{operation});
6645 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6646 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6646 try writer.writeByte('(');6647 try w.writeByte('(');
6647 if (ref_ret) {6648 if (ref_ret) {
6648 try f.writeCValue(writer, local, .FunctionArgument);6649 try f.writeCValue(w, local, .FunctionArgument);
6649 try v.elem(f, writer);6650 try v.elem(f, w);
6650 try writer.writeAll(", ");6651 try w.writeAll(", ");
6651 }6652 }
6652 try f.writeCValue(writer, operand, .FunctionArgument);6653 try f.writeCValue(w, operand, .FunctionArgument);
6653 try v.elem(f, writer);6654 try v.elem(f, w);
6654 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6655 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
6655 try writer.writeAll(");\n");6656 try w.writeAll(");\n");
6656 try v.end(f, inst, writer);6657 try v.end(f, inst, w);
66576658
6658 return local;6659 return local;
6659}6660}
...@@ -6683,31 +6684,31 @@ fn airBinBuiltinCall(...@@ -6683,31 +6684,31 @@ fn airBinBuiltinCall(
6683 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6684 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6684 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6685 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
66856686
6686 const writer = f.object.writer();6687 const w = f.object.writer();
6687 const local = try f.allocLocal(inst, inst_ty);6688 const local = try f.allocLocal(inst, inst_ty);
6688 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6689 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6689 const v = try Vectorize.start(f, inst, writer, operand_ty);6690 const v = try Vectorize.start(f, inst, w, operand_ty);
6690 if (!ref_ret) {6691 if (!ref_ret) {
6691 try f.writeCValue(writer, local, .Other);6692 try f.writeCValue(w, local, .Other);
6692 try v.elem(f, writer);6693 try v.elem(f, w);
6693 try writer.writeAll(" = ");6694 try w.writeAll(" = ");
6694 }6695 }
6695 try writer.print("zig_{s}_", .{operation});6696 try w.print("zig_{s}_", .{operation});
6696 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6697 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6697 try writer.writeByte('(');6698 try w.writeByte('(');
6698 if (ref_ret) {6699 if (ref_ret) {
6699 try f.writeCValue(writer, local, .FunctionArgument);6700 try f.writeCValue(w, local, .FunctionArgument);
6700 try v.elem(f, writer);6701 try v.elem(f, w);
6701 try writer.writeAll(", ");6702 try w.writeAll(", ");
6702 }6703 }
6703 try f.writeCValue(writer, lhs, .FunctionArgument);6704 try f.writeCValue(w, lhs, .FunctionArgument);
6704 try v.elem(f, writer);6705 try v.elem(f, w);
6705 try writer.writeAll(", ");6706 try w.writeAll(", ");
6706 try f.writeCValue(writer, rhs, .FunctionArgument);6707 try f.writeCValue(w, rhs, .FunctionArgument);
6707 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, writer);6708 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
6708 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6709 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
6709 try writer.writeAll(");\n");6710 try w.writeAll(");\n");
6710 try v.end(f, inst, writer);6711 try v.end(f, inst, w);
67116712
6712 return local;6713 return local;
6713}6714}
...@@ -6734,38 +6735,38 @@ fn airCmpBuiltinCall(...@@ -6734,38 +6735,38 @@ fn airCmpBuiltinCall(
6734 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);6735 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6735 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;6736 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
67366737
6737 const writer = f.object.writer();6738 const w = f.object.writer();
6738 const local = try f.allocLocal(inst, inst_ty);6739 const local = try f.allocLocal(inst, inst_ty);
6739 const v = try Vectorize.start(f, inst, writer, operand_ty);6740 const v = try Vectorize.start(f, inst, w, operand_ty);
6740 if (!ref_ret) {6741 if (!ref_ret) {
6741 try f.writeCValue(writer, local, .Other);6742 try f.writeCValue(w, local, .Other);
6742 try v.elem(f, writer);6743 try v.elem(f, w);
6743 try writer.writeAll(" = ");6744 try w.writeAll(" = ");
6744 }6745 }
6745 try writer.print("zig_{s}_", .{switch (operation) {6746 try w.print("zig_{s}_", .{switch (operation) {
6746 else => @tagName(operation),6747 else => @tagName(operation),
6747 .operator => compareOperatorAbbrev(operator),6748 .operator => compareOperatorAbbrev(operator),
6748 }});6749 }});
6749 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);6750 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6750 try writer.writeByte('(');6751 try w.writeByte('(');
6751 if (ref_ret) {6752 if (ref_ret) {
6752 try f.writeCValue(writer, local, .FunctionArgument);6753 try f.writeCValue(w, local, .FunctionArgument);
6753 try v.elem(f, writer);6754 try v.elem(f, w);
6754 try writer.writeAll(", ");6755 try w.writeAll(", ");
6755 }6756 }
6756 try f.writeCValue(writer, lhs, .FunctionArgument);6757 try f.writeCValue(w, lhs, .FunctionArgument);
6757 try v.elem(f, writer);6758 try v.elem(f, w);
6758 try writer.writeAll(", ");6759 try w.writeAll(", ");
6759 try f.writeCValue(writer, rhs, .FunctionArgument);6760 try f.writeCValue(w, rhs, .FunctionArgument);
6760 try v.elem(f, writer);6761 try v.elem(f, w);
6761 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, info);6762 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
6762 try writer.writeByte(')');6763 try w.writeByte(')');
6763 if (!ref_ret) try writer.print("{s}{f}", .{6764 if (!ref_ret) try w.print("{s}{f}", .{
6764 compareOperatorC(operator),6765 compareOperatorC(operator),
6765 try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)),6766 try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)),
6766 });6767 });
6767 try writer.writeAll(";\n");6768 try w.writeAll(";\n");
6768 try v.end(f, inst, writer);6769 try v.end(f, inst, w);
67696770
6770 return local;6771 return local;
6771}6772}
...@@ -6783,7 +6784,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6783,7 +6784,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6783 const ty = ptr_ty.childType(zcu);6784 const ty = ptr_ty.childType(zcu);
6784 const ctype = try f.ctypeFromType(ty, .complete);6785 const ctype = try f.ctypeFromType(ty, .complete);
67856786
6786 const writer = f.object.writer();6787 const w = f.object.writer();
6787 const new_value_mat = try Materialize.start(f, inst, ty, new_value);6788 const new_value_mat = try Materialize.start(f, inst, ty, new_value);
6788 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });6789 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
67896790
...@@ -6795,76 +6796,76 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6795,76 +6796,76 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6795 const local = try f.allocLocal(inst, inst_ty);6796 const local = try f.allocLocal(inst, inst_ty);
6796 if (inst_ty.isPtrLikeOptional(zcu)) {6797 if (inst_ty.isPtrLikeOptional(zcu)) {
6797 {6798 {
6798 const a = try Assignment.start(f, writer, ctype);6799 const a = try Assignment.start(f, w, ctype);
6799 try f.writeCValue(writer, local, .Other);6800 try f.writeCValue(w, local, .Other);
6800 try a.assign(f, writer);6801 try a.assign(f, w);
6801 try f.writeCValue(writer, expected_value, .Other);6802 try f.writeCValue(w, expected_value, .Other);
6802 try a.end(f, writer);6803 try a.end(f, w);
6803 }6804 }
68046805
6805 try writer.writeAll("if (");6806 try w.writeAll("if (");
6806 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});6807 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6807 try f.renderType(writer, ty);6808 try f.renderType(w, ty);
6808 try writer.writeByte(')');6809 try w.writeByte(')');
6809 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6810 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6810 try writer.writeAll(" *)");6811 try w.writeAll(" *)");
6811 try f.writeCValue(writer, ptr, .Other);6812 try f.writeCValue(w, ptr, .Other);
6812 try writer.writeAll(", ");6813 try w.writeAll(", ");
6813 try f.writeCValue(writer, local, .FunctionArgument);6814 try f.writeCValue(w, local, .FunctionArgument);
6814 try writer.writeAll(", ");6815 try w.writeAll(", ");
6815 try new_value_mat.mat(f, writer);6816 try new_value_mat.mat(f, w);
6816 try writer.writeAll(", ");6817 try w.writeAll(", ");
6817 try writeMemoryOrder(writer, extra.successOrder());6818 try writeMemoryOrder(w, extra.successOrder());
6818 try writer.writeAll(", ");6819 try w.writeAll(", ");
6819 try writeMemoryOrder(writer, extra.failureOrder());6820 try writeMemoryOrder(w, extra.failureOrder());
6820 try writer.writeAll(", ");6821 try w.writeAll(", ");
6821 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6822 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
6822 try writer.writeAll(", ");6823 try w.writeAll(", ");
6823 try f.renderType(writer, repr_ty);6824 try f.renderType(w, repr_ty);
6824 try writer.writeByte(')');6825 try w.writeByte(')');
6825 try writer.writeAll(") {\n");6826 try w.writeAll(") {\n");
6826 f.object.indent_writer.pushIndent();6827 f.object.indent_writer.pushIndent();
6827 {6828 {
6828 const a = try Assignment.start(f, writer, ctype);6829 const a = try Assignment.start(f, w, ctype);
6829 try f.writeCValue(writer, local, .Other);6830 try f.writeCValue(w, local, .Other);
6830 try a.assign(f, writer);6831 try a.assign(f, w);
6831 try writer.writeAll("NULL");6832 try w.writeAll("NULL");
6832 try a.end(f, writer);6833 try a.end(f, w);
6833 }6834 }
6834 f.object.indent_writer.popIndent();6835 f.object.indent_writer.popIndent();
6835 try writer.writeAll("}\n");6836 try w.writeAll("}\n");
6836 } else {6837 } else {
6837 {6838 {
6838 const a = try Assignment.start(f, writer, ctype);6839 const a = try Assignment.start(f, w, ctype);
6839 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6840 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6840 try a.assign(f, writer);6841 try a.assign(f, w);
6841 try f.writeCValue(writer, expected_value, .Other);6842 try f.writeCValue(w, expected_value, .Other);
6842 try a.end(f, writer);6843 try a.end(f, w);
6843 }6844 }
6844 {6845 {
6845 const a = try Assignment.start(f, writer, .bool);6846 const a = try Assignment.start(f, w, .bool);
6846 try f.writeCValueMember(writer, local, .{ .identifier = "is_null" });6847 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6847 try a.assign(f, writer);6848 try a.assign(f, w);
6848 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});6849 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6849 try f.renderType(writer, ty);6850 try f.renderType(w, ty);
6850 try writer.writeByte(')');6851 try w.writeByte(')');
6851 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6852 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6852 try writer.writeAll(" *)");6853 try w.writeAll(" *)");
6853 try f.writeCValue(writer, ptr, .Other);6854 try f.writeCValue(w, ptr, .Other);
6854 try writer.writeAll(", ");6855 try w.writeAll(", ");
6855 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });6856 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6856 try writer.writeAll(", ");6857 try w.writeAll(", ");
6857 try new_value_mat.mat(f, writer);6858 try new_value_mat.mat(f, w);
6858 try writer.writeAll(", ");6859 try w.writeAll(", ");
6859 try writeMemoryOrder(writer, extra.successOrder());6860 try writeMemoryOrder(w, extra.successOrder());
6860 try writer.writeAll(", ");6861 try w.writeAll(", ");
6861 try writeMemoryOrder(writer, extra.failureOrder());6862 try writeMemoryOrder(w, extra.failureOrder());
6862 try writer.writeAll(", ");6863 try w.writeAll(", ");
6863 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6864 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
6864 try writer.writeAll(", ");6865 try w.writeAll(", ");
6865 try f.renderType(writer, repr_ty);6866 try f.renderType(w, repr_ty);
6866 try writer.writeByte(')');6867 try w.writeByte(')');
6867 try a.end(f, writer);6868 try a.end(f, w);
6868 }6869 }
6869 }6870 }
6870 try new_value_mat.end(f, inst);6871 try new_value_mat.end(f, inst);
...@@ -6888,7 +6889,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6888,7 +6889,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6888 const ptr = try f.resolveInst(pl_op.operand);6889 const ptr = try f.resolveInst(pl_op.operand);
6889 const operand = try f.resolveInst(extra.operand);6890 const operand = try f.resolveInst(extra.operand);
68906891
6891 const writer = f.object.writer();6892 const w = f.object.writer();
6892 const operand_mat = try Materialize.start(f, inst, ty, operand);6893 const operand_mat = try Materialize.start(f, inst, ty, operand);
6893 try reap(f, inst, &.{ pl_op.operand, extra.operand });6894 try reap(f, inst, &.{ pl_op.operand, extra.operand });
68946895
...@@ -6898,31 +6899,31 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6898,31 +6899,31 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6898 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;6899 const repr_ty = if (is_float) pt.intType(.unsigned, repr_bits) catch unreachable else ty;
68996900
6900 const local = try f.allocLocal(inst, inst_ty);6901 const local = try f.allocLocal(inst, inst_ty);
6901 try writer.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});6902 try w.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
6902 if (is_float) try writer.writeAll("_float") else if (is_128) try writer.writeAll("_int128");6903 if (is_float) try w.writeAll("_float") else if (is_128) try w.writeAll("_int128");
6903 try writer.writeByte('(');6904 try w.writeByte('(');
6904 try f.writeCValue(writer, local, .Other);6905 try f.writeCValue(w, local, .Other);
6905 try writer.writeAll(", (");6906 try w.writeAll(", (");
6906 const use_atomic = switch (extra.op()) {6907 const use_atomic = switch (extra.op()) {
6907 else => true,6908 else => true,
6908 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.6909 // These are missing from stdatomic.h, so no atomic types unless a fallback is used.
6909 .Nand, .Min, .Max => is_float or is_128,6910 .Nand, .Min, .Max => is_float or is_128,
6910 };6911 };
6911 if (use_atomic) try writer.writeAll("zig_atomic(");6912 if (use_atomic) try w.writeAll("zig_atomic(");
6912 try f.renderType(writer, ty);6913 try f.renderType(w, ty);
6913 if (use_atomic) try writer.writeByte(')');6914 if (use_atomic) try w.writeByte(')');
6914 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6915 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6915 try writer.writeAll(" *)");6916 try w.writeAll(" *)");
6916 try f.writeCValue(writer, ptr, .Other);6917 try f.writeCValue(w, ptr, .Other);
6917 try writer.writeAll(", ");6918 try w.writeAll(", ");
6918 try operand_mat.mat(f, writer);6919 try operand_mat.mat(f, w);
6919 try writer.writeAll(", ");6920 try w.writeAll(", ");
6920 try writeMemoryOrder(writer, extra.ordering());6921 try writeMemoryOrder(w, extra.ordering());
6921 try writer.writeAll(", ");6922 try w.writeAll(", ");
6922 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6923 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
6923 try writer.writeAll(", ");6924 try w.writeAll(", ");
6924 try f.renderType(writer, repr_ty);6925 try f.renderType(w, repr_ty);
6925 try writer.writeAll(");\n");6926 try w.writeAll(");\n");
6926 try operand_mat.end(f, inst);6927 try operand_mat.end(f, inst);
69276928
6928 if (f.liveness.isUnused(inst)) {6929 if (f.liveness.isUnused(inst)) {
...@@ -6948,24 +6949,24 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6948,24 +6949,24 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6948 ty;6949 ty;
69496950
6950 const inst_ty = f.typeOfIndex(inst);6951 const inst_ty = f.typeOfIndex(inst);
6951 const writer = f.object.writer();6952 const w = f.object.writer();
6952 const local = try f.allocLocal(inst, inst_ty);6953 const local = try f.allocLocal(inst, inst_ty);
69536954
6954 try writer.writeAll("zig_atomic_load(");6955 try w.writeAll("zig_atomic_load(");
6955 try f.writeCValue(writer, local, .Other);6956 try f.writeCValue(w, local, .Other);
6956 try writer.writeAll(", (zig_atomic(");6957 try w.writeAll(", (zig_atomic(");
6957 try f.renderType(writer, ty);6958 try f.renderType(w, ty);
6958 try writer.writeByte(')');6959 try w.writeByte(')');
6959 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6960 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6960 try writer.writeAll(" *)");6961 try w.writeAll(" *)");
6961 try f.writeCValue(writer, ptr, .Other);6962 try f.writeCValue(w, ptr, .Other);
6962 try writer.writeAll(", ");6963 try w.writeAll(", ");
6963 try writeMemoryOrder(writer, atomic_load.order);6964 try writeMemoryOrder(w, atomic_load.order);
6964 try writer.writeAll(", ");6965 try w.writeAll(", ");
6965 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);6966 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
6966 try writer.writeAll(", ");6967 try w.writeAll(", ");
6967 try f.renderType(writer, repr_ty);6968 try f.renderType(w, repr_ty);
6968 try writer.writeAll(");\n");6969 try w.writeAll(");\n");
69696970
6970 return local;6971 return local;
6971}6972}
...@@ -6979,7 +6980,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6979,7 +6980,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6979 const ptr = try f.resolveInst(bin_op.lhs);6980 const ptr = try f.resolveInst(bin_op.lhs);
6980 const element = try f.resolveInst(bin_op.rhs);6981 const element = try f.resolveInst(bin_op.rhs);
69816982
6982 const writer = f.object.writer();6983 const w = f.object.writer();
6983 const element_mat = try Materialize.start(f, inst, ty, element);6984 const element_mat = try Materialize.start(f, inst, ty, element);
6984 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });6985 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
69856986
...@@ -6988,31 +6989,31 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6988,31 +6989,31 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6988 else6989 else
6989 ty;6990 ty;
69906991
6991 try writer.writeAll("zig_atomic_store((zig_atomic(");6992 try w.writeAll("zig_atomic_store((zig_atomic(");
6992 try f.renderType(writer, ty);6993 try f.renderType(w, ty);
6993 try writer.writeByte(')');6994 try w.writeByte(')');
6994 if (ptr_ty.isVolatilePtr(zcu)) try writer.writeAll(" volatile");6995 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6995 try writer.writeAll(" *)");6996 try w.writeAll(" *)");
6996 try f.writeCValue(writer, ptr, .Other);6997 try f.writeCValue(w, ptr, .Other);
6997 try writer.writeAll(", ");6998 try w.writeAll(", ");
6998 try element_mat.mat(f, writer);6999 try element_mat.mat(f, w);
6999 try writer.print(", {s}, ", .{order});7000 try w.print(", {s}, ", .{order});
7000 try f.object.dg.renderTypeForBuiltinFnName(writer, ty);7001 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
7001 try writer.writeAll(", ");7002 try w.writeAll(", ");
7002 try f.renderType(writer, repr_ty);7003 try f.renderType(w, repr_ty);
7003 try writer.writeAll(");\n");7004 try w.writeAll(");\n");
7004 try element_mat.end(f, inst);7005 try element_mat.end(f, inst);
70057006
7006 return .none;7007 return .none;
7007}7008}
70087009
7009fn writeSliceOrPtr(f: *Function, writer: anytype, ptr: CValue, ptr_ty: Type) !void {7010fn writeSliceOrPtr(f: *Function, w: *Writer, ptr: CValue, ptr_ty: Type) !void {
7010 const pt = f.object.dg.pt;7011 const pt = f.object.dg.pt;
7011 const zcu = pt.zcu;7012 const zcu = pt.zcu;
7012 if (ptr_ty.isSlice(zcu)) {7013 if (ptr_ty.isSlice(zcu)) {
7013 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" });7014 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" });
7014 } else {7015 } else {
7015 try f.writeCValue(writer, ptr, .FunctionArgument);7016 try f.writeCValue(w, ptr, .FunctionArgument);
7016 }7017 }
7017}7018}
70187019
...@@ -7026,7 +7027,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7026,7 +7027,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
7026 const elem_ty = f.typeOf(bin_op.rhs);7027 const elem_ty = f.typeOf(bin_op.rhs);
7027 const elem_abi_size = elem_ty.abiSize(zcu);7028 const elem_abi_size = elem_ty.abiSize(zcu);
7028 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false;7029 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndefDeep(zcu) else false;
7029 const writer = f.object.writer();7030 const w = f.object.writer();
70307031
7031 if (val_is_undef) {7032 if (val_is_undef) {
7032 if (!safety) {7033 if (!safety) {
...@@ -7034,24 +7035,24 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7034,24 +7035,24 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
7034 return .none;7035 return .none;
7035 }7036 }
70367037
7037 try writer.writeAll("memset(");7038 try w.writeAll("memset(");
7038 switch (dest_ty.ptrSize(zcu)) {7039 switch (dest_ty.ptrSize(zcu)) {
7039 .slice => {7040 .slice => {
7040 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });7041 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
7041 try writer.writeAll(", 0xaa, ");7042 try w.writeAll(", 0xaa, ");
7042 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7043 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
7043 if (elem_abi_size > 1) {7044 if (elem_abi_size > 1) {
7044 try writer.print(" * {d});\n", .{elem_abi_size});7045 try w.print(" * {d});\n", .{elem_abi_size});
7045 } else {7046 } else {
7046 try writer.writeAll(");\n");7047 try w.writeAll(");\n");
7047 }7048 }
7048 },7049 },
7049 .one => {7050 .one => {
7050 const array_ty = dest_ty.childType(zcu);7051 const array_ty = dest_ty.childType(zcu);
7051 const len = array_ty.arrayLen(zcu) * elem_abi_size;7052 const len = array_ty.arrayLen(zcu) * elem_abi_size;
70527053
7053 try f.writeCValue(writer, dest_slice, .FunctionArgument);7054 try f.writeCValue(w, dest_slice, .FunctionArgument);
7054 try writer.print(", 0xaa, {d});\n", .{len});7055 try w.print(", 0xaa, {d});\n", .{len});
7055 },7056 },
7056 .many, .c => unreachable,7057 .many, .c => unreachable,
7057 }7058 }
...@@ -7072,38 +7073,38 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7072,38 +7073,38 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
70727073
7073 const index = try f.allocLocal(inst, .usize);7074 const index = try f.allocLocal(inst, .usize);
70747075
7075 try writer.writeAll("for (");7076 try w.writeAll("for (");
7076 try f.writeCValue(writer, index, .Other);7077 try f.writeCValue(w, index, .Other);
7077 try writer.writeAll(" = ");7078 try w.writeAll(" = ");
7078 try f.object.dg.renderValue(writer, .zero_usize, .Other);7079 try f.object.dg.renderValue(w, .zero_usize, .Other);
7079 try writer.writeAll("; ");7080 try w.writeAll("; ");
7080 try f.writeCValue(writer, index, .Other);7081 try f.writeCValue(w, index, .Other);
7081 try writer.writeAll(" != ");7082 try w.writeAll(" != ");
7082 switch (dest_ty.ptrSize(zcu)) {7083 switch (dest_ty.ptrSize(zcu)) {
7083 .slice => {7084 .slice => {
7084 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7085 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
7085 },7086 },
7086 .one => {7087 .one => {
7087 const array_ty = dest_ty.childType(zcu);7088 const array_ty = dest_ty.childType(zcu);
7088 try writer.print("{d}", .{array_ty.arrayLen(zcu)});7089 try w.print("{d}", .{array_ty.arrayLen(zcu)});
7089 },7090 },
7090 .many, .c => unreachable,7091 .many, .c => unreachable,
7091 }7092 }
7092 try writer.writeAll("; ++");7093 try w.writeAll("; ++");
7093 try f.writeCValue(writer, index, .Other);7094 try f.writeCValue(w, index, .Other);
7094 try writer.writeAll(") ");7095 try w.writeAll(") ");
70957096
7096 const a = try Assignment.start(f, writer, try f.ctypeFromType(elem_ty, .complete));7097 const a = try Assignment.start(f, w, try f.ctypeFromType(elem_ty, .complete));
7097 try writer.writeAll("((");7098 try w.writeAll("((");
7098 try f.renderType(writer, elem_ptr_ty);7099 try f.renderType(w, elem_ptr_ty);
7099 try writer.writeByte(')');7100 try w.writeByte(')');
7100 try writeSliceOrPtr(f, writer, dest_slice, dest_ty);7101 try writeSliceOrPtr(f, w, dest_slice, dest_ty);
7101 try writer.writeAll(")[");7102 try w.writeAll(")[");
7102 try f.writeCValue(writer, index, .Other);7103 try f.writeCValue(w, index, .Other);
7103 try writer.writeByte(']');7104 try w.writeByte(']');
7104 try a.assign(f, writer);7105 try a.assign(f, w);
7105 try f.writeCValue(writer, value, .Other);7106 try f.writeCValue(w, value, .Other);
7106 try a.end(f, writer);7107 try a.end(f, w);
71077108
7108 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7109 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
7109 try freeLocal(f, inst, index.new_local, null);7110 try freeLocal(f, inst, index.new_local, null);
...@@ -7113,24 +7114,24 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {...@@ -7113,24 +7114,24 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
71137114
7114 const bitcasted = try bitcast(f, .u8, value, elem_ty);7115 const bitcasted = try bitcast(f, .u8, value, elem_ty);
71157116
7116 try writer.writeAll("memset(");7117 try w.writeAll("memset(");
7117 switch (dest_ty.ptrSize(zcu)) {7118 switch (dest_ty.ptrSize(zcu)) {
7118 .slice => {7119 .slice => {
7119 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" });7120 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
7120 try writer.writeAll(", ");7121 try w.writeAll(", ");
7121 try f.writeCValue(writer, bitcasted, .FunctionArgument);7122 try f.writeCValue(w, bitcasted, .FunctionArgument);
7122 try writer.writeAll(", ");7123 try w.writeAll(", ");
7123 try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" });7124 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
7124 try writer.writeAll(");\n");7125 try w.writeAll(");\n");
7125 },7126 },
7126 .one => {7127 .one => {
7127 const array_ty = dest_ty.childType(zcu);7128 const array_ty = dest_ty.childType(zcu);
7128 const len = array_ty.arrayLen(zcu) * elem_abi_size;7129 const len = array_ty.arrayLen(zcu) * elem_abi_size;
71297130
7130 try f.writeCValue(writer, dest_slice, .FunctionArgument);7131 try f.writeCValue(w, dest_slice, .FunctionArgument);
7131 try writer.writeAll(", ");7132 try w.writeAll(", ");
7132 try f.writeCValue(writer, bitcasted, .FunctionArgument);7133 try f.writeCValue(w, bitcasted, .FunctionArgument);
7133 try writer.print(", {d});\n", .{len});7134 try w.print(", {d});\n", .{len});
7134 },7135 },
7135 .many, .c => unreachable,7136 .many, .c => unreachable,
7136 }7137 }
...@@ -7147,36 +7148,36 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV...@@ -7147,36 +7148,36 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CV
7147 const src_ptr = try f.resolveInst(bin_op.rhs);7148 const src_ptr = try f.resolveInst(bin_op.rhs);
7148 const dest_ty = f.typeOf(bin_op.lhs);7149 const dest_ty = f.typeOf(bin_op.lhs);
7149 const src_ty = f.typeOf(bin_op.rhs);7150 const src_ty = f.typeOf(bin_op.rhs);
7150 const writer = f.object.writer();7151 const w = f.object.writer();
71517152
7152 if (dest_ty.ptrSize(zcu) != .one) {7153 if (dest_ty.ptrSize(zcu) != .one) {
7153 try writer.writeAll("if (");7154 try w.writeAll("if (");
7154 try writeArrayLen(f, writer, dest_ptr, dest_ty);7155 try writeArrayLen(f, w, dest_ptr, dest_ty);
7155 try writer.writeAll(" != 0) ");7156 try w.writeAll(" != 0) ");
7156 }7157 }
7157 try writer.writeAll(function_paren);7158 try w.writeAll(function_paren);
7158 try writeSliceOrPtr(f, writer, dest_ptr, dest_ty);7159 try writeSliceOrPtr(f, w, dest_ptr, dest_ty);
7159 try writer.writeAll(", ");7160 try w.writeAll(", ");
7160 try writeSliceOrPtr(f, writer, src_ptr, src_ty);7161 try writeSliceOrPtr(f, w, src_ptr, src_ty);
7161 try writer.writeAll(", ");7162 try w.writeAll(", ");
7162 try writeArrayLen(f, writer, dest_ptr, dest_ty);7163 try writeArrayLen(f, w, dest_ptr, dest_ty);
7163 try writer.writeAll(" * sizeof(");7164 try w.writeAll(" * sizeof(");
7164 try f.renderType(writer, dest_ty.elemType2(zcu));7165 try f.renderType(w, dest_ty.elemType2(zcu));
7165 try writer.writeAll("));\n");7166 try w.writeAll("));\n");
71667167
7167 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });7168 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
7168 return .none;7169 return .none;
7169}7170}
71707171
7171fn writeArrayLen(f: *Function, writer: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void {7172fn writeArrayLen(f: *Function, alw: ArrayListWriter, dest_ptr: CValue, dest_ty: Type) !void {
7172 const pt = f.object.dg.pt;7173 const pt = f.object.dg.pt;
7173 const zcu = pt.zcu;7174 const zcu = pt.zcu;
7174 switch (dest_ty.ptrSize(zcu)) {7175 switch (dest_ty.ptrSize(zcu)) {
7175 .one => try writer.print("{f}", .{7176 .one => try alw.print("{f}", .{
7176 try f.fmtIntLiteralDec(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),7177 try f.fmtIntLiteralDec(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),
7177 }),7178 }),
7178 .many, .c => unreachable,7179 .many, .c => unreachable,
7179 .slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),7180 .slice => try f.writeCValueMember(alw, dest_ptr, .{ .identifier = "len" }),
7180 }7181 }
7181}7182}
71827183
...@@ -7193,12 +7194,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7193,12 +7194,12 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7193 if (layout.tag_size == 0) return .none;7194 if (layout.tag_size == 0) return .none;
7194 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;7195 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
71957196
7196 const writer = f.object.writer();7197 const w = f.object.writer();
7197 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));7198 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
7198 try f.writeCValueDerefMember(writer, union_ptr, .{ .identifier = "tag" });7199 try f.writeCValueDerefMember(w, union_ptr, .{ .identifier = "tag" });
7199 try a.assign(f, writer);7200 try a.assign(f, w);
7200 try f.writeCValue(writer, new_tag, .Other);7201 try f.writeCValue(w, new_tag, .Other);
7201 try a.end(f, writer);7202 try a.end(f, w);
7202 return .none;7203 return .none;
7203}7204}
72047205
...@@ -7215,13 +7216,13 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7215,13 +7216,13 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7215 if (layout.tag_size == 0) return .none;7216 if (layout.tag_size == 0) return .none;
72167217
7217 const inst_ty = f.typeOfIndex(inst);7218 const inst_ty = f.typeOfIndex(inst);
7218 const writer = f.object.writer();7219 const w = f.object.writer();
7219 const local = try f.allocLocal(inst, inst_ty);7220 const local = try f.allocLocal(inst, inst_ty);
7220 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_ty, .complete));7221 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
7221 try f.writeCValue(writer, local, .Other);7222 try f.writeCValue(w, local, .Other);
7222 try a.assign(f, writer);7223 try a.assign(f, w);
7223 try f.writeCValueMember(writer, operand, .{ .identifier = "tag" });7224 try f.writeCValueMember(w, operand, .{ .identifier = "tag" });
7224 try a.end(f, writer);7225 try a.end(f, w);
7225 return local;7226 return local;
7226}7227}
72277228
...@@ -7233,14 +7234,14 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7233,14 +7234,14 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7233 const operand = try f.resolveInst(un_op);7234 const operand = try f.resolveInst(un_op);
7234 try reap(f, inst, &.{un_op});7235 try reap(f, inst, &.{un_op});
72357236
7236 const writer = f.object.writer();7237 const w = f.object.writer();
7237 const local = try f.allocLocal(inst, inst_ty);7238 const local = try f.allocLocal(inst, inst_ty);
7238 try f.writeCValue(writer, local, .Other);7239 try f.writeCValue(w, local, .Other);
7239 try writer.print(" = {s}(", .{7240 try w.print(" = {s}(", .{
7240 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),7241 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),
7241 });7242 });
7242 try f.writeCValue(writer, operand, .Other);7243 try f.writeCValue(w, operand, .Other);
7243 try writer.writeAll(");\n");7244 try w.writeAll(");\n");
72447245
7245 return local;7246 return local;
7246}7247}
...@@ -7248,16 +7249,16 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7248,16 +7249,16 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
7248fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {7249fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
7249 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;7250 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
72507251
7251 const writer = f.object.writer();7252 const w = f.object.writer();
7252 const inst_ty = f.typeOfIndex(inst);7253 const inst_ty = f.typeOfIndex(inst);
7253 const operand = try f.resolveInst(un_op);7254 const operand = try f.resolveInst(un_op);
7254 try reap(f, inst, &.{un_op});7255 try reap(f, inst, &.{un_op});
7255 const local = try f.allocLocal(inst, inst_ty);7256 const local = try f.allocLocal(inst, inst_ty);
7256 try f.writeCValue(writer, local, .Other);7257 try f.writeCValue(w, local, .Other);
72577258
7258 try writer.writeAll(" = zig_errorName[");7259 try w.writeAll(" = zig_errorName[");
7259 try f.writeCValue(writer, operand, .Other);7260 try f.writeCValue(w, operand, .Other);
7260 try writer.writeAll(" - 1];\n");7261 try w.writeAll(" - 1];\n");
7261 return local;7262 return local;
7262}7263}
72637264
...@@ -7272,16 +7273,16 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7272,16 +7273,16 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
7272 const inst_ty = f.typeOfIndex(inst);7273 const inst_ty = f.typeOfIndex(inst);
7273 const inst_scalar_ty = inst_ty.scalarType(zcu);7274 const inst_scalar_ty = inst_ty.scalarType(zcu);
72747275
7275 const writer = f.object.writer();7276 const w = f.object.writer();
7276 const local = try f.allocLocal(inst, inst_ty);7277 const local = try f.allocLocal(inst, inst_ty);
7277 const v = try Vectorize.start(f, inst, writer, inst_ty);7278 const v = try Vectorize.start(f, inst, w, inst_ty);
7278 const a = try Assignment.start(f, writer, try f.ctypeFromType(inst_scalar_ty, .complete));7279 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_scalar_ty, .complete));
7279 try f.writeCValue(writer, local, .Other);7280 try f.writeCValue(w, local, .Other);
7280 try v.elem(f, writer);7281 try v.elem(f, w);
7281 try a.assign(f, writer);7282 try a.assign(f, w);
7282 try f.writeCValue(writer, operand, .Other);7283 try f.writeCValue(w, operand, .Other);
7283 try a.end(f, writer);7284 try a.end(f, w);
7284 try v.end(f, inst, writer);7285 try v.end(f, inst, w);
72857286
7286 return local;7287 return local;
7287}7288}
...@@ -7297,22 +7298,22 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7297,22 +7298,22 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
72977298
7298 const inst_ty = f.typeOfIndex(inst);7299 const inst_ty = f.typeOfIndex(inst);
72997300
7300 const writer = f.object.writer();7301 const w = f.object.writer();
7301 const local = try f.allocLocal(inst, inst_ty);7302 const local = try f.allocLocal(inst, inst_ty);
7302 const v = try Vectorize.start(f, inst, writer, inst_ty);7303 const v = try Vectorize.start(f, inst, w, inst_ty);
7303 try f.writeCValue(writer, local, .Other);7304 try f.writeCValue(w, local, .Other);
7304 try v.elem(f, writer);7305 try v.elem(f, w);
7305 try writer.writeAll(" = ");7306 try w.writeAll(" = ");
7306 try f.writeCValue(writer, pred, .Other);7307 try f.writeCValue(w, pred, .Other);
7307 try v.elem(f, writer);7308 try v.elem(f, w);
7308 try writer.writeAll(" ? ");7309 try w.writeAll(" ? ");
7309 try f.writeCValue(writer, lhs, .Other);7310 try f.writeCValue(w, lhs, .Other);
7310 try v.elem(f, writer);7311 try v.elem(f, w);
7311 try writer.writeAll(" : ");7312 try w.writeAll(" : ");
7312 try f.writeCValue(writer, rhs, .Other);7313 try f.writeCValue(w, rhs, .Other);
7313 try v.elem(f, writer);7314 try v.elem(f, w);
7314 try writer.writeAll(";\n");7315 try w.writeAll(";\n");
7315 try v.end(f, inst, writer);7316 try v.end(f, inst, w);
73167317
7317 return local;7318 return local;
7318}7319}
...@@ -7326,24 +7327,24 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7326,24 +7327,24 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7326 const operand = try f.resolveInst(unwrapped.operand);7327 const operand = try f.resolveInst(unwrapped.operand);
7327 const inst_ty = unwrapped.result_ty;7328 const inst_ty = unwrapped.result_ty;
73287329
7329 const writer = f.object.writer();7330 const w = f.object.writer();
7330 const local = try f.allocLocal(inst, inst_ty);7331 const local = try f.allocLocal(inst, inst_ty);
7331 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand7332 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
7332 for (mask, 0..) |mask_elem, out_idx| {7333 for (mask, 0..) |mask_elem, out_idx| {
7333 try f.writeCValue(writer, local, .Other);7334 try f.writeCValue(w, local, .Other);
7334 try writer.writeByte('[');7335 try w.writeByte('[');
7335 try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other);7336 try f.object.dg.renderValue(w, try pt.intValue(.usize, out_idx), .Other);
7336 try writer.writeAll("] = ");7337 try w.writeAll("] = ");
7337 switch (mask_elem.unwrap()) {7338 switch (mask_elem.unwrap()) {
7338 .elem => |src_idx| {7339 .elem => |src_idx| {
7339 try f.writeCValue(writer, operand, .Other);7340 try f.writeCValue(w, operand, .Other);
7340 try writer.writeByte('[');7341 try w.writeByte('[');
7341 try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other);7342 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
7342 try writer.writeByte(']');7343 try w.writeByte(']');
7343 },7344 },
7344 .value => |val| try f.object.dg.renderValue(writer, .fromInterned(val), .Other),7345 .value => |val| try f.object.dg.renderValue(w, .fromInterned(val), .Other),
7345 }7346 }
7346 try writer.writeAll(";\n");7347 try w.writeAll(";\n");
7347 }7348 }
73487349
7349 return local;7350 return local;
...@@ -7360,30 +7361,30 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7360,30 +7361,30 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
7360 const inst_ty = unwrapped.result_ty;7361 const inst_ty = unwrapped.result_ty;
7361 const elem_ty = inst_ty.childType(zcu);7362 const elem_ty = inst_ty.childType(zcu);
73627363
7363 const writer = f.object.writer();7364 const w = f.object.writer();
7364 const local = try f.allocLocal(inst, inst_ty);7365 const local = try f.allocLocal(inst, inst_ty);
7365 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands7366 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands
7366 for (mask, 0..) |mask_elem, out_idx| {7367 for (mask, 0..) |mask_elem, out_idx| {
7367 try f.writeCValue(writer, local, .Other);7368 try f.writeCValue(w, local, .Other);
7368 try writer.writeByte('[');7369 try w.writeByte('[');
7369 try f.object.dg.renderValue(writer, try pt.intValue(.usize, out_idx), .Other);7370 try f.object.dg.renderValue(w, try pt.intValue(.usize, out_idx), .Other);
7370 try writer.writeAll("] = ");7371 try w.writeAll("] = ");
7371 switch (mask_elem.unwrap()) {7372 switch (mask_elem.unwrap()) {
7372 .a_elem => |src_idx| {7373 .a_elem => |src_idx| {
7373 try f.writeCValue(writer, operand_a, .Other);7374 try f.writeCValue(w, operand_a, .Other);
7374 try writer.writeByte('[');7375 try w.writeByte('[');
7375 try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other);7376 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
7376 try writer.writeByte(']');7377 try w.writeByte(']');
7377 },7378 },
7378 .b_elem => |src_idx| {7379 .b_elem => |src_idx| {
7379 try f.writeCValue(writer, operand_b, .Other);7380 try f.writeCValue(w, operand_b, .Other);
7380 try writer.writeByte('[');7381 try w.writeByte('[');
7381 try f.object.dg.renderValue(writer, try pt.intValue(.usize, src_idx), .Other);7382 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
7382 try writer.writeByte(']');7383 try w.writeByte(']');
7383 },7384 },
7384 .undef => try f.object.dg.renderUndefValue(writer, elem_ty, .Other),7385 .undef => try f.object.dg.renderUndefValue(w, elem_ty, .Other),
7385 }7386 }
7386 try writer.writeAll(";\n");7387 try w.writeAll(";\n");
7387 }7388 }
73887389
7389 return local;7390 return local;
...@@ -7398,7 +7399,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7398,7 +7399,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7398 const operand = try f.resolveInst(reduce.operand);7399 const operand = try f.resolveInst(reduce.operand);
7399 try reap(f, inst, &.{reduce.operand});7400 try reap(f, inst, &.{reduce.operand});
7400 const operand_ty = f.typeOf(reduce.operand);7401 const operand_ty = f.typeOf(reduce.operand);
7401 const writer = f.object.writer();7402 const w = f.object.writer();
74027403
7403 const use_operator = scalar_ty.bitSize(zcu) <= 64;7404 const use_operator = scalar_ty.bitSize(zcu) <= 64;
7404 const op: union(enum) {7405 const op: union(enum) {
...@@ -7445,10 +7446,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7445,10 +7446,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7445 // }7446 // }
74467447
7447 const accum = try f.allocLocal(inst, scalar_ty);7448 const accum = try f.allocLocal(inst, scalar_ty);
7448 try f.writeCValue(writer, accum, .Other);7449 try f.writeCValue(w, accum, .Other);
7449 try writer.writeAll(" = ");7450 try w.writeAll(" = ");
74507451
7451 try f.object.dg.renderValue(writer, switch (reduce.operation) {7452 try f.object.dg.renderValue(w, switch (reduce.operation) {
7452 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {7453 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
7453 .bool => Value.false,7454 .bool => Value.false,
7454 .int => try pt.intValue(scalar_ty, 0),7455 .int => try pt.intValue(scalar_ty, 0),
...@@ -7485,42 +7486,42 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7485,42 +7486,42 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7485 else => unreachable,7486 else => unreachable,
7486 },7487 },
7487 }, .Other);7488 }, .Other);
7488 try writer.writeAll(";\n");7489 try w.writeAll(";\n");
74897490
7490 const v = try Vectorize.start(f, inst, writer, operand_ty);7491 const v = try Vectorize.start(f, inst, w, operand_ty);
7491 try f.writeCValue(writer, accum, .Other);7492 try f.writeCValue(w, accum, .Other);
7492 switch (op) {7493 switch (op) {
7493 .builtin => |func| {7494 .builtin => |func| {
7494 try writer.print(" = zig_{s}_", .{func.operation});7495 try w.print(" = zig_{s}_", .{func.operation});
7495 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);7496 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
7496 try writer.writeByte('(');7497 try w.writeByte('(');
7497 try f.writeCValue(writer, accum, .FunctionArgument);7498 try f.writeCValue(w, accum, .FunctionArgument);
7498 try writer.writeAll(", ");7499 try w.writeAll(", ");
7499 try f.writeCValue(writer, operand, .Other);7500 try f.writeCValue(w, operand, .Other);
7500 try v.elem(f, writer);7501 try v.elem(f, w);
7501 try f.object.dg.renderBuiltinInfo(writer, scalar_ty, func.info);7502 try f.object.dg.renderBuiltinInfo(w, scalar_ty, func.info);
7502 try writer.writeByte(')');7503 try w.writeByte(')');
7503 },7504 },
7504 .infix => |ass| {7505 .infix => |ass| {
7505 try writer.writeAll(ass);7506 try w.writeAll(ass);
7506 try f.writeCValue(writer, operand, .Other);7507 try f.writeCValue(w, operand, .Other);
7507 try v.elem(f, writer);7508 try v.elem(f, w);
7508 },7509 },
7509 .ternary => |cmp| {7510 .ternary => |cmp| {
7510 try writer.writeAll(" = ");7511 try w.writeAll(" = ");
7511 try f.writeCValue(writer, accum, .Other);7512 try f.writeCValue(w, accum, .Other);
7512 try writer.writeAll(cmp);7513 try w.writeAll(cmp);
7513 try f.writeCValue(writer, operand, .Other);7514 try f.writeCValue(w, operand, .Other);
7514 try v.elem(f, writer);7515 try v.elem(f, w);
7515 try writer.writeAll(" ? ");7516 try w.writeAll(" ? ");
7516 try f.writeCValue(writer, accum, .Other);7517 try f.writeCValue(w, accum, .Other);
7517 try writer.writeAll(" : ");7518 try w.writeAll(" : ");
7518 try f.writeCValue(writer, operand, .Other);7519 try f.writeCValue(w, operand, .Other);
7519 try v.elem(f, writer);7520 try v.elem(f, w);
7520 },7521 },
7521 }7522 }
7522 try writer.writeAll(";\n");7523 try w.writeAll(";\n");
7523 try v.end(f, inst, writer);7524 try v.end(f, inst, w);
75247525
7525 return accum;7526 return accum;
7526}7527}
...@@ -7546,7 +7547,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7546,7 +7547,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7546 }7547 }
7547 }7548 }
75487549
7549 const writer = f.object.writer();7550 const w = f.object.writer();
7550 const local = try f.allocLocal(inst, inst_ty);7551 const local = try f.allocLocal(inst, inst_ty);
7551 switch (ip.indexToKey(inst_ty.toIntern())) {7552 switch (ip.indexToKey(inst_ty.toIntern())) {
7552 inline .array_type, .vector_type => |info, tag| {7553 inline .array_type, .vector_type => |info, tag| {
...@@ -7554,20 +7555,20 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7554,20 +7555,20 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7554 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),7555 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),
7555 };7556 };
7556 for (resolved_elements, 0..) |element, i| {7557 for (resolved_elements, 0..) |element, i| {
7557 try a.restart(f, writer);7558 try a.restart(f, w);
7558 try f.writeCValue(writer, local, .Other);7559 try f.writeCValue(w, local, .Other);
7559 try writer.print("[{d}]", .{i});7560 try w.print("[{d}]", .{i});
7560 try a.assign(f, writer);7561 try a.assign(f, w);
7561 try f.writeCValue(writer, element, .Other);7562 try f.writeCValue(w, element, .Other);
7562 try a.end(f, writer);7563 try a.end(f, w);
7563 }7564 }
7564 if (tag == .array_type and info.sentinel != .none) {7565 if (tag == .array_type and info.sentinel != .none) {
7565 try a.restart(f, writer);7566 try a.restart(f, w);
7566 try f.writeCValue(writer, local, .Other);7567 try f.writeCValue(w, local, .Other);
7567 try writer.print("[{d}]", .{info.len});7568 try w.print("[{d}]", .{info.len});
7568 try a.assign(f, writer);7569 try a.assign(f, w);
7569 try f.object.dg.renderValue(writer, Value.fromInterned(info.sentinel), .Other);7570 try f.object.dg.renderValue(w, Value.fromInterned(info.sentinel), .Other);
7570 try a.end(f, writer);7571 try a.end(f, w);
7571 }7572 }
7572 },7573 },
7573 .struct_type => {7574 .struct_type => {
...@@ -7579,19 +7580,19 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7579,19 +7580,19 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7579 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);7580 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
7580 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7581 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
75817582
7582 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7583 const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
7583 try f.writeCValueMember(writer, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|7584 try f.writeCValueMember(w, local, if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name|
7584 .{ .identifier = field_name.toSlice(ip) }7585 .{ .identifier = field_name.toSlice(ip) }
7585 else7586 else
7586 .{ .field = field_index });7587 .{ .field = field_index });
7587 try a.assign(f, writer);7588 try a.assign(f, w);
7588 try f.writeCValue(writer, resolved_elements[field_index], .Other);7589 try f.writeCValue(w, resolved_elements[field_index], .Other);
7589 try a.end(f, writer);7590 try a.end(f, w);
7590 }7591 }
7591 },7592 },
7592 .@"packed" => {7593 .@"packed" => {
7593 try f.writeCValue(writer, local, .Other);7594 try f.writeCValue(w, local, .Other);
7594 try writer.writeAll(" = ");7595 try w.writeAll(" = ");
75957596
7596 const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));7597 const backing_int_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));
7597 const int_info = backing_int_ty.intInfo(zcu);7598 const int_info = backing_int_ty.intInfo(zcu);
...@@ -7607,9 +7608,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7607,9 +7608,9 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7607 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7608 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
76087609
7609 if (!empty) {7610 if (!empty) {
7610 try writer.writeAll("zig_or_");7611 try w.writeAll("zig_or_");
7611 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7612 try f.object.dg.renderTypeForBuiltinFnName(w, inst_ty);
7612 try writer.writeByte('(');7613 try w.writeByte('(');
7613 }7614 }
7614 empty = false;7615 empty = false;
7615 }7616 }
...@@ -7619,57 +7620,57 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7619,57 +7620,57 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7619 const field_ty = inst_ty.fieldType(field_index, zcu);7620 const field_ty = inst_ty.fieldType(field_index, zcu);
7620 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7621 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
76217622
7622 if (!empty) try writer.writeAll(", ");7623 if (!empty) try w.writeAll(", ");
7623 // TODO: Skip this entire shift if val is 0?7624 // TODO: Skip this entire shift if val is 0?
7624 try writer.writeAll("zig_shlw_");7625 try w.writeAll("zig_shlw_");
7625 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7626 try f.object.dg.renderTypeForBuiltinFnName(w, inst_ty);
7626 try writer.writeByte('(');7627 try w.writeByte('(');
76277628
7628 if (field_ty.isAbiInt(zcu)) {7629 if (field_ty.isAbiInt(zcu)) {
7629 try writer.writeAll("zig_and_");7630 try w.writeAll("zig_and_");
7630 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);7631 try f.object.dg.renderTypeForBuiltinFnName(w, inst_ty);
7631 try writer.writeByte('(');7632 try w.writeByte('(');
7632 }7633 }
76337634
7634 if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {7635 if (inst_ty.isAbiInt(zcu) and (field_ty.isAbiInt(zcu) or field_ty.isPtrAtRuntime(zcu))) {
7635 try f.renderIntCast(writer, inst_ty, element, .{}, field_ty, .FunctionArgument);7636 try f.renderIntCast(w, inst_ty, element, .{}, field_ty, .FunctionArgument);
7636 } else {7637 } else {
7637 try writer.writeByte('(');7638 try w.writeByte('(');
7638 try f.renderType(writer, inst_ty);7639 try f.renderType(w, inst_ty);
7639 try writer.writeByte(')');7640 try w.writeByte(')');
7640 if (field_ty.isPtrAtRuntime(zcu)) {7641 if (field_ty.isPtrAtRuntime(zcu)) {
7641 try writer.writeByte('(');7642 try w.writeByte('(');
7642 try f.renderType(writer, switch (int_info.signedness) {7643 try f.renderType(w, switch (int_info.signedness) {
7643 .unsigned => .usize,7644 .unsigned => .usize,
7644 .signed => .isize,7645 .signed => .isize,
7645 });7646 });
7646 try writer.writeByte(')');7647 try w.writeByte(')');
7647 }7648 }
7648 try f.writeCValue(writer, element, .Other);7649 try f.writeCValue(w, element, .Other);
7649 }7650 }
76507651
7651 if (field_ty.isAbiInt(zcu)) {7652 if (field_ty.isAbiInt(zcu)) {
7652 try writer.writeAll(", ");7653 try w.writeAll(", ");
7653 const field_int_info = field_ty.intInfo(zcu);7654 const field_int_info = field_ty.intInfo(zcu);
7654 const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)7655 const field_mask = if (int_info.signedness == .signed and int_info.bits == field_int_info.bits)
7655 try pt.intValue(backing_int_ty, -1)7656 try pt.intValue(backing_int_ty, -1)
7656 else7657 else
7657 try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);7658 try (try pt.intType(.unsigned, field_int_info.bits)).maxIntScalar(pt, backing_int_ty);
7658 try f.object.dg.renderValue(writer, field_mask, .FunctionArgument);7659 try f.object.dg.renderValue(w, field_mask, .FunctionArgument);
7659 try writer.writeByte(')');7660 try w.writeByte(')');
7660 }7661 }
76617662
7662 try writer.print(", {f}", .{7663 try w.print(", {f}", .{
7663 try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)),7664 try f.fmtIntLiteralDec(try pt.intValue(bit_offset_ty, bit_offset)),
7664 });7665 });
7665 try f.object.dg.renderBuiltinInfo(writer, inst_ty, .bits);7666 try f.object.dg.renderBuiltinInfo(w, inst_ty, .bits);
7666 try writer.writeByte(')');7667 try w.writeByte(')');
7667 if (!empty) try writer.writeByte(')');7668 if (!empty) try w.writeByte(')');
76687669
7669 bit_offset += field_ty.bitSize(zcu);7670 bit_offset += field_ty.bitSize(zcu);
7670 empty = false;7671 empty = false;
7671 }7672 }
7672 try writer.writeAll(";\n");7673 try w.writeAll(";\n");
7673 },7674 },
7674 }7675 }
7675 },7676 },
...@@ -7678,11 +7679,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7678,11 +7679,11 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7678 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);7679 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
7679 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;7680 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
76807681
7681 const a = try Assignment.start(f, writer, try f.ctypeFromType(field_ty, .complete));7682 const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
7682 try f.writeCValueMember(writer, local, .{ .field = field_index });7683 try f.writeCValueMember(w, local, .{ .field = field_index });
7683 try a.assign(f, writer);7684 try a.assign(f, w);
7684 try f.writeCValue(writer, resolved_elements[field_index], .Other);7685 try f.writeCValue(w, resolved_elements[field_index], .Other);
7685 try a.end(f, writer);7686 try a.end(f, w);
7686 },7687 },
7687 else => unreachable,7688 else => unreachable,
7688 }7689 }
...@@ -7704,7 +7705,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7704,7 +7705,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7704 const payload = try f.resolveInst(extra.init);7705 const payload = try f.resolveInst(extra.init);
7705 try reap(f, inst, &.{extra.init});7706 try reap(f, inst, &.{extra.init});
77067707
7707 const writer = f.object.writer();7708 const w = f.object.writer();
7708 const local = try f.allocLocal(inst, union_ty);7709 const local = try f.allocLocal(inst, union_ty);
7709 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);7710 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
77107711
...@@ -7714,20 +7715,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7714,20 +7715,20 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7714 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;7715 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
7715 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);7716 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
77167717
7717 const a = try Assignment.start(f, writer, try f.ctypeFromType(tag_ty, .complete));7718 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
7718 try f.writeCValueMember(writer, local, .{ .identifier = "tag" });7719 try f.writeCValueMember(w, local, .{ .identifier = "tag" });
7719 try a.assign(f, writer);7720 try a.assign(f, w);
7720 try writer.print("{f}", .{try f.fmtIntLiteralDec(try tag_val.intFromEnum(tag_ty, pt))});7721 try w.print("{f}", .{try f.fmtIntLiteralDec(try tag_val.intFromEnum(tag_ty, pt))});
7721 try a.end(f, writer);7722 try a.end(f, w);
7722 }7723 }
7723 break :field .{ .payload_identifier = field_name.toSlice(ip) };7724 break :field .{ .payload_identifier = field_name.toSlice(ip) };
7724 } else .{ .identifier = field_name.toSlice(ip) };7725 } else .{ .identifier = field_name.toSlice(ip) };
77257726
7726 const a = try Assignment.start(f, writer, try f.ctypeFromType(payload_ty, .complete));7727 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
7727 try f.writeCValueMember(writer, local, field);7728 try f.writeCValueMember(w, local, field);
7728 try a.assign(f, writer);7729 try a.assign(f, w);
7729 try f.writeCValue(writer, payload, .Other);7730 try f.writeCValue(w, payload, .Other);
7730 try a.end(f, writer);7731 try a.end(f, w);
7731 return local;7732 return local;
7732}7733}
77337734
...@@ -7740,15 +7741,15 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7740,15 +7741,15 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7740 const ptr = try f.resolveInst(prefetch.ptr);7741 const ptr = try f.resolveInst(prefetch.ptr);
7741 try reap(f, inst, &.{prefetch.ptr});7742 try reap(f, inst, &.{prefetch.ptr});
77427743
7743 const writer = f.object.writer();7744 const w = f.object.writer();
7744 switch (prefetch.cache) {7745 switch (prefetch.cache) {
7745 .data => {7746 .data => {
7746 try writer.writeAll("zig_prefetch(");7747 try w.writeAll("zig_prefetch(");
7747 if (ptr_ty.isSlice(zcu))7748 if (ptr_ty.isSlice(zcu))
7748 try f.writeCValueMember(writer, ptr, .{ .identifier = "ptr" })7749 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" })
7749 else7750 else
7750 try f.writeCValue(writer, ptr, .FunctionArgument);7751 try f.writeCValue(w, ptr, .FunctionArgument);
7751 try writer.print(", {d}, {d});\n", .{ @intFromEnum(prefetch.rw), prefetch.locality });7752 try w.print(", {d}, {d});\n", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7752 },7753 },
7753 // The available prefetch intrinsics do not accept a cache argument; only7754 // The available prefetch intrinsics do not accept a cache argument; only
7754 // address, rw, and locality.7755 // address, rw, and locality.
...@@ -7761,13 +7762,13 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7761,13 +7762,13 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7761fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {7762fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7762 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7763 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
77637764
7764 const writer = f.object.writer();7765 const w = f.object.writer();
7765 const inst_ty = f.typeOfIndex(inst);7766 const inst_ty = f.typeOfIndex(inst);
7766 const local = try f.allocLocal(inst, inst_ty);7767 const local = try f.allocLocal(inst, inst_ty);
7767 try f.writeCValue(writer, local, .Other);7768 try f.writeCValue(w, local, .Other);
77687769
7769 try writer.writeAll(" = ");7770 try w.writeAll(" = ");
7770 try writer.print("zig_wasm_memory_size({d});\n", .{pl_op.payload});7771 try w.print("zig_wasm_memory_size({d});\n", .{pl_op.payload});
77717772
7772 return local;7773 return local;
7773}7774}
...@@ -7775,17 +7776,17 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7775,17 +7776,17 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
7775fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {7776fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
7776 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;7777 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
77777778
7778 const writer = f.object.writer();7779 const w = f.object.writer();
7779 const inst_ty = f.typeOfIndex(inst);7780 const inst_ty = f.typeOfIndex(inst);
7780 const operand = try f.resolveInst(pl_op.operand);7781 const operand = try f.resolveInst(pl_op.operand);
7781 try reap(f, inst, &.{pl_op.operand});7782 try reap(f, inst, &.{pl_op.operand});
7782 const local = try f.allocLocal(inst, inst_ty);7783 const local = try f.allocLocal(inst, inst_ty);
7783 try f.writeCValue(writer, local, .Other);7784 try f.writeCValue(w, local, .Other);
77847785
7785 try writer.writeAll(" = ");7786 try w.writeAll(" = ");
7786 try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});7787 try w.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
7787 try f.writeCValue(writer, operand, .FunctionArgument);7788 try f.writeCValue(w, operand, .FunctionArgument);
7788 try writer.writeAll(");\n");7789 try w.writeAll(");\n");
7789 return local;7790 return local;
7790}7791}
77917792
...@@ -7803,36 +7804,36 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7803,36 +7804,36 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7803 const inst_ty = f.typeOfIndex(inst);7804 const inst_ty = f.typeOfIndex(inst);
7804 const inst_scalar_ty = inst_ty.scalarType(zcu);7805 const inst_scalar_ty = inst_ty.scalarType(zcu);
78057806
7806 const writer = f.object.writer();7807 const w = f.object.writer();
7807 const local = try f.allocLocal(inst, inst_ty);7808 const local = try f.allocLocal(inst, inst_ty);
7808 const v = try Vectorize.start(f, inst, writer, inst_ty);7809 const v = try Vectorize.start(f, inst, w, inst_ty);
7809 try f.writeCValue(writer, local, .Other);7810 try f.writeCValue(w, local, .Other);
7810 try v.elem(f, writer);7811 try v.elem(f, w);
7811 try writer.writeAll(" = zig_fma_");7812 try w.writeAll(" = zig_fma_");
7812 try f.object.dg.renderTypeForBuiltinFnName(writer, inst_scalar_ty);7813 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
7813 try writer.writeByte('(');7814 try w.writeByte('(');
7814 try f.writeCValue(writer, mulend1, .FunctionArgument);7815 try f.writeCValue(w, mulend1, .FunctionArgument);
7815 try v.elem(f, writer);7816 try v.elem(f, w);
7816 try writer.writeAll(", ");7817 try w.writeAll(", ");
7817 try f.writeCValue(writer, mulend2, .FunctionArgument);7818 try f.writeCValue(w, mulend2, .FunctionArgument);
7818 try v.elem(f, writer);7819 try v.elem(f, w);
7819 try writer.writeAll(", ");7820 try w.writeAll(", ");
7820 try f.writeCValue(writer, addend, .FunctionArgument);7821 try f.writeCValue(w, addend, .FunctionArgument);
7821 try v.elem(f, writer);7822 try v.elem(f, w);
7822 try writer.writeAll(");\n");7823 try w.writeAll(");\n");
7823 try v.end(f, inst, writer);7824 try v.end(f, inst, w);
78247825
7825 return local;7826 return local;
7826}7827}
78277828
7828fn airRuntimeNavPtr(f: *Function, inst: Air.Inst.Index) !CValue {7829fn airRuntimeNavPtr(f: *Function, inst: Air.Inst.Index) !CValue {
7829 const ty_nav = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;7830 const ty_nav = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;
7830 const writer = f.object.writer();7831 const w = f.object.writer();
7831 const local = try f.allocLocal(inst, .fromInterned(ty_nav.ty));7832 const local = try f.allocLocal(inst, .fromInterned(ty_nav.ty));
7832 try f.writeCValue(writer, local, .Other);7833 try f.writeCValue(w, local, .Other);
7833 try writer.writeAll(" = ");7834 try w.writeAll(" = ");
7834 try f.object.dg.renderNav(writer, ty_nav.nav, .Other);7835 try f.object.dg.renderNav(w, ty_nav.nav, .Other);
7835 try writer.writeAll(";\n");7836 try w.writeAll(";\n");
7836 return local;7837 return local;
7837}7838}
78387839
...@@ -7844,15 +7845,15 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7844,15 +7845,15 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7844 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;7845 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
7845 assert(function_info.varargs);7846 assert(function_info.varargs);
78467847
7847 const writer = f.object.writer();7848 const w = f.object.writer();
7848 const local = try f.allocLocal(inst, inst_ty);7849 const local = try f.allocLocal(inst, inst_ty);
7849 try writer.writeAll("va_start(*(va_list *)&");7850 try w.writeAll("va_start(*(va_list *)&");
7850 try f.writeCValue(writer, local, .Other);7851 try f.writeCValue(w, local, .Other);
7851 if (function_info.param_ctypes.len > 0) {7852 if (function_info.param_ctypes.len > 0) {
7852 try writer.writeAll(", ");7853 try w.writeAll(", ");
7853 try f.writeCValue(writer, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);7854 try f.writeCValue(w, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
7854 }7855 }
7855 try writer.writeAll(");\n");7856 try w.writeAll(");\n");
7856 return local;7857 return local;
7857}7858}
78587859
...@@ -7863,14 +7864,14 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7863,14 +7864,14 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
7863 const va_list = try f.resolveInst(ty_op.operand);7864 const va_list = try f.resolveInst(ty_op.operand);
7864 try reap(f, inst, &.{ty_op.operand});7865 try reap(f, inst, &.{ty_op.operand});
78657866
7866 const writer = f.object.writer();7867 const w = f.object.writer();
7867 const local = try f.allocLocal(inst, inst_ty);7868 const local = try f.allocLocal(inst, inst_ty);
7868 try f.writeCValue(writer, local, .Other);7869 try f.writeCValue(w, local, .Other);
7869 try writer.writeAll(" = va_arg(*(va_list *)");7870 try w.writeAll(" = va_arg(*(va_list *)");
7870 try f.writeCValue(writer, va_list, .Other);7871 try f.writeCValue(w, va_list, .Other);
7871 try writer.writeAll(", ");7872 try w.writeAll(", ");
7872 try f.renderType(writer, ty_op.ty.toType());7873 try f.renderType(w, ty_op.ty.toType());
7873 try writer.writeAll(");\n");7874 try w.writeAll(");\n");
7874 return local;7875 return local;
7875}7876}
78767877
...@@ -7880,10 +7881,10 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7880,10 +7881,10 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
7880 const va_list = try f.resolveInst(un_op);7881 const va_list = try f.resolveInst(un_op);
7881 try reap(f, inst, &.{un_op});7882 try reap(f, inst, &.{un_op});
78827883
7883 const writer = f.object.writer();7884 const w = f.object.writer();
7884 try writer.writeAll("va_end(*(va_list *)");7885 try w.writeAll("va_end(*(va_list *)");
7885 try f.writeCValue(writer, va_list, .Other);7886 try f.writeCValue(w, va_list, .Other);
7886 try writer.writeAll(");\n");7887 try w.writeAll(");\n");
7887 return .none;7888 return .none;
7888}7889}
78897890
...@@ -7894,13 +7895,13 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -7894,13 +7895,13 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
7894 const va_list = try f.resolveInst(ty_op.operand);7895 const va_list = try f.resolveInst(ty_op.operand);
7895 try reap(f, inst, &.{ty_op.operand});7896 try reap(f, inst, &.{ty_op.operand});
78967897
7897 const writer = f.object.writer();7898 const w = f.object.writer();
7898 const local = try f.allocLocal(inst, inst_ty);7899 const local = try f.allocLocal(inst, inst_ty);
7899 try writer.writeAll("va_copy(*(va_list *)&");7900 try w.writeAll("va_copy(*(va_list *)&");
7900 try f.writeCValue(writer, local, .Other);7901 try f.writeCValue(w, local, .Other);
7901 try writer.writeAll(", *(va_list *)");7902 try w.writeAll(", *(va_list *)");
7902 try f.writeCValue(writer, va_list, .Other);7903 try f.writeCValue(w, va_list, .Other);
7903 try writer.writeAll(");\n");7904 try w.writeAll(");\n");
7904 return local;7905 return local;
7905}7906}
79067907
...@@ -7915,7 +7916,7 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {...@@ -7915,7 +7916,7 @@ fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 {
7915 };7916 };
7916}7917}
79177918
7918fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {7919fn writeMemoryOrder(w: *Writer, order: std.builtin.AtomicOrder) !void {
7919 return w.writeAll(toMemoryOrder(order));7920 return w.writeAll(toMemoryOrder(order));
7920}7921}
79217922
...@@ -8028,7 +8029,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type {...@@ -8028,7 +8029,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type {
8028 indent_count: usize = 0,8029 indent_count: usize = 0,
8029 current_line_empty: bool = true,8030 current_line_empty: bool = true,
80308031
8031 pub fn writer(self: *Self) Writer {8032 pub fn w(self: *Self) Writer {
8032 return .{ .context = .{8033 return .{ .context = .{
8033 .context = self,8034 .context = self,
8034 .writeFn = writeAny,8035 .writeFn = writeAny,
...@@ -8079,7 +8080,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type {...@@ -8079,7 +8080,7 @@ fn IndentWriter(comptime UnderlyingWriter: type) type {
80798080
8080/// A wrapper around `std.io.AnyWriter` that maintains a generic error set while8081/// A wrapper around `std.io.AnyWriter` that maintains a generic error set while
8081/// erasing the rest of the implementation. This is intended to avoid duplicate8082/// erasing the rest of the implementation. This is intended to avoid duplicate
8082/// generic instantiations for writer types which share the same error set, while8083/// generic instantiations for w types which share the same error set, while
8083/// maintaining ease of error handling.8084/// maintaining ease of error handling.
8084fn ErrorOnlyGenericWriter(comptime Error: type) type {8085fn ErrorOnlyGenericWriter(comptime Error: type) type {
8085 return std.io.GenericWriter(std.io.AnyWriter, Error, struct {8086 return std.io.GenericWriter(std.io.AnyWriter, Error, struct {
...@@ -8160,12 +8161,12 @@ const StringLiteral = struct {...@@ -8160,12 +8161,12 @@ const StringLiteral = struct {
8160 const max_char_len = 4;8161 const max_char_len = 4;
8161 const max_literal_len = @min(16380 - max_char_len, 4095);8162 const max_literal_len = @min(16380 - max_char_len, 4095);
81628163
8163 fn init(writer: *std.io.Writer, len: usize) StringLiteral {8164 fn init(w: *std.io.Writer, len: usize) StringLiteral {
8164 return .{8165 return .{
8165 .cur_len = 0,8166 .cur_len = 0,
8166 .len = len,8167 .len = len,
8167 .start_count = writer.count,8168 .start_count = w.count,
8168 .writer = writer,8169 .writer = w,
8169 };8170 };
8170 }8171 }
81718172
...@@ -8226,8 +8227,8 @@ const FormatStringContext = struct {...@@ -8226,8 +8227,8 @@ const FormatStringContext = struct {
8226 sentinel: ?u8,8227 sentinel: ?u8,
8227};8228};
82288229
8229fn formatStringLiteral(data: FormatStringContext, writer: *std.io.Writer) std.io.Writer.Error!void {8230fn formatStringLiteral(data: FormatStringContext, w: *std.io.Writer) std.io.Writer.Error!void {
8230 var literal: StringLiteral = .init(writer, data.str.len + @intFromBool(data.sentinel != null));8231 var literal: StringLiteral = .init(w, data.str.len + @intFromBool(data.sentinel != null));
8231 try literal.start();8232 try literal.start();
8232 for (data.str) |c| try literal.writeChar(c);8233 for (data.str) |c| try literal.writeChar(c);
8233 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);8234 if (data.sentinel) |sentinel| if (sentinel != 0) try literal.writeChar(sentinel);
...@@ -8253,7 +8254,7 @@ const FormatIntLiteralContext = struct {...@@ -8253,7 +8254,7 @@ const FormatIntLiteralContext = struct {
8253 base: u8,8254 base: u8,
8254 case: std.fmt.Case,8255 case: std.fmt.Case,
8255};8256};
8256fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.io.Writer.Error!void {8257fn formatIntLiteral(data: FormatIntLiteralContext, w: *std.io.Writer) std.io.Writer.Error!void {
8257 const pt = data.dg.pt;8258 const pt = data.dg.pt;
8258 const zcu = pt.zcu;8259 const zcu = pt.zcu;
8259 const target = &data.dg.mod.resolved_target.result;8260 const target = &data.dg.mod.resolved_target.result;
...@@ -8333,28 +8334,28 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i...@@ -8333,28 +8334,28 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i
8333 if (c_limb_info.count == 1) {8334 if (c_limb_info.count == 1) {
8334 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or8335 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
8335 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))8336 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
8336 return writer.print("{s}_{s}", .{8337 return w.print("{s}_{s}", .{
8337 data.ctype.getStandardDefineAbbrev() orelse return writer.print("zig_{s}Int_{c}{d}", .{8338 data.ctype.getStandardDefineAbbrev() orelse return w.print("zig_{s}Int_{c}{d}", .{
8338 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,8339 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
8339 }),8340 }),
8340 if (int.positive) "MAX" else "MIN",8341 if (int.positive) "MAX" else "MIN",
8341 });8342 });
83428343
8343 if (!int.positive) try writer.writeByte('-');8344 if (!int.positive) try w.writeByte('-');
8344 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);8345 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);
83458346
8346 switch (data.base) {8347 switch (data.base) {
8347 2 => try writer.writeAll("0b"),8348 2 => try w.writeAll("0b"),
8348 8 => try writer.writeByte('0'),8349 8 => try w.writeByte('0'),
8349 10 => {},8350 10 => {},
8350 16 => try writer.writeAll("0x"),8351 16 => try w.writeAll("0x"),
8351 else => unreachable,8352 else => unreachable,
8352 }8353 }
8353 const string = try oom(int.abs().toStringAlloc(allocator, data.base, data.case));8354 const string = try oom(int.abs().toStringAlloc(allocator, data.base, data.case));
8354 defer allocator.free(string);8355 defer allocator.free(string);
8355 try writer.writeAll(string);8356 try w.writeAll(string);
8356 } else {8357 } else {
8357 try data.ctype.renderLiteralPrefix(writer, data.kind, ctype_pool);8358 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);
8358 wrap.truncate(int, .unsigned, c_bits);8359 wrap.truncate(int, .unsigned, c_bits);
8359 @memset(wrap.limbs[wrap.len..], 0);8360 @memset(wrap.limbs[wrap.len..], 0);
8360 wrap.len = wrap.limbs.len;8361 wrap.len = wrap.limbs.len;
...@@ -8397,7 +8398,7 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i...@@ -8397,7 +8398,7 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i
8397 c_limb_ctype = c_limb_info.ctype;8398 c_limb_ctype = c_limb_info.ctype;
8398 }8399 }
83998400
8400 if (limb_offset > 0) try writer.writeAll(", ");8401 if (limb_offset > 0) try w.writeAll(", ");
8401 try formatIntLiteral(.{8402 try formatIntLiteral(.{
8402 .dg = data.dg,8403 .dg = data.dg,
8403 .int_info = c_limb_int_info,8404 .int_info = c_limb_int_info,
...@@ -8406,10 +8407,10 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i...@@ -8406,10 +8407,10 @@ fn formatIntLiteral(data: FormatIntLiteralContext, writer: *std.io.Writer) std.i
8406 .val = try oom(pt.intValue_big(.comptime_int, c_limb_mut.toConst())),8407 .val = try oom(pt.intValue_big(.comptime_int, c_limb_mut.toConst())),
8407 .base = data.base,8408 .base = data.base,
8408 .case = data.case,8409 .case = data.case,
8409 }, writer);8410 }, w);
8410 }8411 }
8411 }8412 }
8412 try data.ctype.renderLiteralSuffix(writer, ctype_pool);8413 try data.ctype.renderLiteralSuffix(w, ctype_pool);
8413}8414}
84148415
8415const Materialize = struct {8416const Materialize = struct {
...@@ -8423,8 +8424,8 @@ const Materialize = struct {...@@ -8423,8 +8424,8 @@ const Materialize = struct {
8423 } };8424 } };
8424 }8425 }
84258426
8426 pub fn mat(self: Materialize, f: *Function, writer: anytype) !void {8427 pub fn mat(self: Materialize, f: *Function, w: *Writer) !void {
8427 try f.writeCValue(writer, self.local, .Other);8428 try f.writeCValue(w, self.local, .Other);
8428 }8429 }
84298430
8430 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {8431 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
...@@ -8435,36 +8436,36 @@ const Materialize = struct {...@@ -8435,36 +8436,36 @@ const Materialize = struct {
8435const Assignment = struct {8436const Assignment = struct {
8436 ctype: CType,8437 ctype: CType,
84378438
8438 pub fn start(f: *Function, writer: anytype, ctype: CType) !Assignment {8439 pub fn start(f: *Function, w: *Writer, ctype: CType) !Assignment {
8439 const self: Assignment = .{ .ctype = ctype };8440 const self: Assignment = .{ .ctype = ctype };
8440 try self.restart(f, writer);8441 try self.restart(f, w);
8441 return self;8442 return self;
8442 }8443 }
84438444
8444 pub fn restart(self: Assignment, f: *Function, writer: anytype) !void {8445 pub fn restart(self: Assignment, f: *Function, w: *Writer) !void {
8445 switch (self.strategy(f)) {8446 switch (self.strategy(f)) {
8446 .assign => {},8447 .assign => {},
8447 .memcpy => try writer.writeAll("memcpy("),8448 .memcpy => try w.writeAll("memcpy("),
8448 }8449 }
8449 }8450 }
84508451
8451 pub fn assign(self: Assignment, f: *Function, writer: anytype) !void {8452 pub fn assign(self: Assignment, f: *Function, w: *Writer) !void {
8452 switch (self.strategy(f)) {8453 switch (self.strategy(f)) {
8453 .assign => try writer.writeAll(" = "),8454 .assign => try w.writeAll(" = "),
8454 .memcpy => try writer.writeAll(", "),8455 .memcpy => try w.writeAll(", "),
8455 }8456 }
8456 }8457 }
84578458
8458 pub fn end(self: Assignment, f: *Function, writer: anytype) !void {8459 pub fn end(self: Assignment, f: *Function, w: *Writer) !void {
8459 switch (self.strategy(f)) {8460 switch (self.strategy(f)) {
8460 .assign => {},8461 .assign => {},
8461 .memcpy => {8462 .memcpy => {
8462 try writer.writeAll(", sizeof(");8463 try w.writeAll(", sizeof(");
8463 try f.renderCType(writer, self.ctype);8464 try f.renderCType(w, self.ctype);
8464 try writer.writeAll("))");8465 try w.writeAll("))");
8465 },8466 },
8466 }8467 }
8467 try writer.writeAll(";\n");8468 try w.writeAll(";\n");
8468 }8469 }
84698470
8470 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {8471 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
...@@ -8478,37 +8479,37 @@ const Assignment = struct {...@@ -8478,37 +8479,37 @@ const Assignment = struct {
8478const Vectorize = struct {8479const Vectorize = struct {
8479 index: CValue = .none,8480 index: CValue = .none,
84808481
8481 pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize {8482 pub fn start(f: *Function, inst: Air.Inst.Index, w: *Writer, ty: Type) !Vectorize {
8482 const pt = f.object.dg.pt;8483 const pt = f.object.dg.pt;
8483 const zcu = pt.zcu;8484 const zcu = pt.zcu;
8484 return if (ty.zigTypeTag(zcu) == .vector) index: {8485 return if (ty.zigTypeTag(zcu) == .vector) index: {
8485 const local = try f.allocLocal(inst, .usize);8486 const local = try f.allocLocal(inst, .usize);
84868487
8487 try writer.writeAll("for (");8488 try w.writeAll("for (");
8488 try f.writeCValue(writer, local, .Other);8489 try f.writeCValue(w, local, .Other);
8489 try writer.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});8490 try w.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});
8490 try f.writeCValue(writer, local, .Other);8491 try f.writeCValue(w, local, .Other);
8491 try writer.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});8492 try w.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});
8492 try f.writeCValue(writer, local, .Other);8493 try f.writeCValue(w, local, .Other);
8493 try writer.print(" += {f}) {{\n", .{try f.fmtIntLiteralDec(.one_usize)});8494 try w.print(" += {f}) {{\n", .{try f.fmtIntLiteralDec(.one_usize)});
8494 f.object.indent_writer.pushIndent();8495 f.object.indent_writer.pushIndent();
84958496
8496 break :index .{ .index = local };8497 break :index .{ .index = local };
8497 } else .{};8498 } else .{};
8498 }8499 }
84998500
8500 pub fn elem(self: Vectorize, f: *Function, writer: anytype) !void {8501 pub fn elem(self: Vectorize, f: *Function, w: *Writer) !void {
8501 if (self.index != .none) {8502 if (self.index != .none) {
8502 try writer.writeByte('[');8503 try w.writeByte('[');
8503 try f.writeCValue(writer, self.index, .Other);8504 try f.writeCValue(w, self.index, .Other);
8504 try writer.writeByte(']');8505 try w.writeByte(']');
8505 }8506 }
8506 }8507 }
85078508
8508 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, writer: anytype) !void {8509 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, w: *Writer) !void {
8509 if (self.index != .none) {8510 if (self.index != .none) {
8510 f.object.indent_writer.popIndent();8511 f.object.indent_writer.popIndent();
8511 try writer.writeAll("}\n");8512 try w.writeAll("}\n");
8512 try freeLocal(f, inst, self.index.new_local, null);8513 try freeLocal(f, inst, self.index.new_local, null);
8513 }8514 }
8514 }8515 }