authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-21 07:09:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-24 11:08:00-04:00
log14ae0638ff9721a64736bd022d133a09163fdd64
tree11f14a60ffe913ef2f957539d42d36e645c2cba0
parenta8428b777c588e2dedfaebdd8c22a5b838d6b5ee

implement linker and c backend support for restricted type safety check


24 files changed, 1124 insertions(+), 586 deletions(-)

src/InternPool.zig+5-1
......@@ -12358,7 +12358,11 @@ pub fn addFieldTagValue(
1235812358/// encoding instead of `Tag.ptr_uav_aligned` when possible.
1235912359fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
1236012360 if (a_ty == b_ty) return true;
12361 const b_info = ip.indexToKey(b_ty).ptr_type;
12361 const b_info = switch (ip.indexToKey(b_ty)) {
12362 else => unreachable,
12363 .ptr_type => |ptr_type| ptr_type,
12364 .restricted_ptr_type => |restricted_ptr_type| ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type,
12365 };
1236212366 return a_info.flags.alignment == b_info.flags.alignment and
1236312367 (a_info.child == b_info.child or a_info.flags.alignment != .none);
1236412368}
src/Type.zig+8-4
......@@ -1350,14 +1350,17 @@ pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {
13501350 };
13511351}
13521352
1353const RestrictedRepr = enum { double_pointer, single_pointer };
1353const RestrictedRepr = enum { indirect, direct };
13541354pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr {
1355 return restrictedReprByZirIndex(zcu.intern_pool.indexToKey(ty.toIntern()).restricted_ptr_type.zir_index, zcu);
1355 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1356 .restricted_ptr_type => |restricted_ptr_type| restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu),
1357 else => .direct,
1358 };
13561359}
13571360pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {
13581361 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {
1359 .Debug, .ReleaseSafe => .double_pointer,
1360 .ReleaseFast, .ReleaseSmall => .single_pointer,
1362 .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct,
1363 .ReleaseFast, .ReleaseSmall => .direct,
13611364 };
13621365}
13631366
......@@ -2670,6 +2673,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
26702673 const ip = &zcu.intern_pool;
26712674 return .{
26722675 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {
2676 .restricted_ptr_type => |restricted_ptr_type| restricted_ptr_type.zir_index,
26732677 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
26742678 .declared => |d| d.zir_index,
26752679 .reified => |r| r.zir_index,
src/Zcu.zig+1
......@@ -3995,6 +3995,7 @@ pub const Feature = enum {
39953995 /// * With this feature disabled, semantic analysis, code generation, and linking all occur on the
39963996 /// same thread, and the "emit" stage has access to AIR.
39973997 separate_thread,
3998 restricted_types,
39983999};
39994000
40004001pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {
src/codegen.zig+242-74
......@@ -210,7 +210,7 @@ pub fn generateLazyFunction(
210210 debug_output: link.File.DebugInfoOutput,
211211) (CodeGenError || std.Io.Writer.Error)!void {
212212 const zcu = pt.zcu;
213 const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
213 const target = if (Type.fromInterned(lazy_sym.key).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
214214 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
215215 else
216216 zcu.getTarget();
......@@ -223,13 +223,118 @@ pub fn generateLazyFunction(
223223 }
224224}
225225
226const LazySymbolStructure = struct {
227 parent: ?link.File.LazySymbol = null,
228 modify: ?Modification = null,
229
230 pub const Modification = struct {
231 lazy_sym: link.File.LazySymbol,
232 operation: Operation,
233
234 pub const Operation = enum {
235 ptr_inc,
236
237 pub fn apply(operation: Operation, slice: []u8, endian: std.builtin.Endian) void {
238 switch (operation) {
239 .ptr_inc => switch (slice.len) {
240 else => unreachable,
241 2 => std.mem.writeInt(u16, slice[0..2], std.mem.readInt(u16, slice[0..2], endian) + 1, endian),
242 4 => std.mem.writeInt(u32, slice[0..4], std.mem.readInt(u32, slice[0..4], endian) + 1, endian),
243 8 => std.mem.writeInt(u64, slice[0..8], std.mem.readInt(u64, slice[0..8], endian) + 1, endian),
244 },
245 }
246 }
247 };
248 };
249};
250pub const LazySymbolAttributes = struct {
251 header: bool = false,
252 required_alignment: Alignment,
253 size: ?u64 = null,
254};
255pub fn getLazySymbolInfo(
256 comptime kind: enum { structure, attributes },
257 lazy_sym: link.File.LazySymbol,
258 zcu: *Zcu,
259) switch (kind) {
260 .structure => LazySymbolStructure,
261 .attributes => LazySymbolAttributes,
262} {
263 const ip = &zcu.intern_pool;
264 return switch (lazy_sym.kind) {
265 .code => switch (kind) {
266 .structure => .{},
267 .attributes => {
268 const comp = zcu.comp;
269 const target = &comp.root_mod.resolved_target.result;
270 return .{ .required_alignment = switch (comp.root_mod.optimize_mode) {
271 .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target),
272 .ReleaseSmall => target_util.minFunctionAlignment(target),
273 } };
274 },
275 },
276 .const_data => switch (ip.indexToKey(lazy_sym.key)) {
277 else => unreachable,
278 .enum_type => switch (kind) {
279 .structure => .{},
280 .attributes => .{ .required_alignment = .@"1" },
281 },
282 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {
283 .structure => .{},
284 .attributes => {
285 const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key);
286 const unrestricted_ptr_ty: Type =
287 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);
288 return .{ .required_alignment = restricted_ptr_ty.abiAlignment(zcu)
289 .maxStrict(unrestricted_ptr_ty.abiAlignment(zcu)) };
290 },
291 },
292 },
293 .deferred_const_data => switch (lazy_sym.key) {
294 else => unreachable,
295 .anyerror_type => switch (kind) {
296 .structure => .{},
297 .attributes => .{ .required_alignment = .@"4" },
298 },
299 _ => switch (ip.indexToKey(lazy_sym.key)) {
300 else => unreachable,
301 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {
302 else => unreachable,
303 .restricted_ptr_type => |restricted_ptr_type| switch (kind) {
304 .structure => .{ .parent = .{ .kind = .const_data, .key = ptr.ty }, .modify = .{
305 .lazy_sym = .{ .kind = .deferred_const_data, .key = ptr.ty },
306 .operation = .ptr_inc,
307 } },
308 .attributes => {
309 const unrestricted_ptr_ty: Type =
310 .fromInterned(restricted_ptr_type.unrestricted_ptr_type);
311 return .{
312 .required_alignment = unrestricted_ptr_ty.abiAlignment(zcu),
313 .size = unrestricted_ptr_ty.abiSize(zcu),
314 };
315 },
316 },
317 },
318 .restricted_ptr_type => switch (kind) {
319 .structure => .{ .parent = .{ .kind = .const_data, .key = lazy_sym.key } },
320 .attributes => {
321 const restricted_ptr_ty: Type = .fromInterned(lazy_sym.key);
322 return .{
323 .header = true,
324 .required_alignment = restricted_ptr_ty.abiAlignment(zcu),
325 .size = restricted_ptr_ty.abiSize(zcu),
326 };
327 },
328 },
329 },
330 },
331 };
332}
226333pub fn generateLazySymbol(
227334 bin_file: *link.File,
228335 pt: Zcu.PerThread,
229336 src_loc: Zcu.LazySrcLoc,
230337 lazy_sym: link.File.LazySymbol,
231 // TODO don't use an "out" parameter like this; put it in the result instead
232 alignment: *Alignment,
233338 w: *std.Io.Writer,
234339 debug_output: link.File.DebugInfoOutput,
235340 reloc_parent: link.File.RelocInfo.Parent,
......@@ -243,51 +348,81 @@ pub fn generateLazySymbol(
243348 const target = &comp.root_mod.resolved_target.result;
244349 const endian = target.cpu.arch.endian();
245350
246 log.debug("generateLazySymbol: kind = {s}, ty = {f}", .{
351 log.debug("generateLazySymbol: kind = {s}, key = {f}", .{
247352 @tagName(lazy_sym.kind),
248 Type.fromInterned(lazy_sym.ty).fmt(pt),
353 Value.fromInterned(lazy_sym.key).fmtValue(pt),
249354 });
250355
251 if (lazy_sym.kind == .code) {
252 alignment.* = target_util.defaultFunctionAlignment(target);
253 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, reloc_parent.atom_index, w, debug_output);
356 switch (lazy_sym.kind) {
357 .code => return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, reloc_parent.atom_index, w, debug_output),
358 .const_data => switch (ip.indexToKey(lazy_sym.key)) {
359 .enum_type => {
360 const enum_ty: Type = .fromInterned(lazy_sym.key);
361 const tag_names = enum_ty.enumFields(zcu);
362 for (0..tag_names.len) |tag_index| {
363 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
364 try w.rebase(w.end, tag_name.len + 1);
365 w.writeAll(tag_name) catch unreachable;
366 w.writeByte(0) catch unreachable;
367 }
368 return;
369 },
370 .restricted_ptr_type => return,
371 else => {},
372 },
373 .deferred_const_data => switch (lazy_sym.key) {
374 .anyerror_type => {
375 const err_names = ip.global_error_set.getNamesFromMainThread();
376 const strings_start: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
377 var string_index = strings_start;
378 try w.rebase(w.end, string_index);
379 w.writeInt(u32, @intCast(err_names.len), endian) catch unreachable;
380 if (err_names.len > 0) {
381 for (err_names) |err_name_nts| {
382 w.writeInt(u32, string_index, endian) catch unreachable;
383 string_index += @intCast(err_name_nts.toSlice(ip).len + 1);
384 }
385 w.writeInt(u32, string_index, endian) catch unreachable;
386 try w.rebase(w.end, string_index - strings_start);
387 for (err_names) |err_name_nts| {
388 w.writeAll(err_name_nts.toSlice(ip)) catch unreachable;
389 w.writeByte(0) catch unreachable;
390 }
391 }
392 return;
393 },
394 _ => switch (ip.indexToKey(lazy_sym.key)) {
395 .ptr => |ptr| switch (ip.indexToKey(ptr.ty)) {
396 .restricted_ptr_type => |restricted_ptr_type| return lowerPtr(
397 bin_file,
398 pt,
399 src_loc,
400 try ip.getCoerced(
401 comp.gpa,
402 comp.io,
403 pt.tid,
404 lazy_sym.key,
405 restricted_ptr_type.unrestricted_ptr_type,
406 ),
407 w,
408 reloc_parent,
409 0,
410 ),
411 else => {},
412 },
413 .restricted_ptr_type => return w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)),
414 else => {},
415 },
416 else => {},
417 },
254418 }
255
256 if (lazy_sym.ty == .anyerror_type) {
257 alignment.* = .@"4";
258 const err_names = ip.global_error_set.getNamesFromMainThread();
259 const strings_start: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
260 var string_index = strings_start;
261 try w.rebase(w.end, string_index);
262 w.writeInt(u32, @intCast(err_names.len), endian) catch unreachable;
263 if (err_names.len == 0) return;
264 for (err_names) |err_name_nts| {
265 w.writeInt(u32, string_index, endian) catch unreachable;
266 string_index += @intCast(err_name_nts.toSlice(ip).len + 1);
267 }
268 w.writeInt(u32, string_index, endian) catch unreachable;
269 try w.rebase(w.end, string_index - strings_start);
270 for (err_names) |err_name_nts| {
271 w.writeAll(err_name_nts.toSlice(ip)) catch unreachable;
272 w.writeByte(0) catch unreachable;
273 }
274 } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") {
275 alignment.* = .@"1";
276 const enum_ty = Type.fromInterned(lazy_sym.ty);
277 const tag_names = enum_ty.enumFields(zcu);
278 for (0..tag_names.len) |tag_index| {
279 const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
280 try w.rebase(w.end, tag_name.len + 1);
281 w.writeAll(tag_name) catch unreachable;
282 w.writeByte(0) catch unreachable;
283 }
284 } else if (Type.fromInterned(lazy_sym.ty).unrestrictedType(zcu)) |unrestricted_ptr_ty| {
285 alignment.* = unrestricted_ptr_ty.abiAlignment(zcu);
286 try w.splatByteAll(0, @divExact(zcu.getTarget().ptrBitWidth(), 8)); // to be filled in later
287 } else {
288 return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {f}", .{
289 @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt),
290 });
419 switch (ip.typeOf(lazy_sym.key)) {
420 .type_type => return zcu.codegenFailType(lazy_sym.key, "TODO implement generateLazySymbol for {t} {f}", .{
421 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
422 }),
423 else => std.debug.panic("TODO implement generateLazySymbol for {t} {f}", .{
424 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
425 }),
291426 }
292427}
293428
......@@ -441,7 +576,10 @@ pub fn generateSymbol(
441576 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
442577 },
443578 },
444 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
579 .ptr => switch (ty.restrictedRepr(zcu)) {
580 .indirect => try lowerLazySymbolRef(bin_file, pt, .{ .kind = .deferred_const_data, .key = val.toIntern() }, w, reloc_parent, 0),
581 .direct => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
582 },
445583 .slice => |slice| {
446584 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
447585 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
......@@ -838,7 +976,7 @@ fn lowerNavRef(
838976 else => {},
839977 }
840978
841 const vaddr = lf.getNavVAddr(pt, nav_index, .{
979 const vaddr = lf.getNavVAddr(nav_index, .{
842980 .parent = reloc_parent,
843981 .offset = w.end,
844982 .addend = @intCast(offset),
......@@ -906,7 +1044,7 @@ pub fn genNavRef(
9061044 .link_once => unreachable,
9071045 }
9081046 } else if (lf.cast(.elf2)) |elf| {
909 return .{ .sym_index = @intFromEnum(elf.navSymbol(zcu, nav_index) catch |err| switch (err) {
1047 return .{ .sym_index = @intFromEnum(elf.navSymbol(nav_index) catch |err| switch (err) {
9101048 error.OutOfMemory => |e| return e,
9111049 else => |e| return .{ .fail = try ErrorMsg.create(
9121050 zcu.gpa,
......@@ -937,13 +1075,38 @@ pub fn genNavRef(
9371075 .link_once => unreachable,
9381076 }
9391077 } else if (lf.cast(.coff2)) |coff| {
940 return .{ .sym_index = @intFromEnum(try coff.navSymbol(zcu, nav_index)) };
1078 return .{ .sym_index = @intFromEnum(try coff.navSymbol(nav_index)) };
9411079 } else {
9421080 const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
9431081 return .{ .fail = msg };
9441082 }
9451083}
9461084
1085fn lowerLazySymbolRef(
1086 lf: *link.File,
1087 pt: Zcu.PerThread,
1088 lazy_sym: link.File.LazySymbol,
1089 w: *std.Io.Writer,
1090 reloc_parent: link.File.RelocInfo.Parent,
1091 offset: u64,
1092) (GenerateSymbolError || std.Io.Writer.Error)!void {
1093 const vaddr = lf.getLazySymbolVAddr(pt, lazy_sym, .{
1094 .parent = reloc_parent,
1095 .offset = w.end,
1096 .addend = @intCast(offset),
1097 }) catch @panic("TODO rework getNavVAddr");
1098
1099 const target = &lf.comp.root_mod.resolved_target.result;
1100 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
1101 const endian = target.cpu.arch.endian();
1102 switch (ptr_width_bytes) {
1103 2 => try w.writeInt(u16, @intCast(vaddr), endian),
1104 4 => try w.writeInt(u32, @intCast(vaddr), endian),
1105 8 => try w.writeInt(u64, vaddr, endian),
1106 else => unreachable,
1107 }
1108}
1109
9471110/// deprecated legacy type
9481111pub const GenResult = union(enum) {
9491112 mcv: MCValue,
......@@ -1006,6 +1169,7 @@ pub fn genTypedValue(
10061169 } },
10071170 .fail => |em| .{ .fail = em },
10081171 },
1172 .lea_lazy_sym => unreachable, // `Zcu.Feature.restricted_types` is not supported by this code path
10091173 };
10101174}
10111175
......@@ -1018,6 +1182,7 @@ const LowerResult = union(enum) {
10181182 lea_nav: InternPool.Nav.Index,
10191183 load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
10201184 lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
1185 lea_lazy_sym: link.File.LazySymbol,
10211186};
10221187
10231188pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {
......@@ -1034,38 +1199,41 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
10341199 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
10351200 .pointer => switch (ty.ptrSize(zcu)) {
10361201 .slice => {},
1037 .one, .many, .c => {
1038 const ptr = ip.indexToKey(val.toIntern()).ptr;
1039 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1040 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1041 .int => unreachable, // handled above
1042
1043 .nav => |nav_index| {
1044 const nav = ip.getNav(nav_index);
1045 const nav_ty: Type = .fromInterned(nav.resolved.?.type);
1046 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1047 return .{ .lea_nav = nav_index };
1202 .one, .many, .c => switch (ty.restrictedRepr(zcu)) {
1203 .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = val.toIntern() } },
1204 .direct => {
1205 const ptr = ip.indexToKey(val.toIntern()).ptr;
1206 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1207 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1208 .int => unreachable, // handled above
1209
1210 .nav => |nav_index| {
1211 const nav = ip.getNav(nav_index);
1212 const nav_ty: Type = .fromInterned(nav.resolved.?.type);
1213 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1214 return .{ .lea_nav = nav_index };
1215 } else {
1216 // Create the 0xaa bit pattern...
1217 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1218 // ...but align the pointer
1219 const alignment = zcu.navAlignment(nav_index);
1220 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1221 }
1222 },
1223
1224 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1225 return .{ .lea_uav = uav };
10481226 } else {
10491227 // Create the 0xaa bit pattern...
10501228 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
10511229 // ...but align the pointer
1052 const alignment = zcu.navAlignment(nav_index);
1230 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
10531231 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1054 }
1055 },
1056
1057 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1058 return .{ .lea_uav = uav };
1059 } else {
1060 // Create the 0xaa bit pattern...
1061 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1062 // ...but align the pointer
1063 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1064 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1065 },
1232 },
10661233
1067 else => {},
1068 };
1234 else => {},
1235 };
1236 },
10691237 },
10701238 },
10711239 .int => {
src/codegen/aarch64/Select.zig+8-8
......@@ -663,8 +663,8 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void {
663663
664664 maybe_noop: {
665665 switch (isel.air.typeOf(ty_op.operand, ip).restrictedRepr(zcu)) {
666 .double_pointer => break :maybe_noop,
667 .single_pointer => {},
666 .indirect => break :maybe_noop,
667 .direct => {},
668668 }
669669 if (true) break :maybe_noop;
670670 if (ty_op.operand.toIndex()) |src_air_inst_index| {
......@@ -5766,7 +5766,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
57665766 const unrestricted_ty = ty_op.ty.toType();
57675767 const restricted_ty = isel.air.typeOf(ty_op.operand, ip);
57685768 switch (restricted_ty.restrictedRepr(zcu)) {
5769 .double_pointer => {
5769 .indirect => {
57705770 switch (air_tag) {
57715771 else => unreachable,
57725772 .unwrap_restricted => {},
......@@ -5777,7 +5777,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
57775777 _ = try dst_vi.value.load(isel, unrestricted_ty, ptr_mat.ra, .{});
57785778 try ptr_mat.finish(isel);
57795779 },
5780 .single_pointer => try dst_vi.value.move(isel, ty_op.operand),
5780 .direct => try dst_vi.value.move(isel, ty_op.operand),
57815781 }
57825782 }
57835783 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
......@@ -6888,12 +6888,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
68886888 },
68896889 } }));
68906890 try isel.lazy_relocs.append(gpa, .{
6891 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6891 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
68926892 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
68936893 });
68946894 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
68956895 try isel.lazy_relocs.append(gpa, .{
6896 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
6896 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
68976897 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
68986898 });
68996899 try isel.emit(.adrp(ptr_ra.x(), 0));
......@@ -7231,12 +7231,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
72317231 defer isel.freeReg(ptr_ra);
72327232 try isel.emit(.subs(.wzr, error_mat.ra.w(), .{ .register = ptr_ra.w() }));
72337233 try isel.lazy_relocs.append(gpa, .{
7234 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
7234 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
72357235 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
72367236 });
72377237 try isel.emit(.ldr(ptr_ra.w(), .{ .base = ptr_ra.x() }));
72387238 try isel.lazy_relocs.append(gpa, .{
7239 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },
7239 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
72407240 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
72417241 });
72427242 try isel.emit(.adrp(ptr_ra.x(), 0));
src/codegen/c.zig+147-14
......@@ -61,6 +61,8 @@ pub const Mir = struct {
6161 /// less than the natural alignment.
6262 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
6363 ctype_deps: CType.Dependencies,
64 /// Key is a restricted type or value for which we need generated supporting decls.
65 need_restricted: std.array_hash_map.Auto(InternPool.Index, void),
6466 /// Key is an enum type for which we need a generated `@tagName` function.
6567 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
6668 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.
......@@ -74,6 +76,7 @@ pub const Mir = struct {
7476 gpa.free(mir.code);
7577 mir.need_uavs.deinit(gpa);
7678 mir.ctype_deps.deinit(gpa);
79 mir.need_restricted.deinit(gpa);
7780 mir.need_tag_name_funcs.deinit(gpa);
7881 mir.need_never_tail_funcs.deinit(gpa);
7982 mir.need_never_inline_funcs.deinit(gpa);
......@@ -549,6 +552,25 @@ pub const Function = struct {
549552 try f.writeCValue(w, member, .other);
550553 }
551554
555 fn writePanic(f: *Function, panic_id: Zcu.SimplePanicId, w: *std.Io.Writer) !void {
556 const zcu = f.dg.pt.zcu;
557 const ip = &zcu.intern_pool;
558 try renderNavName(w, switch (ip.indexToKey(zcu.builtin_decl_values.get(panic_id.toBuiltin()))) {
559 inline .@"extern", .func => |func| func.owner_nav,
560 .ptr => |ptr| switch (ptr.byte_offset) {
561 0 => switch (ptr.base_addr) {
562 .nav => |nav| nav,
563 else => unreachable,
564 },
565 else => unreachable,
566 },
567 else => unreachable,
568 }, ip);
569 try w.writeAll("();");
570 try f.newline();
571 try airUnreach(f);
572 }
573
552574 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {
553575 return f.dg.fail(format, args);
554576 }
......@@ -645,6 +667,7 @@ pub const DeclGen = struct {
645667 /// `.none` for natural alignment. The specified alignment is never
646668 /// less than the natural alignment.
647669 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
670 need_restricted: std.array_hash_map.Auto(InternPool.Index, void),
648671
649672 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
650673 @branchHint(.cold);
......@@ -1055,11 +1078,24 @@ pub const DeclGen = struct {
10551078 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
10561079 try w.writeByte('}');
10571080 },
1058 .ptr => {
1059 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1060 try w.writeByte('(');
1061 try dg.renderPointer(w, derivation, location);
1062 try w.writeByte(')');
1081 .ptr => switch (ty.restrictedRepr(zcu)) {
1082 .indirect => {
1083 try dg.need_restricted.ensureUnusedCapacity(zcu.gpa, 2);
1084 dg.need_restricted.putAssumeCapacity(ty.toIntern(), {});
1085 dg.need_restricted.putAssumeCapacity(val.toIntern(), {});
1086
1087 const restricted_ty_name = ty.containerTypeName(ip).toSlice(ip);
1088 try w.print("&zig_restricted_{f}__{d}[zig_restricted_index_{f}__{d}]", .{
1089 fmtIdentUnsolo(restricted_ty_name), ty.toIntern(),
1090 fmtIdentUnsolo(restricted_ty_name), val.toIntern(),
1091 });
1092 },
1093 .direct => {
1094 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1095 try w.writeByte('(');
1096 try dg.renderPointer(w, derivation, location);
1097 try w.writeByte(')');
1098 },
10631099 },
10641100 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
10651101 .npv_payload => unreachable, // opv optional
......@@ -2061,6 +2097,55 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
20612097 }
20622098}
20632099
2100pub fn genRestricted(
2101 dg: *DeclGen,
2102 need_restricted: *const std.array_hash_map.Auto(InternPool.Index, std.array_hash_map.Auto(InternPool.Index, void)),
2103 w: *Writer,
2104) Error!void {
2105 const pt = dg.pt;
2106 const zcu = pt.zcu;
2107 const ip = &zcu.intern_pool;
2108 for (need_restricted.keys(), need_restricted.values()) |restricted_ty, *restricted_vals| {
2109 const unrestricted_ptr_type = ip.indexToKey(restricted_ty).restricted_ptr_type.unrestricted_ptr_type;
2110 const unrestricted_cty: CType = try .lower(.fromInterned(unrestricted_ptr_type), &dg.ctype_deps, dg.arena, zcu);
2111 const restricted_ty_name = Type.fromInterned(restricted_ty).containerTypeName(ip).toSlice(ip);
2112 try w.print(
2113 \\#define zig_restricted_len_{f}__{d} {d}u
2114 \\static {f}const zig_restricted_{f}__{d}[zig_restricted_len_{f}__{d}]{f} = {{
2115 \\
2116 , .{
2117 fmtIdentUnsolo(restricted_ty_name),
2118 restricted_ty,
2119 restricted_vals.count(),
2120
2121 unrestricted_cty.fmtDeclaratorPrefix(zcu),
2122 fmtIdentUnsolo(restricted_ty_name),
2123 restricted_ty,
2124 fmtIdentUnsolo(restricted_ty_name),
2125 restricted_ty,
2126 unrestricted_cty.fmtDeclaratorSuffix(zcu),
2127 });
2128 for (restricted_vals.keys(), 0..) |restricted_val, restricted_index| {
2129 try w.print(
2130 \\#define zig_restricted_index_{f}__{d} {d}u
2131 \\ [zig_restricted_index_{f}__{d}] =
2132 , .{
2133 fmtIdentUnsolo(restricted_ty_name),
2134 restricted_val,
2135 restricted_index,
2136
2137 fmtIdentUnsolo(restricted_ty_name),
2138 restricted_val,
2139 });
2140 try dg.renderValue(w, .fromInterned(
2141 try ip.getCoerced(zcu.gpa, zcu.comp.io, pt.tid, restricted_val, unrestricted_ptr_type),
2142 ), .static_initializer);
2143 try w.writeAll(",\n");
2144 }
2145 try w.writeAll("};\n");
2146 }
2147}
2148
20642149pub fn genErrDecls(
20652150 zcu: *const Zcu,
20662151 w: *Writer,
......@@ -2220,6 +2305,7 @@ pub fn generate(
22202305 .expected_block = null,
22212306 .ctype_deps = .empty,
22222307 .uavs = .empty,
2308 .need_restricted = .empty,
22232309 },
22242310 .code = .init(gpa),
22252311 .indent_counter = 0,
......@@ -2231,6 +2317,7 @@ pub fn generate(
22312317 function.code.deinit();
22322318 function.dg.ctype_deps.deinit(gpa);
22332319 function.dg.uavs.deinit(gpa);
2320 function.dg.need_restricted.deinit(gpa);
22342321 function.deinit();
22352322 }
22362323
......@@ -2252,6 +2339,7 @@ pub fn generate(
22522339 .code = &.{},
22532340 .ctype_deps = function.dg.ctype_deps.move(),
22542341 .need_uavs = function.dg.uavs.move(),
2342 .need_restricted = function.dg.need_restricted.move(),
22552343 .need_tag_name_funcs = function.need_tag_name_funcs.move(),
22562344 .need_never_tail_funcs = function.need_never_tail_funcs.move(),
22572345 .need_never_inline_funcs = function.need_never_inline_funcs.move(),
......@@ -5541,8 +5629,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
55415629}
55425630
55435631fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
5544 const pt = f.dg.pt;
5545 const zcu = pt.zcu;
5632 const zcu = f.dg.pt.zcu;
5633 const ip = &zcu.intern_pool;
55465634 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
55475635
55485636 const unrestricted_ty = ty_op.ty.toType();
......@@ -5553,14 +5641,57 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
55535641 const w = &f.code.writer;
55545642 const local = try f.allocLocal(inst, unrestricted_ty);
55555643
5556 try f.writeCValue(w, local, .other);
5557 try w.writeAll(" = ");
55585644 switch (restricted_ty.restrictedRepr(zcu)) {
5559 .double_pointer => {
5560 _ = safety; // TODO
5645 .indirect => {
5646 if (safety) {
5647 const target = &f.dg.mod.resolved_target.result;
5648 const ptr_bits = target.ptrBitWidth();
5649
5650 const int_from_ptr = try f.allocLocal(inst, .usize);
5651 try f.writeCValue(w, int_from_ptr, .other);
5652 try w.print(" = zig_subw_u{d}(({f})", .{
5653 ptr_bits,
5654 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
5655 });
5656 try f.writeCValue(w, operand, .other);
5657 try w.print(", ({f})zig_restricted_{f}__{d}, {f});", .{
5658 CType.fmtTypeName(.{ .int = .uintptr_t }, zcu),
5659 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),
5660 restricted_ty.toIntern(),
5661 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
5662 });
5663 try f.newline();
5664
5665 const rotate_amount = std.math.log2_int(u16, @divExact(ptr_bits, 8));
5666 try w.print("if ((zig_shr_u{d}(", .{ptr_bits});
5667 try f.writeCValue(w, int_from_ptr, .other);
5668 try w.print(", {f}) | zig_shlw_u{d}(", .{
5669 fmtUnsignedIntLiteralSmall(target, .uint8_t, rotate_amount, false, 10, .lower),
5670 ptr_bits,
5671 });
5672 try f.writeCValue(w, int_from_ptr, .other);
5673 try w.print(", {f}, {f})) >= zig_restricted_len_{f}__{d}) {{", .{
5674 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits - rotate_amount, false, 10, .lower),
5675 fmtUnsignedIntLiteralSmall(target, .uint8_t, ptr_bits, false, 10, .lower),
5676 fmtIdentUnsolo(restricted_ty.containerTypeName(ip).toSlice(ip)),
5677 restricted_ty.toIntern(),
5678 });
5679 f.indent();
5680 try f.newline();
5681 try f.writePanic(.corrupt_restricted_pointer, w);
5682 try f.outdent();
5683 try w.writeByte('}');
5684 try f.newline();
5685 }
5686 try f.writeCValue(w, local, .other);
5687 try w.writeAll(" = ");
55615688 try f.writeCValueDeref(w, operand);
55625689 },
5563 .single_pointer => try f.writeCValue(w, operand, .other),
5690 .direct => {
5691 try f.writeCValue(w, local, .other);
5692 try w.writeAll(" = ");
5693 try f.writeCValue(w, operand, .other);
5694 },
55645695 }
55655696 try w.writeByte(';');
55665697 try f.newline();
......@@ -5849,7 +5980,8 @@ fn airBinBuiltinCall(
58495980 try f.writeCValue(w, rhs, .other);
58505981 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
58515982 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
5852 try w.writeAll(");\n");
5983 try w.writeAll(");");
5984 try f.newline();
58535985 try v.end(f, inst, w);
58545986
58555987 return local;
......@@ -6459,7 +6591,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
64596591 },
64606592 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
64616593 }
6462 try w.writeAll(";\n");
6594 try w.writeByte(';');
6595 try f.newline();
64636596 }
64646597
64656598 return local;
src/codegen/c/type.zig+2-2
......@@ -285,7 +285,7 @@ pub const CType = union(enum) {
285285 .pointer => {
286286 const ptr = cur_ty.ptrInfo(zcu);
287287 if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) {
288 .double_pointer => {
288 .indirect => {
289289 const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu);
290290 const unrestricted_cty_buf = try arena.create(CType);
291291 unrestricted_cty_buf.* = unrestricted_cty;
......@@ -296,7 +296,7 @@ pub const CType = union(enum) {
296296 .nonstring = false,
297297 } };
298298 },
299 .single_pointer => {},
299 .direct => {},
300300 };
301301 switch (ptr.flags.size) {
302302 .slice => {
src/codegen/llvm/FuncGen.zig+5-3
......@@ -3261,11 +3261,13 @@ fn airUnwrapRestricted(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Alloc
32613261 const restricted_ty = self.typeOf(ty_op.operand);
32623262 const operand = try self.resolveInst(ty_op.operand);
32633263 switch (restricted_ty.restrictedRepr(zcu)) {
3264 .double_pointer => {
3265 _ = safety; // TODO
3264 .indirect => {
3265 if (safety) {
3266 // TODO
3267 }
32663268 return self.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "restricted.unwrap");
32673269 },
3268 .single_pointer => return operand,
3270 .direct => return operand,
32693271 }
32703272}
32713273
src/codegen/riscv64/CodeGen.zig+25-19
......@@ -1282,9 +1282,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
12821282 const pt = func.pt;
12831283 const zcu = pt.zcu;
12841284 const ip = &zcu.intern_pool;
1285 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) {
1286 .@"enum" => {
1287 const enum_ty = Type.fromInterned(lazy_sym.ty);
1285 switch (ip.indexToKey(lazy_sym.key)) {
1286 .enum_type => {
1287 const enum_ty = Type.fromInterned(lazy_sym.key);
12881288 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
12891289
12901290 const param_regs = abi.Registers.Integer.function_arg_regs;
......@@ -1301,9 +1301,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
13011301 const zo = elf_file.zigObjectPtr().?;
13021302 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
13031303 .kind = .const_data,
1304 .ty = enum_ty.toIntern(),
1304 .key = lazy_sym.key,
13051305 }) catch |err|
1306 return func.fail("{s} creating lazy symbol", .{@errorName(err)});
1306 return func.fail("{t} creating lazy symbol", .{err});
13071307
13081308 try func.genSetReg(Type.u64, data_reg, .{ .lea_symbol = .{ .sym = sym_index } });
13091309
......@@ -1367,8 +1367,8 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
13671367 });
13681368 },
13691369 else => return func.fail(
1370 "TODO implement {s} for {f}",
1371 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
1370 "TODO implement {t} for {f}",
1371 .{ lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt) },
13721372 ),
13731373 }
13741374}
......@@ -8359,22 +8359,28 @@ fn wantSafety(func: *Func) bool {
83598359
83608360fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
83618361 @branchHint(.cold);
8362 const zcu = func.pt.zcu;
8363 switch (func.owner) {
8364 .nav_index => |i| return zcu.codegenFail(i, format, args),
8365 .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
8366 }
8367 return error.CodegenFail;
8362 const pt = func.pt;
8363 const zcu = pt.zcu;
8364 return switch (func.owner) {
8365 .nav_index => |i| zcu.codegenFail(i, format, args),
8366 .lazy_sym => |s| switch (zcu.intern_pool.typeOf(s.key)) {
8367 .type_type => zcu.codegenFailType(s.key, format, args),
8368 else => std.debug.panic("{f}: " ++ format, .{Value.fromInterned(s.key).fmtValue(pt)} ++ args),
8369 },
8370 };
83688371}
83698372
83708373fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
83718374 @branchHint(.cold);
8372 const zcu = func.pt.zcu;
8373 switch (func.owner) {
8374 .nav_index => |i| return zcu.codegenFailMsg(i, msg),
8375 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
8376 }
8377 return error.CodegenFail;
8375 const pt = func.pt;
8376 const zcu = pt.zcu;
8377 return switch (func.owner) {
8378 .nav_index => |i| zcu.codegenFailMsg(i, msg),
8379 .lazy_sym => |s| switch (zcu.intern_pool.typeOf(s.key)) {
8380 .type_type => zcu.codegenFailTypeMsg(s.key, msg),
8381 else => std.debug.panic("{f}: {s}", .{ Value.fromInterned(s.key).fmtValue(pt), msg.msg }),
8382 },
8383 };
83788384}
83798385
83808386fn parseRegName(name: []const u8) ?Register {
src/codegen/wasm/CodeGen.zig+2-2
......@@ -6730,11 +6730,11 @@ fn airUnwrapRestricted(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerEr
67306730 const unrestricted_ty = ty_op.ty.toType();
67316731 const restricted_ty = cg.typeOf(ty_op.operand);
67326732 const result = result: switch (restricted_ty.restrictedRepr(zcu)) {
6733 .double_pointer => {
6733 .indirect => {
67346734 _ = safety; // TODO
67356735 break :result try cg.load(operand, unrestricted_ty, 0);
67366736 },
6737 .single_pointer => cg.reuseOperand(ty_op.operand, operand),
6737 .direct => cg.reuseOperand(ty_op.operand, operand),
67386738 };
67396739 return cg.finishAir(inst, result, &.{ty_op.operand});
67406740}
src/codegen/x86_64/CodeGen.zig+211-244
......@@ -527,45 +527,38 @@ pub const MCValue = union(enum) {
527527
528528 pub fn format(mcv: MCValue, w: *Writer) Writer.Error!void {
529529 switch (mcv) {
530 .none, .unreach, .dead, .undef => try w.print("({s})", .{@tagName(mcv)}),
530 .none, .unreach, .dead, .undef => try w.print("({t})", .{mcv}),
531531 .immediate => |pl| try w.print("0x{x}", .{pl}),
532532 .memory => |pl| try w.print("[ds:0x{x}]", .{pl}),
533 inline .eflags, .register => |pl| try w.print("{s}", .{@tagName(pl)}),
534 .register_pair => |pl| try w.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
535 .register_triple => |pl| try w.print("{s}:{s}:{s}", .{
536 @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
537 }),
538 .register_quadruple => |pl| try w.print("{s}:{s}:{s}:{s}", .{
539 @tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
540 }),
541 .register_offset => |pl| try w.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
542 .register_overflow => |pl| try w.print("{s}:{s}", .{
543 @tagName(pl.eflags),
544 @tagName(pl.reg),
545 }),
546 .register_mask => |pl| try w.print("mask({s},{f}):{c}{s}", .{
547 @tagName(pl.info.kind),
533 inline .eflags, .register => |pl| try w.print("{t}", .{pl}),
534 .register_pair => |pl| try w.print("{t}:{t}", .{ pl[1], pl[0] }),
535 .register_triple => |pl| try w.print("{t}:{t}:{t}", .{ pl[2], pl[1], pl[0] }),
536 .register_quadruple => |pl| try w.print("{t}:{t}:{t}:{t}", .{ pl[3], pl[2], pl[1], pl[0] }),
537 .register_offset => |pl| try w.print("{t} + 0x{x}", .{ pl.reg, pl.off }),
538 .register_overflow => |pl| try w.print("{t}:{t}", .{ pl.eflags, pl.reg }),
539 .register_mask => |pl| try w.print("mask({t},{f}):{c}{t}", .{
540 pl.info.kind,
548541 pl.info.scalar,
549542 @as(u8, if (pl.info.inverted) '!' else ' '),
550 @tagName(pl.reg),
543 pl.reg,
551544 }),
552 .indirect => |pl| try w.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
545 .indirect => |pl| try w.print("[{t} + 0x{x}]", .{ pl.reg, pl.off }),
553546 .indirect_load_frame => |pl| try w.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),
554547 .load_frame => |pl| try w.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),
555548 .lea_frame => |pl| try w.print("{f} + 0x{x}", .{ pl.index, pl.off }),
556 .load_nav => |pl| try w.print("[nav:{d}]", .{@intFromEnum(pl)}),
557 .lea_nav => |pl| try w.print("nav:{d}", .{@intFromEnum(pl)}),
558 .load_uav => |pl| try w.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
559 .lea_uav => |pl| try w.print("uav:{d}", .{@intFromEnum(pl.val)}),
560 .load_lazy_sym => |pl| try w.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
561 .lea_lazy_sym => |pl| try w.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
562 .load_extern_func => |pl| try w.print("[extern:{d}]", .{@intFromEnum(pl)}),
563 .lea_extern_func => |pl| try w.print("extern:{d}", .{@intFromEnum(pl)}),
549 .load_nav => |pl| try w.print("[nav:{d}]", .{pl}),
550 .lea_nav => |pl| try w.print("nav:{d}", .{pl}),
551 .load_uav => |pl| try w.print("[uav:{d}]", .{pl.val}),
552 .lea_uav => |pl| try w.print("uav:{d}", .{pl.val}),
553 .load_lazy_sym => |pl| try w.print("[lazy:{t}:{d}]", .{ pl.kind, pl.key }),
554 .lea_lazy_sym => |pl| try w.print("lazy:{t}:{d}", .{ pl.kind, pl.key }),
555 .load_extern_func => |pl| try w.print("[extern:{d}]", .{pl}),
556 .lea_extern_func => |pl| try w.print("extern:{d}", .{pl}),
564557 .elementwise_args => |pl| try w.print("elementwise:{d}:[{f} + 0x{x}]", .{
565558 pl.regs, pl.frame_index, pl.frame_off,
566559 }),
567560 .reserved_frame => |pl| try w.print("(dead:{f})", .{pl}),
568 .air_ref => |pl| try w.print("(air:0x{x})", .{@intFromEnum(pl)}),
561 .air_ref => |pl| try w.print("(air:0x{x})", .{pl}),
569562 }
570563 }
571564};
......@@ -1138,7 +1131,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {
11381131 if (first) {
11391132 const ip = &data.self.pt.zcu.intern_pool;
11401133 const mir_inst = lower.mir.instructions.get(data.inst);
1141 try w.print(" | .{s}", .{@tagName(mir_inst.ops)});
1134 try w.print(" | .{t}", .{mir_inst.ops});
11421135 switch (mir_inst.ops) {
11431136 else => unreachable,
11441137 .pseudo_dbg_prologue_end_none,
......@@ -2059,7 +2052,7 @@ fn gen(
20592052 .{},
20602053 );
20612054 },
2062 else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}),
2055 else => |cc| return self.fail("{t} does not support var args", .{cc}),
20632056 };
20642057
20652058 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
......@@ -4452,8 +4445,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44524445 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
44534446 } },
44544447 } }) catch |err| switch (err) {
4455 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
4456 @tagName(air_tag),
4448 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
4449 air_tag,
44574450 cg.typeOf(bin_op.lhs).fmt(pt),
44584451 ops[0].tracking(cg),
44594452 ops[1].tracking(cg),
......@@ -4464,8 +4457,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
44644457 else => unreachable,
44654458 .add, .add_optimized => {},
44664459 .add_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
4467 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
4468 @tagName(air_tag),
4460 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
4461 air_tag,
44694462 cg.typeOf(bin_op.lhs).fmt(pt),
44704463 res[0].tracking(cg),
44714464 }),
......@@ -13029,8 +13022,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1302913022 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
1303013023 } },
1303113024 } }) catch |err| switch (err) {
13032 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
13033 @tagName(air_tag),
13025 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
13026 air_tag,
1303413027 cg.typeOf(bin_op.lhs).fmt(pt),
1303513028 ops[0].tracking(cg),
1303613029 ops[1].tracking(cg),
......@@ -15203,8 +15196,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1520315196 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
1520415197 } },
1520515198 } }) catch |err| switch (err) {
15206 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
15207 @tagName(air_tag),
15199 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
15200 air_tag,
1520815201 cg.typeOf(bin_op.lhs).fmt(pt),
1520915202 ops[0].tracking(cg),
1521015203 ops[1].tracking(cg),
......@@ -15215,8 +15208,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
1521515208 else => unreachable,
1521615209 .sub, .sub_optimized => {},
1521715210 .sub_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
15218 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
15219 @tagName(air_tag),
15211 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
15212 air_tag,
1522015213 cg.typeOf(bin_op.lhs).fmt(pt),
1522115214 res[0].tracking(cg),
1522215215 }),
......@@ -22050,8 +22043,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2205022043 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
2205122044 } },
2205222045 } }) catch |err| switch (err) {
22053 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
22054 @tagName(air_tag),
22046 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
22047 air_tag,
2205522048 cg.typeOf(bin_op.lhs).fmt(pt),
2205622049 ops[0].tracking(cg),
2205722050 ops[1].tracking(cg),
......@@ -24987,8 +24980,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2498724980 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
2498824981 } },
2498924982 } }) catch |err| switch (err) {
24990 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
24991 @tagName(air_tag),
24983 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
24984 air_tag,
2499224985 ty.fmt(pt),
2499324986 ops[0].tracking(cg),
2499424987 ops[1].tracking(cg),
......@@ -26785,8 +26778,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2678526778 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
2678626779 } },
2678726780 } }) catch |err| switch (err) {
26788 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
26789 @tagName(air_tag),
26781 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
26782 air_tag,
2679026783 ty.fmt(pt),
2679126784 ops[0].tracking(cg),
2679226785 ops[1].tracking(cg),
......@@ -26794,8 +26787,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2679426787 else => |e| return e,
2679526788 };
2679626789 res[0].wrapInt(cg) catch |err| switch (err) {
26797 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
26798 @tagName(air_tag),
26790 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
26791 air_tag,
2679926792 cg.typeOf(bin_op.lhs).fmt(pt),
2680026793 res[0].tracking(cg),
2680126794 }),
......@@ -32010,8 +32003,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3201032003 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp3q, ._, ._ },
3201132004 } },
3201232005 } }) catch |err| switch (err) {
32013 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
32014 @tagName(air_tag),
32006 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
32007 air_tag,
3201532008 cg.typeOf(bin_op.lhs).fmt(pt),
3201632009 ops[0].tracking(cg),
3201732010 ops[1].tracking(cg),
......@@ -33248,8 +33241,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3324833241 assert(air_tag == .div_exact);
3324933242 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
3325033243 }) catch |err| switch (err) {
33251 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
33252 @tagName(air_tag),
33244 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
33245 air_tag,
3325333246 ty.fmt(pt),
3325433247 ops[0].tracking(cg),
3325533248 ops[1].tracking(cg),
......@@ -34705,8 +34698,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3470534698 } }) else err: {
3470634699 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
3470734700 }) catch |err| switch (err) {
34708 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
34709 @tagName(air_tag),
34701 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
34702 air_tag,
3471034703 ty.fmt(pt),
3471134704 ops[0].tracking(cg),
3471234705 ops[1].tracking(cg),
......@@ -36266,8 +36259,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3626636259 } },
3626736260 } },
3626836261 }) catch |err| switch (err) {
36269 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
36270 @tagName(air_tag),
36262 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
36263 air_tag,
3627136264 cg.typeOf(bin_op.lhs).fmt(pt),
3627236265 ops[0].tracking(cg),
3627336266 ops[1].tracking(cg),
......@@ -37958,8 +37951,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3795837951 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3795937952 } },
3796037953 } })) catch |err| switch (err) {
37961 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
37962 @tagName(air_tag),
37954 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
37955 air_tag,
3796337956 ty.fmt(pt),
3796437957 ops[0].tracking(cg),
3796537958 ops[1].tracking(cg),
......@@ -39740,8 +39733,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
3974039733 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
3974139734 } },
3974239735 } }) catch |err| switch (err) {
39743 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
39744 @tagName(air_tag),
39736 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
39737 air_tag,
3974539738 cg.typeOf(bin_op.lhs).fmt(pt),
3974639739 ops[0].tracking(cg),
3974739740 ops[1].tracking(cg),
......@@ -43253,8 +43246,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4325343246 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
4325443247 } },
4325543248 } }) catch |err| switch (err) {
43256 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
43257 @tagName(air_tag),
43249 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43250 air_tag,
4325843251 cg.typeOf(bin_op.lhs).fmt(pt),
4325943252 ops[0].tracking(cg),
4326043253 ops[1].tracking(cg),
......@@ -43367,8 +43360,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4336743360 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
4336843361 } },
4336943362 } }) catch |err| switch (err) {
43370 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
43371 @tagName(air_tag),
43363 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43364 air_tag,
4337243365 cg.typeOf(bin_op.lhs).fmt(pt),
4337343366 ops[0].tracking(cg),
4337443367 ops[1].tracking(cg),
......@@ -43496,8 +43489,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4349643489 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
4349743490 } },
4349843491 } }) catch |err| switch (err) {
43499 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
43500 @tagName(air_tag),
43492 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43493 air_tag,
4350143494 cg.typeOf(bin_op.lhs).fmt(pt),
4350243495 ops[0].tracking(cg),
4350343496 ops[1].tracking(cg),
......@@ -47805,8 +47798,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4780547798 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4780647799 } },
4780747800 } }) catch |err| switch (err) {
47808 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
47809 @tagName(air_tag),
47801 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
47802 air_tag,
4781047803 cg.typeOf(bin_op.lhs).fmt(pt),
4781147804 ops[0].tracking(cg),
4781247805 ops[1].tracking(cg),
......@@ -52108,8 +52101,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5210852101 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
5210952102 } },
5211052103 } }) catch |err| switch (err) {
52111 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
52112 @tagName(air_tag),
52104 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
52105 air_tag,
5211352106 cg.typeOf(bin_op.lhs).fmt(pt),
5211452107 ops[0].tracking(cg),
5211552108 ops[1].tracking(cg),
......@@ -52957,8 +52950,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5295752950 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
5295852951 } },
5295952952 } }) catch |err| switch (err) {
52960 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
52961 @tagName(air_tag),
52953 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
52954 air_tag,
5296252955 ty_pl.ty.toType().fmt(pt),
5296352956 ops[0].tracking(cg),
5296452957 ops[1].tracking(cg),
......@@ -53862,8 +53855,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5386253855 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
5386353856 } },
5386453857 } }) catch |err| switch (err) {
53865 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
53866 @tagName(air_tag),
53858 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
53859 air_tag,
5386753860 ty_pl.ty.toType().fmt(pt),
5386853861 ops[0].tracking(cg),
5386953862 ops[1].tracking(cg),
......@@ -57459,8 +57452,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
5745957452 .{ ._, ._, .@"or", .tmp2q, .tmp1q, ._, ._ },
5746057453 } },
5746157454 } }) catch |err| switch (err) {
57462 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
57463 @tagName(air_tag),
57455 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
57456 air_tag,
5746457457 ty_pl.ty.toType().fmt(pt),
5746557458 ops[0].tracking(cg),
5746657459 ops[1].tracking(cg),
......@@ -60804,8 +60797,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6080460797 .{ ._, ._, .@"or", .tmp4q, .tmp5q, ._, ._ },
6080560798 } },
6080660799 } }) catch |err| switch (err) {
60807 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
60808 @tagName(air_tag),
60800 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
60801 air_tag,
6080960802 ty_pl.ty.toType().fmt(pt),
6081060803 ops[0].tracking(cg),
6081160804 ops[1].tracking(cg),
......@@ -61199,8 +61192,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6119961192 } },
6120061193 } },
6120161194 }) catch |err| switch (err) {
61202 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
61203 @tagName(air_tag),
61195 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
61196 air_tag,
6120461197 cg.typeOf(bin_op.lhs).fmt(pt),
6120561198 ops[0].tracking(cg),
6120661199 ops[1].tracking(cg),
......@@ -61762,8 +61755,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6176261755 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
6176361756 } },
6176461757 } }) catch |err| switch (err) {
61765 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
61766 @tagName(air_tag),
61758 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
61759 air_tag,
6176761760 cg.typeOf(bin_op.lhs).fmt(pt),
6176861761 cg.typeOf(bin_op.rhs).fmt(pt),
6176961762 ops[0].tracking(cg),
......@@ -62124,8 +62117,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6212462117 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
6212562118 } },
6212662119 } }) catch |err| switch (err) {
62127 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
62128 @tagName(air_tag),
62120 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
62121 air_tag,
6212962122 cg.typeOf(bin_op.lhs).fmt(pt),
6213062123 cg.typeOf(bin_op.rhs).fmt(pt),
6213162124 ops[0].tracking(cg),
......@@ -62136,8 +62129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6213662129 switch (air_tag) {
6213762130 else => unreachable,
6213862131 .shl => res[0].wrapInt(cg) catch |err| switch (err) {
62139 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
62140 @tagName(air_tag),
62132 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
62133 air_tag,
6214162134 cg.typeOf(bin_op.lhs).fmt(pt),
6214262135 res[0].tracking(cg),
6214362136 }),
......@@ -62303,8 +62296,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6230362296 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
6230462297 } },
6230562298 } }) catch |err| switch (err) {
62306 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
62307 @tagName(air_tag),
62299 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
62300 air_tag,
6230862301 cg.typeOf(bin_op.rhs).fmt(pt),
6230962302 ops[1].tracking(cg),
6231062303 }),
......@@ -65560,8 +65553,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6556065553 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp1q, ._, ._ },
6556165554 } },
6556265555 } }) catch |err| switch (err) {
65563 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
65564 @tagName(air_tag),
65556 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
65557 air_tag,
6556565558 lhs_ty.fmt(pt),
6556665559 ops[0].tracking(cg),
6556765560 ops[1].tracking(cg),
......@@ -67345,8 +67338,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
6734567338 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
6734667339 } },
6734767340 } }) catch |err| switch (err) {
67348 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
67349 @tagName(air_tag),
67341 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
67342 air_tag,
6735067343 ty_op.ty.toType().fmt(pt),
6735167344 ops[0].tracking(cg),
6735267345 }),
......@@ -70497,8 +70490,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7049770490 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7049870491 } },
7049970492 } }) catch |err| switch (err) {
70500 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
70501 @tagName(air_tag),
70493 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
70494 air_tag,
7050270495 cg.typeOf(ty_op.operand).fmt(pt),
7050370496 ops[0].tracking(cg),
7050470497 }),
......@@ -70894,8 +70887,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7089470887 .{ .@"0:", ._, .lea, .dst0d, .leasia(.dst0, .@"8", .tmp0, .add_8_src0_size), ._, ._ },
7089570888 } },
7089670889 } }) catch |err| switch (err) {
70897 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
70898 @tagName(air_tag),
70890 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
70891 air_tag,
7089970892 cg.typeOf(ty_op.operand).fmt(pt),
7090070893 ops[0].tracking(cg),
7090170894 }),
......@@ -71782,8 +71775,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7178271775 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7178371776 } },
7178471777 } }) catch |err| switch (err) {
71785 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
71786 @tagName(air_tag),
71778 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
71779 air_tag,
7178771780 cg.typeOf(ty_op.operand).fmt(pt),
7178871781 ops[0].tracking(cg),
7178971782 }),
......@@ -72431,8 +72424,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7243172424 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7243272425 } },
7243372426 } }) catch |err| switch (err) {
72434 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
72435 @tagName(air_tag),
72427 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
72428 air_tag,
7243672429 ty_op.ty.toType().fmt(pt),
7243772430 ops[0].tracking(cg),
7243872431 }),
......@@ -75533,8 +75526,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7553375526 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7553475527 } },
7553575528 } }) catch |err| switch (err) {
75536 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
75537 @tagName(air_tag),
75529 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
75530 air_tag,
7553875531 ty_op.ty.toType().fmt(pt),
7553975532 ops[0].tracking(cg),
7554075533 }),
......@@ -76595,8 +76588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7659576588 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
7659676589 } },
7659776590 } }) catch |err| switch (err) {
76598 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
76599 @tagName(air_tag),
76591 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
76592 air_tag,
7660076593 cg.typeOf(un_op).fmt(pt),
7660176594 ops[0].tracking(cg),
7660276595 }),
......@@ -77445,8 +77438,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7744577438 } },
7744677439 } },
7744777440 }) catch |err| switch (err) {
77448 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
77449 @tagName(air_tag),
77441 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
77442 air_tag,
7745077443 cg.typeOf(un_op).fmt(pt),
7745177444 ops[0].tracking(cg),
7745277445 }),
......@@ -78996,8 +78989,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
7899678989 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
7899778990 } },
7899878991 } }) catch |err| switch (err) {
78999 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
79000 @tagName(air_tag),
78992 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
78993 air_tag,
7900178994 cg.typeOf(ty_op.operand).fmt(pt),
7900278995 ops[0].tracking(cg),
7900378996 }),
......@@ -80332,8 +80325,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8033280325 } },
8033380326 } },
8033480327 }) catch |err| switch (err) {
80335 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
80336 @tagName(air_tag),
80328 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
80329 air_tag,
8033780330 cg.typeOf(un_op).fmt(pt),
8033880331 ops[0].tracking(cg),
8033980332 }),
......@@ -80872,8 +80865,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8087280865 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
8087380866 } },
8087480867 } }) catch |err| switch (err) {
80875 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
80876 @tagName(air_tag),
80868 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
80869 air_tag,
8087780870 cg.typeOf(un_op).fmt(pt),
8087880871 ops[0].tracking(cg),
8087980872 }),
......@@ -81352,8 +81345,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8135281345 } else err: {
8135381346 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
8135481347 }) catch |err| switch (err) {
81355 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
81356 @tagName(air_tag),
81348 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
81349 air_tag,
8135781350 cg.typeOf(bin_op.lhs).fmt(pt),
8135881351 ops[0].tracking(cg),
8135981352 ops[1].tracking(cg),
......@@ -81927,8 +81920,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8192781920 .@"struct", .@"union" => {
8192881921 assert(ty.containerLayout(zcu) == .@"packed");
8192981922 for (&ops) |*op| op.wrapInt(cg) catch |err| switch (err) {
81930 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{
81931 @tagName(air_tag),
81923 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
81924 air_tag,
8193281925 ty.fmt(pt),
8193381926 op.tracking(cg),
8193481927 }),
......@@ -81939,8 +81932,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8193981932 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
8194081933 },
8194181934 }) catch |err| switch (err) {
81942 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
81943 @tagName(air_tag),
81935 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
81936 air_tag,
8194481937 ty.fmt(pt),
8194581938 ops[0].tracking(cg),
8194681939 ops[1].tracking(cg),
......@@ -89017,9 +89010,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8901789010 } },
8901889011 }),
8901989012 }) catch |err| switch (err) {
89020 error.SelectFailed => return cg.fail("failed to select {s} {s} {f} {f} {f}", .{
89021 @tagName(air_tag),
89022 @tagName(vector_cmp.compareOperator()),
89013 error.SelectFailed => return cg.fail("failed to select {t} {t} {f} {f} {f}", .{
89014 air_tag,
89015 vector_cmp.compareOperator(),
8902389016 cg.typeOf(vector_cmp.lhs).fmt(pt),
8902489017 ops[0].tracking(cg),
8902589018 ops[1].tracking(cg),
......@@ -91595,8 +91588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9159591588 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
9159691589 } },
9159791590 } }) catch |err| switch (err) {
91598 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
91599 @tagName(air_tag),
91591 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
91592 air_tag,
9160091593 ty_op.ty.toType().fmt(pt),
9160191594 cg.typeOf(ty_op.operand).fmt(pt),
9160291595 ops[0].tracking(cg),
......@@ -93270,8 +93263,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9327093263 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
9327193264 } },
9327293265 } }) catch |err| switch (err) {
93273 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
93274 @tagName(air_tag),
93266 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
93267 air_tag,
9327593268 ty_op.ty.toType().fmt(pt),
9327693269 cg.typeOf(ty_op.operand).fmt(pt),
9327793270 ops[0].tracking(cg),
......@@ -98028,8 +98021,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
9802898021 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
9802998022 } },
9803098023 } }) catch |err| switch (err) {
98031 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
98032 @tagName(air_tag),
98024 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
98025 air_tag,
9803398026 dst_ty.fmt(pt),
9803498027 src_ty.fmt(pt),
9803598028 ops[0].tracking(cg),
......@@ -103694,8 +103687,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103694103687 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
103695103688 } },
103696103689 } }) catch |err| switch (err) {
103697 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
103698 @tagName(air_tag),
103690 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103691 air_tag,
103699103692 ty_op.ty.toType().fmt(pt),
103700103693 cg.typeOf(ty_op.operand).fmt(pt),
103701103694 ops[0].tracking(cg),
......@@ -103835,8 +103828,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103835103828 const restricted_ty = cg.typeOf(ty_op.operand);
103836103829 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
103837103830 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {
103838 .double_pointer => {
103839 switch (air_tag) {
103831 .indirect => {
103832 if (zcu.comp.config.use_new_linker) switch (air_tag) {
103840103833 else => unreachable,
103841103834 .unwrap_restricted => {},
103842103835 .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{
......@@ -103848,7 +103841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103848103841 .call_frame = .{ .alignment = .@"32" },
103849103842 .extra_temps = .{
103850103843 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103851 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } },
103844 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103852103845 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103853103846 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103854103847 .unused,
......@@ -103878,7 +103871,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103878103871 .call_frame = .{ .alignment = .@"16" },
103879103872 .extra_temps = .{
103880103873 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103881 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } },
103874 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103882103875 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103883103876 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103884103877 .unused,
......@@ -103907,7 +103900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103907103900 .call_frame = .{ .alignment = .@"8" },
103908103901 .extra_temps = .{
103909103902 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103910 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .const_data, .ref = .src0 } } },
103903 .{ .type = .usize, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data, .ref = .src0 } } },
103911103904 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103912103905 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103913103906 .unused,
......@@ -103929,18 +103922,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103929103922 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103930103923 } },
103931103924 } }) catch |err| switch (err) {
103932 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
103933 @tagName(air_tag),
103925 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103926 air_tag,
103934103927 unrestricted_ty.fmt(pt),
103935103928 restricted_ty.fmt(pt),
103936103929 ops[0].tracking(cg),
103937103930 }),
103938103931 else => |e| return e,
103939103932 },
103940 }
103933 };
103941103934 break :res try ops[0].load(unrestricted_ty, .{}, cg);
103942103935 },
103943 .single_pointer => ops[0],
103936 .direct => ops[0],
103944103937 };
103945103938 try res.finish(inst, &.{ty_op.operand}, &ops, cg);
103946103939 },
......@@ -115178,8 +115171,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115178115171 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
115179115172 } },
115180115173 } }) catch |err| switch (err) {
115181 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
115182 @tagName(air_tag),
115174 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
115175 air_tag,
115183115176 ty_op.ty.toType().fmt(pt),
115184115177 cg.typeOf(ty_op.operand).fmt(pt),
115185115178 ops[0].tracking(cg),
......@@ -127197,8 +127190,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
127197127190 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
127198127191 } },
127199127192 } }) catch |err| switch (err) {
127200 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{
127201 @tagName(air_tag),
127193 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
127194 air_tag,
127202127195 ty_op.ty.toType().fmt(pt),
127203127196 cg.typeOf(ty_op.operand).fmt(pt),
127204127197 ops[0].tracking(cg),
......@@ -161387,9 +161380,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161387161380 } },
161388161381 } },
161389161382 }) catch |err| switch (err) {
161390 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{
161391 @tagName(air_tag),
161392 @tagName(reduce.operation),
161383 error.SelectFailed => return cg.fail("failed to select {t}.{t} {f} {f}", .{
161384 air_tag,
161385 reduce.operation,
161393161386 cg.typeOf(reduce.operand).fmt(pt),
161394161387 ops[0].tracking(cg),
161395161388 }),
......@@ -161398,9 +161391,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161398161391 switch (reduce.operation) {
161399161392 .And, .Or, .Xor, .Min, .Max => {},
161400161393 .Add, .Mul => if (cg.intInfo(res_ty)) |_| res[0].wrapInt(cg) catch |err| switch (err) {
161401 error.SelectFailed => return cg.fail("failed to select {s}.{s} wrap {f} {f}", .{
161402 @tagName(air_tag),
161403 @tagName(reduce.operation),
161394 error.SelectFailed => return cg.fail("failed to select {t}.{t} wrap {f} {f}", .{
161395 air_tag,
161396 reduce.operation,
161404161397 res_ty.fmt(pt),
161405161398 res[0].tracking(cg),
161406161399 }),
......@@ -169101,9 +169094,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169101169094 } },
169102169095 } },
169103169096 }) catch |err| switch (err) {
169104 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{
169105 @tagName(air_tag),
169106 @tagName(reduce.operation),
169097 error.SelectFailed => return cg.fail("failed to select {t}.{t} {f} {f}", .{
169098 air_tag,
169099 reduce.operation,
169107169100 cg.typeOf(reduce.operand).fmt(pt),
169108169101 ops[0].tracking(cg),
169109169102 }),
......@@ -170898,8 +170891,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170898170891 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
170899170892 } },
170900170893 } }) catch |err| switch (err) {
170901 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
170902 @tagName(air_tag),
170894 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
170895 air_tag,
170903170896 ty_op.ty.toType().fmt(pt),
170904170897 ops[0].tracking(cg),
170905170898 }),
......@@ -170914,8 +170907,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170914170907 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
170915170908 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }) ++ .{undefined};
170916170909 ops[2] = ops[0].getByteLen(cg) catch |err| switch (err) {
170917 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
170918 @tagName(air_tag),
170910 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
170911 air_tag,
170919170912 cg.typeOf(bin_op.lhs).fmt(pt),
170920170913 cg.typeOf(bin_op.rhs).fmt(pt),
170921170914 ops[0].tracking(cg),
......@@ -170955,8 +170948,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170955170948 } },
170956170949 }},
170957170950 }) catch |err| switch (err) {
170958 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f} {f}", .{
170959 @tagName(air_tag),
170951 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f} {f}", .{
170952 air_tag,
170960170953 cg.typeOf(bin_op.lhs).fmt(pt),
170961170954 cg.typeOf(bin_op.rhs).fmt(pt),
170962170955 ops[0].tracking(cg),
......@@ -171136,8 +171129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171136171129 .{ ._, ._, .@"test", .tmp0p, .tmp0p, ._, ._ },
171137171130 } },
171138171131 } }) catch |err| switch (err) {
171139 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
171140 @tagName(air_tag),
171132 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171133 air_tag,
171141171134 cg.typeOf(un_op).fmt(pt),
171142171135 ops[0].tracking(cg),
171143171136 }),
......@@ -171302,8 +171295,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171302171295 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
171303171296 } },
171304171297 } }) catch |err| switch (err) {
171305 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
171306 @tagName(air_tag),
171298 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171299 air_tag,
171307171300 cg.typeOf(un_op).fmt(pt),
171308171301 ops[0].tracking(cg),
171309171302 }),
......@@ -171323,7 +171316,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171323171316 .{ .src = .{ .to_gpr, .none, .none } },
171324171317 },
171325171318 .extra_temps = .{
171326 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
171319 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171327171320 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171328171321 .unused,
171329171322 .unused,
......@@ -171352,7 +171345,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171352171345 .{ .src = .{ .to_gpr, .none, .none } },
171353171346 },
171354171347 .extra_temps = .{
171355 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
171348 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171356171349 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171357171350 .unused,
171358171351 .unused,
......@@ -171381,7 +171374,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171381171374 .{ .src = .{ .to_gpr, .none, .none } },
171382171375 },
171383171376 .extra_temps = .{
171384 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
171377 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171385171378 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171386171379 .unused,
171387171380 .unused,
......@@ -171404,8 +171397,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171404171397 .{ ._, ._, .lea, .dst1d, .leai(.dst1, .tmp1), ._, ._ },
171405171398 } },
171406171399 } }) catch |err| switch (err) {
171407 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
171408 @tagName(air_tag),
171400 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171401 air_tag,
171409171402 cg.typeOf(un_op).fmt(pt),
171410171403 ops[0].tracking(cg),
171411171404 }),
......@@ -171422,6 +171415,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171422171415 },
171423171416 .error_set_has_value => |air_tag| {
171424171417 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
171418 assert(ty_op.ty != .anyerror_type); // das a constant
171425171419 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}) ++ .{try cg.tempInit(ty_op.ty.toType(), .none)};
171426171420 var res: [1]Temp = undefined;
171427171421 cg.select(&res, &.{.bool}, &ops, comptime &.{ .{
......@@ -171502,8 +171496,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171502171496 .{ ._, ._, .@"test", .src0d, .src0d, ._, ._ },
171503171497 } },
171504171498 } }) catch |err| switch (err) {
171505 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{
171506 @tagName(air_tag),
171499 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171500 air_tag,
171507171501 ty_op.ty.toType().fmt(pt),
171508171502 ops[0].tracking(cg),
171509171503 }),
......@@ -171575,8 +171569,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171575171569 }
171576171570 }
171577171571 },
171578 else => return cg.fail("failed to select {s} {f}", .{
171579 @tagName(air_tag),
171572 else => return cg.fail("failed to select {t} {f}", .{
171573 air_tag,
171580171574 agg_ty.fmt(pt),
171581171575 }),
171582171576 }
......@@ -173021,8 +173015,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173021173015 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
173022173016 } },
173023173017 } }) catch |err| switch (err) {
173024 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{
173025 @tagName(air_tag),
173018 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
173019 air_tag,
173026173020 cg.typeOf(bin_op.lhs).fmt(pt),
173027173021 ops[0].tracking(cg),
173028173022 ops[1].tracking(cg),
......@@ -173055,7 +173049,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173055173049 .{ .src = .{ .to_gpr, .none, .none } },
173056173050 },
173057173051 .extra_temps = .{
173058 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
173052 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173059173053 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173060173054 .unused,
173061173055 .unused,
......@@ -173079,7 +173073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173079173073 .{ .src = .{ .to_gpr, .none, .none } },
173080173074 },
173081173075 .extra_temps = .{
173082 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
173076 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173083173077 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173084173078 .unused,
173085173079 .unused,
......@@ -173103,7 +173097,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173103173097 .{ .src = .{ .to_gpr, .none, .none } },
173104173098 },
173105173099 .extra_temps = .{
173106 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },
173100 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173107173101 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173108173102 .unused,
173109173103 .unused,
......@@ -173122,8 +173116,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173122173116 .{ ._, ._, .cmp, .src0d, .lea(.tmp1d), ._, ._ },
173123173117 } },
173124173118 } }) catch |err| switch (err) {
173125 error.SelectFailed => return cg.fail("failed to select {s} {f}", .{
173126 @tagName(air_tag),
173119 error.SelectFailed => return cg.fail("failed to select {t} {f}", .{
173120 air_tag,
173127173121 ops[0].tracking(cg),
173128173122 }),
173129173123 else => |e| return e,
......@@ -173856,9 +173850,9 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173856173850 const pt = cg.pt;
173857173851 const zcu = pt.zcu;
173858173852 const ip = &zcu.intern_pool;
173859 switch (ip.indexToKey(lazy_sym.ty)) {
173853 switch (ip.indexToKey(lazy_sym.key)) {
173860173854 .enum_type => {
173861 const enum_ty: Type = .fromInterned(lazy_sym.ty);
173855 const enum_ty: Type = .fromInterned(lazy_sym.key);
173862173856 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
173863173857
173864173858 const ret_regs = abi.getCAbiIntReturnRegs(.auto)[0..2].*;
......@@ -173875,12 +173869,12 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173875173869 const data_lock = cg.register_manager.lockRegAssumeUnused(data_reg);
173876173870 defer cg.register_manager.unlockReg(data_lock);
173877173871 try cg.asmRegisterMemory(.{ ._, .lea }, data_reg.to64(), .{
173878 .base = .{ .lazy_sym = .{ .kind = .const_data, .ty = lazy_sym.ty } },
173872 .base = .{ .lazy_sym = .{ .kind = .const_data, .key = lazy_sym.key } },
173879173873 });
173880173874
173881173875 var data_off: i32 = 0;
173882173876 const reset_index = cg.next_temp_index;
173883 const tag_names = ip.loadEnumType(lazy_sym.ty).field_names;
173877 const tag_names = ip.loadEnumType(lazy_sym.key).field_names;
173884173878 for (0..tag_names.len) |tag_index| {
173885173879 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {
173886173880 else => unreachable,
......@@ -173919,7 +173913,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173919173913 try cg.asmOpOnly(.{ ._, .ret });
173920173914 },
173921173915 .error_set_type => |error_set_type| {
173922 const err_ty: Type = .fromInterned(lazy_sym.ty);
173916 const err_ty: Type = .fromInterned(lazy_sym.key);
173923173917 wip_mir_log.debug("{f}.@errorCast:", .{err_ty.fmt(pt)});
173924173918
173925173919 const ret_reg = abi.getCAbiIntReturnRegs(.auto)[0];
......@@ -173964,8 +173958,8 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173964173958 try cg.asmOpOnly(.{ ._, .ret });
173965173959 },
173966173960 else => return cg.fail(
173967 "TODO implement {s} for {f}",
173968 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },
173961 "TODO implement {t} for {f}",
173962 .{ lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt) },
173969173963 ),
173970173964 }
173971173965 try cg.resetTemps(@enumFromInt(0));
......@@ -175315,10 +175309,7 @@ fn genShiftBinOpMir(
175315175309 .mod = .{ .rm = .{
175316175310 .size = .fromSize(abi_size),
175317175311 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
175318 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{
175319 @tagName(lhs_mcv),
175320 @tagName(shift_mcv),
175321 }),
175312 return self.fail("TODO genShiftBinOpMir between {t} and {t}", .{ lhs_mcv, shift_mcv }),
175322175313 } },
175323175314 },
175324175315 .indirect => |reg_off| .{
......@@ -175349,10 +175340,7 @@ fn genShiftBinOpMir(
175349175340 },
175350175341 else => {},
175351175342 }
175352 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{
175353 @tagName(lhs_mcv),
175354 @tagName(shift_mcv),
175355 });
175343 return self.fail("TODO genShiftBinOpMir between {t} and {t}", .{ lhs_mcv, shift_mcv });
175356175344}
175357175345
175358175346fn genBinOpMir(
......@@ -175401,9 +175389,7 @@ fn genBinOpMir(
175401175389 .add => .{ ._, .adc },
175402175390 .sub, .cmp => .{ ._, .sbb },
175403175391 .@"or", .@"and", .xor => mir_tag,
175404 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{
175405 @tagName(mir_tag[1]),
175406 }),
175392 else => return self.fail("TODO genBinOpMir implement large ABI for {t}", .{mir_tag[1]}),
175407175393 },
175408175394 else => unreachable,
175409175395 };
......@@ -175652,9 +175638,7 @@ fn genBinOpMir(
175652175638 .add => .{ ._, .adc },
175653175639 .sub, .cmp => .{ ._, .sbb },
175654175640 .@"or", .@"and", .xor => mir_tag,
175655 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{
175656 @tagName(mir_tag[1]),
175657 }),
175641 else => return self.fail("TODO genBinOpMir implement large ABI for {t}", .{mir_tag[1]}),
175658175642 },
175659175643 };
175660175644 const dst_limb_mem: Memory = switch (dst_mcv) {
......@@ -176527,7 +176511,7 @@ fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
176527176511 }
176528176512 return self.fail("TODO implement condbr when condition is {f} with abi larger than 8 bytes", .{mcv});
176529176513 },
176530 else => return self.fail("TODO implement condbr when condition is {s}", .{@tagName(mcv)}),
176514 else => return self.fail("TODO implement condbr when condition is {t}", .{mcv}),
176531176515 }
176532176516}
176533176517
......@@ -177551,10 +177535,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177551177535 label_gop.value_ptr.target = @intCast(self.mir_instructions.len);
177552177536 } else continue;
177553177537 if (mnem_str[0] == '.') {
177554 if (prefix != .none) return self.fail("prefixed directive: '{s} {s}'", .{
177555 @tagName(prefix),
177556 mnem_str,
177557 });
177538 if (prefix != .none) return self.fail("prefixed directive: '{t} {s}'", .{ prefix, mnem_str });
177558177539 prefix = .directive;
177559177540 }
177560177541
......@@ -177871,8 +177852,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177871177852 inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
177872177853 max_mnem_len = @max(mnem.name.len, max_mnem_len);
177873177854 var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
177874 const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{
177875 @tagName(mnem_tag),
177855 const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{t}{c}", .{
177856 mnem_tag,
177876177857 @as(u8, switch (mnem_size.size) {
177877177858 .byte => 'b',
177878177859 .word => 'w',
......@@ -177908,9 +177889,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177908177889 ) orelse continue };
177909177890 } else {
177910177891 assert(prefix != .none); // no combination of fixes produced a known mnemonic
177911 return self.fail("invalid prefix for mnemonic: '{s} {s}'", .{
177912 @tagName(prefix), mnem_name,
177913 });
177892 return self.fail("invalid prefix for mnemonic: '{t} {s}'", .{ prefix, mnem_name });
177914177893 };
177915177894
177916177895 (if (prefix == .directive) switch (mnem_tag) {
......@@ -177969,12 +177948,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177969177948 .@".cfi_escape" => error.InvalidInstruction,
177970177949 else => unreachable,
177971177950 } else self.asmOps(mnem_fixed_tag, ops)) catch |err| switch (err) {
177972 error.InvalidInstruction => return self.fail("invalid instruction: '{s} {s} {s} {s} {s}'", .{
177973 mnem_str,
177974 @tagName(ops[0]),
177975 @tagName(ops[1]),
177976 @tagName(ops[2]),
177977 @tagName(ops[3]),
177951 error.InvalidInstruction => return self.fail("invalid instruction: '{s} {t} {t} {t} {t}'", .{
177952 mnem_str, ops[0], ops[1], ops[2], ops[3],
177978177953 }),
177979177954 else => |e| return e,
177980177955 };
......@@ -178537,9 +178512,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
178537178512 break :src_info .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };
178538178513 },
178539178514 .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref), opts),
178540 else => return self.fail("TODO implement genCopy for {s} of {f}", .{
178541 @tagName(src_mcv), ty.fmt(pt),
178542 }),
178515 else => return self.fail("TODO implement genCopy for {t} of {f}", .{ src_mcv, ty.fmt(pt) }),
178543178516 };
178544178517 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
178545178518
......@@ -179347,9 +179320,7 @@ fn genSetMem(
179347179320 opts,
179348179321 );
179349179322 },
179350 else => return self.fail("TODO implement genSetMem for {s} of {f}", .{
179351 @tagName(src_mcv), ty.fmt(pt),
179352 }),
179323 else => return self.fail("TODO implement genSetMem for {t} of {f}", .{ src_mcv, ty.fmt(pt) }),
179353179324 },
179354179325 .register_offset => |reg_off| {
179355179326 const src_reg = self.copyToTmpRegister(ty, src_mcv) catch |err| switch (err) {
......@@ -179705,7 +179676,7 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void {
179705179676 };
179706179677 switch (ptr_mem.mod) {
179707179678 .rm => {},
179708 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),
179679 .off => return self.fail("TODO airCmpxchg with {t}", .{ptr_mcv}),
179709179680 }
179710179681 const ptr_lock = switch (ptr_mem.base) {
179711179682 .none, .frame, .nav, .uav => null,
......@@ -179788,7 +179759,7 @@ fn atomicOp(
179788179759 };
179789179760 switch (ptr_mem.mod) {
179790179761 .rm => {},
179791 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),
179762 .off => return self.fail("TODO airCmpxchg with {t}", .{ptr_mcv}),
179792179763 }
179793179764 const mem_lock = switch (ptr_mem.base) {
179794179765 .none, .frame, .nav, .uav => null,
......@@ -179883,8 +179854,8 @@ fn atomicOp(
179883179854 else => null,
179884179855 },
179885179856 else => unreachable,
179886 }) orelse return self.fail("TODO implement atomicOp of {s} for {f}", .{
179887 @tagName(op), val_ty.fmt(pt),
179857 }) orelse return self.fail("TODO implement atomicOp of {t} for {f}", .{
179858 op, val_ty.fmt(pt),
179888179859 });
179889179860 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});
179890179861 switch (mir_tag[0]) {
......@@ -180952,7 +180923,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void {
180952180923 );
180953180924 break :result .{ .load_frame = .{ .index = dst_fi } };
180954180925 },
180955 else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}),
180926 else => |cc| return self.fail("{t} does not support var args", .{cc}),
180956180927 };
180957180928 return self.finishAir(inst, result, .{ .none, .none, .none });
180958180929}
......@@ -181139,7 +181110,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void {
181139181110 try self.convertFloatVarArg(inst, ty, promote_ty, promote_mcv);
181140181111 break :result promote_mcv;
181141181112 },
181142 else => |cc| return self.fail("{s} does not support var args", .{@tagName(cc)}),
181113 else => |cc| return self.fail("{t} does not support var args", .{cc}),
181143181114 };
181144181115 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
181145181116}
......@@ -181236,6 +181207,7 @@ fn lowerValue(cg: *CodeGen, val: Value) Allocator.Error!MCValue {
181236181207 .lea_nav => |nav| .{ .lea_nav = nav },
181237181208 .lea_uav => |uav| .{ .lea_uav = uav },
181238181209 .load_uav => |uav| .{ .load_uav = uav },
181210 .lea_lazy_sym => |lazy_sym| .{ .lea_lazy_sym = lazy_sym },
181239181211 };
181240181212}
181241181213
......@@ -181630,10 +181602,14 @@ fn resolveCallingConventionValues(
181630181602
181631181603fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
181632181604 @branchHint(.cold);
181633 const zcu = cg.pt.zcu;
181605 const pt = cg.pt;
181606 const zcu = pt.zcu;
181634181607 return switch (cg.owner) {
181635181608 .nav_index => |i| zcu.codegenFail(i, format, args),
181636 .lazy_sym => |s| zcu.codegenFailType(s.ty, format, args),
181609 .lazy_sym => |s| switch (zcu.intern_pool.typeOf(s.key)) {
181610 .type_type => zcu.codegenFailType(s.key, format, args),
181611 else => std.debug.panic("{f}: " ++ format, .{Value.fromInterned(s.key).fmtValue(pt)} ++ args),
181612 },
181637181613 };
181638181614}
181639181615
......@@ -187899,14 +187875,14 @@ const Select = struct {
187899187875 error.InvalidInstruction => {
187900187876 const fixes = @tagName(mir_tag[0]);
187901187877 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;
187902 return s.cg.fail("invalid instruction: '{s}{s}{s} {s} {s} {s} {s}'", .{
187878 return s.cg.fail("invalid instruction: '{s}{t}{s} {t} {t} {t} {t}'", .{
187903187879 fixes[0..fixes_blank],
187904 @tagName(mir_tag[1]),
187880 mir_tag[1],
187905187881 fixes[fixes_blank + 1 ..],
187906 @tagName(mir_ops[0]),
187907 @tagName(mir_ops[1]),
187908 @tagName(mir_ops[2]),
187909 @tagName(mir_ops[3]),
187882 mir_ops[0],
187883 mir_ops[1],
187884 mir_ops[2],
187885 mir_ops[3],
187910187886 });
187911187887 },
187912187888 else => |e| return e,
......@@ -187976,16 +187952,7 @@ const Select = struct {
187976187952 },
187977187953 .f_p => switch (mir_tag[1]) {
187978187954 .add, .com, .comi, .div, .divr, .mul, .st, .sub, .subr, .ucom, .ucomi => s.top +%= 1,
187979 else => {
187980 const fixes = @tagName(mir_tag[0]);
187981 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;
187982 std.debug.panic("{s}: {s}{s}{s}\n", .{
187983 @src().fn_name,
187984 fixes[0..fixes_blank],
187985 @tagName(mir_tag[1]),
187986 fixes[fixes_blank + 1 ..],
187987 });
187988 },
187955 else => unreachable,
187989187956 },
187990187957 .f_pp => switch (mir_tag[1]) {
187991187958 .com, .ucom => s.top +%= 2,
......@@ -189095,7 +189062,7 @@ const Select = struct {
189095189062 const ty = if (lazy_symbol_spec.ref == .none) spec.type else lazy_symbol_spec.ref.typeOf(s);
189096189063 return .{ try cg.tempInit(.usize, .{ .lea_lazy_sym = .{
189097189064 .kind = lazy_symbol_spec.kind,
189098 .ty = switch (ip.indexToKey(ty.toIntern())) {
189065 .key = switch (ip.indexToKey(ty.toIntern())) {
189099189066 .inferred_error_set_type => |func_index| switch (ip.funcIesResolvedUnordered(func_index)) {
189100189067 .none => unreachable,
189101189068 else => |ty_index| ty_index,
src/codegen/x86_64/Emit.zig+2-2
......@@ -163,8 +163,8 @@ pub fn emitMir(emit: *Emit) Error!void {
163163 else if (emit.bin_file.cast(.macho)) |macho_file|
164164 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
165165 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
166 else if (emit.bin_file.cast(.coff2)) |elf|
167 @intFromEnum(try elf.lazySymbol(lazy_sym))
166 else if (emit.bin_file.cast(.coff2)) |coff|
167 @intFromEnum(try coff.lazySymbol(lazy_sym))
168168 else
169169 return emit.fail("lazy symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
170170 .is_extern = false,
src/codegen/x86_64/Mir.zig+28-7
......@@ -1867,7 +1867,7 @@ pub const Memory = struct {
18671867 size: bits.Memory.Size,
18681868 index: Register,
18691869 scale: bits.Memory.Scale,
1870 _: u13 = undefined,
1870 unused: u13 = 0,
18711871 };
18721872
18731873 pub fn encode(mem: bits.Memory) Memory {
......@@ -1895,7 +1895,7 @@ pub const Memory = struct {
18951895 .rip_inst => |inst_index| inst_index,
18961896 .nav => |nav| @intFromEnum(nav),
18971897 .uav => |uav| @intFromEnum(uav.val),
1898 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.ty),
1898 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.key),
18991899 .extern_func => |extern_func| @intFromEnum(extern_func),
19001900 },
19011901 .off = switch (mem.mod) {
......@@ -1933,7 +1933,10 @@ pub const Memory = struct {
19331933 .rip_inst => .{ .rip_inst = mem.base },
19341934 .nav => .{ .nav = @enumFromInt(mem.base) },
19351935 .uav => .{ .uav = .{ .val = @enumFromInt(mem.base), .orig_ty = @enumFromInt(mem.extra) } },
1936 .lazy_sym => .{ .lazy_sym = .{ .kind = @enumFromInt(mem.extra), .ty = @enumFromInt(mem.base) } },
1936 .lazy_sym => .{ .lazy_sym = .{
1937 .kind = @enumFromInt(mem.extra),
1938 .key = @enumFromInt(mem.base),
1939 } },
19371940 .extern_func => .{ .extern_func = @enumFromInt(mem.base) },
19381941 },
19391942 .scale_index = switch (mem.info.index) {
......@@ -2061,10 +2064,28 @@ pub fn emitLazy(
20612064 .table_relocs = .empty,
20622065 };
20632066 defer e.deinit();
2064 e.emitMir() catch |err| switch (err) {
2065 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, e.lower.err_msg.?),
2066 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2067 else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),
2067 e.emitMir() catch |err| switch (zcu.intern_pool.typeOf(lazy_sym.key)) {
2068 .type_type => switch (err) {
2069 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.key, e.lower.err_msg.?),
2070 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(
2071 lazy_sym.key,
2072 "emit MIR failed: {t} (Zig compiler bug)",
2073 .{err},
2074 ),
2075 else => return zcu.codegenFailType(lazy_sym.key, "emit MIR failed: {t}", .{err}),
2076 },
2077 else => switch (err) {
2078 error.LowerFail, error.EmitFail => std.debug.panic("{f}: {s}", .{
2079 @import("../../Value.zig").fromInterned(lazy_sym.key).fmtValue(pt), e.lower.err_msg.?.msg,
2080 }),
2081 error.InvalidInstruction, error.CannotEncode => std.debug.panic(
2082 "{f}: emit MIR failed: {t} (Zig compiler bug)",
2083 .{ @import("../../Value.zig").fromInterned(lazy_sym.key).fmtValue(pt), err },
2084 ),
2085 else => std.debug.panic("{f}: emit MIR failed: {t}", .{
2086 @import("../../Value.zig").fromInterned(lazy_sym.key).fmtValue(pt), err,
2087 }),
2088 },
20682089 };
20692090}
20702091
src/codegen/x86_64/encoder.zig+10-16
......@@ -238,7 +238,7 @@ pub const Instruction = struct {
238238 try w.print("{f} ", .{sib.ptr_size});
239239
240240 if (mem.isSegmentRegister()) {
241 return w.print("{s}:0x{x}", .{ @tagName(sib.base.reg), sib.disp });
241 return w.print("{t}:0x{x}", .{ sib.base.reg, sib.disp });
242242 }
243243
244244 try w.writeByte('[');
......@@ -246,21 +246,18 @@ pub const Instruction = struct {
246246 var any = true;
247247 switch (sib.base) {
248248 .none => any = false,
249 .reg => |reg| try w.print("{s}", .{@tagName(reg)}),
249 .reg => |reg| try w.print("{t}", .{reg}),
250250 .frame => |frame_index| try w.print("{f}", .{frame_index}),
251251 .table => try w.print("Table", .{}),
252252 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
253 .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),
254 .uav => |uav| try w.print("Uav({d})", .{@intFromEnum(uav.val)}),
255 .lazy_sym => |lazy_sym| try w.print("LazySym({s}, {d})", .{
256 @tagName(lazy_sym.kind),
257 @intFromEnum(lazy_sym.ty),
258 }),
259 .extern_func => |extern_func| try w.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
253 .nav => |nav| try w.print("Nav({d})", .{nav}),
254 .uav => |uav| try w.print("Uav({d})", .{uav.val}),
255 .lazy_sym => |lazy_sym| try w.print("LazySym({t}, {d})", .{ lazy_sym.kind, lazy_sym.key }),
256 .extern_func => |extern_func| try w.print("ExternFunc({d})", .{extern_func}),
260257 }
261258 if (mem.scaleIndex()) |si| {
262259 if (any) try w.writeAll(" + ");
263 try w.print("{s} * {d}", .{ @tagName(si.index), si.scale });
260 try w.print("{t} * {d}", .{ si.index, si.scale });
264261 any = true;
265262 }
266263 if (sib.disp != 0 or !any) {
......@@ -274,10 +271,7 @@ pub const Instruction = struct {
274271
275272 try w.writeByte(']');
276273 },
277 .moffs => |moffs| try w.print("{s}:0x{x}", .{
278 @tagName(moffs.seg),
279 moffs.offset,
280 }),
274 .moffs => |moffs| try w.print("{t}:0x{x}", .{ moffs.seg, moffs.offset }),
281275 },
282276 .imm => |imm| if (enc_op.isSigned()) {
283277 const imms = imm.asSigned(enc_op.immBitSize());
......@@ -344,9 +338,9 @@ pub const Instruction = struct {
344338 pub fn format(inst: Instruction, w: *Writer) Writer.Error!void {
345339 switch (inst.prefix) {
346340 .none, .directive => {},
347 else => try w.print("{s} ", .{@tagName(inst.prefix)}),
341 else => try w.print("{t} ", .{inst.prefix}),
348342 }
349 try w.print("{s}", .{@tagName(inst.encoding.mnemonic)});
343 try w.print("{t}", .{inst.encoding.mnemonic});
350344 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {
351345 if (op == .none) break;
352346 if (i > 0) try w.writeByte(',');
src/link.zig+18-4
......@@ -1019,7 +1019,7 @@ pub const File = struct {
10191019 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
10201020 /// the block/atom.
10211021 /// Never called when LLVM is codegenning the ZCU.
1022 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {
1022 pub fn getNavVAddr(base: *File, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {
10231023 assert(base.comp.zcu.?.llvm_object == null);
10241024 switch (base.tag) {
10251025 .lld => unreachable,
......@@ -1029,7 +1029,7 @@ pub const File = struct {
10291029 .plan9 => unreachable,
10301030 inline else => |tag| {
10311031 dev.check(tag.devFeature());
1032 return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info);
1032 return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(nav_index, reloc_info);
10331033 },
10341034 }
10351035 }
......@@ -1290,11 +1290,25 @@ pub const File = struct {
12901290 };
12911291
12921292 pub const LazySymbol = struct {
1293 pub const Kind = enum { code, const_data };
1293 pub const Kind = enum(u2) { code, const_data, deferred_const_data };
12941294
12951295 kind: Kind,
1296 ty: InternPool.Index,
1296 key: InternPool.Index,
12971297 };
1298 pub fn getLazySymbolVAddr(base: *File, pt: Zcu.PerThread, lazy_symbol: LazySymbol, reloc_info: RelocInfo) !u64 {
1299 assert(base.comp.zcu.?.llvm_object == null);
1300 switch (base.tag) {
1301 .lld => unreachable,
1302 .c => unreachable,
1303 .spirv => unreachable,
1304 .wasm => unreachable,
1305 .plan9 => unreachable,
1306 inline else => |tag| {
1307 dev.check(tag.devFeature());
1308 return @as(*tag.Type(), @fieldParentPtr("base", base)).getLazySymbolVAddr(pt, lazy_symbol, reloc_info);
1309 },
1310 }
1311 }
12981312
12991313 pub fn determinePermissions(
13001314 output_mode: std.builtin.OutputMode,
src/link/C.zig+50-3
......@@ -134,6 +134,7 @@ const RenderedDecl = struct {
134134 code: String,
135135 ctype_deps: CTypeDependencies,
136136 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
137 need_restricted: std.array_hash_map.Auto(InternPool.Index, void),
137138 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
138139 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
139140 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
......@@ -143,6 +144,7 @@ const RenderedDecl = struct {
143144 .code = .empty,
144145 .ctype_deps = .empty,
145146 .need_uavs = .empty,
147 .need_restricted = .empty,
146148 .need_tag_name_funcs = .empty,
147149 .need_never_tail_funcs = .empty,
148150 .need_never_inline_funcs = .empty,
......@@ -150,6 +152,7 @@ const RenderedDecl = struct {
150152
151153 fn deinit(rd: *RenderedDecl, gpa: Allocator) void {
152154 rd.need_uavs.deinit(gpa);
155 rd.need_restricted.deinit(gpa);
153156 rd.need_tag_name_funcs.deinit(gpa);
154157 rd.need_never_tail_funcs.deinit(gpa);
155158 rd.need_never_inline_funcs.deinit(gpa);
......@@ -162,6 +165,7 @@ const RenderedDecl = struct {
162165 fn clearRetainingCapacity(rd: *RenderedDecl) void {
163166 rd.fwd_decl = undefined;
164167 rd.code = undefined;
168 rd.need_restricted.clearRetainingCapacity();
165169 rd.need_uavs.clearRetainingCapacity();
166170 rd.need_tag_name_funcs.clearRetainingCapacity();
167171 rd.need_never_tail_funcs.clearRetainingCapacity();
......@@ -501,6 +505,7 @@ pub fn updateFunc(
501505 .code = try c.addString(&.{ mir.c.code_header, mir.c.code }),
502506 .ctype_deps = try c.addCTypeDependencies(pt, &mir.c.ctype_deps),
503507 .need_uavs = mir.c.need_uavs.move(),
508 .need_restricted = mir.c.need_restricted.move(),
504509 .need_tag_name_funcs = mir.c.need_tag_name_funcs.move(),
505510 .need_never_tail_funcs = mir.c.need_never_tail_funcs.move(),
506511 .need_never_inline_funcs = mir.c.need_never_inline_funcs.move(),
......@@ -576,11 +581,13 @@ pub fn updateNav(
576581 .expected_block = null,
577582 .ctype_deps = .empty,
578583 .uavs = rendered_decl.need_uavs.move(),
584 .need_restricted = .empty,
579585 };
580586
581587 defer {
582588 rendered_decl.need_uavs = dg.uavs.move();
583589 dg.ctype_deps.deinit(gpa);
590 dg.need_restricted.deinit(gpa);
584591 }
585592
586593 rendered_decl.fwd_decl = fwd_decl: {
......@@ -618,6 +625,7 @@ pub fn updateNav(
618625 };
619626
620627 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
628 rendered_decl.need_restricted = dg.need_restricted.move();
621629 }
622630
623631 const old_uavs_len = c.uavs.count();
......@@ -667,10 +675,12 @@ fn updateUav(
667675 .expected_block = null,
668676 .ctype_deps = .empty,
669677 .uavs = .empty,
678 .need_restricted = .empty,
670679 };
671680 defer {
672681 rendered_decl.need_uavs = dg.uavs.move();
673682 dg.ctype_deps.deinit(gpa);
683 dg.need_restricted.deinit(gpa);
674684 }
675685
676686 rendered_decl.fwd_decl = fwd_decl: {
......@@ -716,6 +726,7 @@ fn updateUav(
716726 };
717727
718728 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
729 rendered_decl.need_restricted = dg.need_restricted.move();
719730}
720731
721732pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) error{}!void {
......@@ -795,6 +806,10 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
795806 var need_aligned_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64) = .empty;
796807 defer need_aligned_types.deinit(gpa);
797808
809 var need_restricted: std.array_hash_map.Auto(InternPool.Index, std.array_hash_map.Auto(InternPool.Index, void)) = .empty;
810 defer need_restricted.deinit(gpa);
811 defer for (need_restricted.values()) |*values| values.deinit(gpa);
812
798813 var need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;
799814 defer need_tag_name_funcs.deinit(gpa);
800815
......@@ -816,7 +831,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
816831 if (!gop.found_existing) gop.value_ptr.* = .none;
817832 }
818833
819 // For every referenced NAV, some UAVs, C types, and lazy functions may be referenced.
834 // For every referenced NAV, some UAVs, restricted types, C types, and lazy functions may be referenced.
820835 for (need_navs.keys()) |nav| {
821836 const rendered = c.navs.getPtr(nav).?;
822837 try mergeNeededCTypes(
......@@ -827,6 +842,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
827842 &rendered.ctype_deps,
828843 );
829844 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
845 try mergeNeededRestricted(zcu, &need_restricted, &rendered.need_restricted);
830846
831847 try need_tag_name_funcs.ensureUnusedCapacity(gpa, rendered.need_tag_name_funcs.count());
832848 for (rendered.need_tag_name_funcs.keys()) |enum_type| {
......@@ -844,7 +860,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
844860 }
845861 }
846862
847 // UAVs may reference other UAVs or C types.
863 // UAVs may reference other UAVs, restricted types, or C types.
848864 {
849865 var index: usize = 0;
850866 while (need_uavs.count() > index) : (index += 1) {
......@@ -858,6 +874,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
858874 &rendered.ctype_deps,
859875 );
860876 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
877 try mergeNeededRestricted(zcu, &need_restricted, &rendered.need_restricted);
861878 }
862879 }
863880
......@@ -962,7 +979,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
962979 // * NAV exports
963980 // * UAV forward declarations
964981 // * NAV forward declarations
965 // * Lazy declarations (error names; @tagName functions; never_tail/never_inline wrappers)
982 // * Lazy declarations (restricted decls; error names; @tagName functions; never_tail/never_inline wrappers)
966983 // * UAV definitions
967984 // * NAV definitions
968985 //
......@@ -1115,11 +1132,18 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
11151132 .error_msg = null,
11161133 .ctype_deps = .empty,
11171134 .uavs = .empty,
1135 .need_restricted = .empty,
11181136 };
11191137 defer {
11201138 assert(lazy_dg.uavs.count() == 0);
11211139 lazy_dg.ctype_deps.deinit(gpa);
1140 assert(lazy_dg.need_restricted.count() == 0);
11221141 }
1142 codegen.genRestricted(&lazy_dg, &need_restricted, &lazy_decls_aw.writer) catch |err| switch (err) {
1143 error.WriteFailed => return error.OutOfMemory,
1144 error.OutOfMemory => |e| return e,
1145 error.AnalysisFail => unreachable,
1146 };
11231147 const slice_const_u8_sentinel_0_cty: codegen.CType = try .lower(
11241148 .slice_const_u8_sentinel_0,
11251149 &lazy_dg.ctype_deps,
......@@ -1259,10 +1283,12 @@ pub fn updateExports(
12591283 .error_msg = null,
12601284 .ctype_deps = .empty,
12611285 .uavs = .empty,
1286 .need_restricted = .empty,
12621287 };
12631288 defer {
12641289 assert(dg.uavs.count() == 0);
12651290 dg.ctype_deps.deinit(gpa);
1291 assert(dg.need_restricted.count() == 0);
12661292 }
12671293
12681294 const code: String = code: {
......@@ -1347,6 +1373,27 @@ fn mergeNeededUavs(
13471373 }
13481374}
13491375
1376fn mergeNeededRestricted(
1377 zcu: *const Zcu,
1378 global: *std.array_hash_map.Auto(InternPool.Index, std.array_hash_map.Auto(InternPool.Index, void)),
1379 new: *const std.array_hash_map.Auto(InternPool.Index, void),
1380) Allocator.Error!void {
1381 const gpa = zcu.comp.gpa;
1382 const ip = &zcu.intern_pool;
1383
1384 try global.ensureUnusedCapacity(gpa, new.count());
1385 for (new.keys()) |restricted_key| {
1386 const restricted_ty = switch (ip.indexToKey(restricted_key)) {
1387 else => unreachable,
1388 .restricted_ptr_type => restricted_key,
1389 .ptr => |ptr| ptr.ty,
1390 };
1391 const gop = global.getOrPutAssumeCapacity(restricted_ty);
1392 if (!gop.found_existing) gop.value_ptr.* = .empty;
1393 if (restricted_ty != restricted_key) try gop.value_ptr.put(gpa, restricted_key, {});
1394 }
1395}
1396
13501397fn addCTypeDependencies(
13511398 c: *C,
13521399 pt: Zcu.PerThread,
src/link/Coff.zig+77-36
......@@ -138,6 +138,7 @@ pub const Node = union(enum) {
138138 uav: UavMapIndex,
139139 lazy_code: LazyMapRef.Index(.code),
140140 lazy_const_data: LazyMapRef.Index(.const_data),
141 lazy_deferred_const_data: LazyMapRef.Index(.deferred_const_data),
141142
142143 pub const PseudoSectionMapIndex = enum(u32) {
143144 _,
......@@ -222,7 +223,7 @@ pub const Node = union(enum) {
222223 }
223224
224225 pub fn lazySymbol(lmr: LazyMapRef, coff: *const Coff) link.File.LazySymbol {
225 return .{ .kind = lmr.kind, .ty = coff.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
226 return .{ .kind = lmr.kind, .key = coff.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
226227 }
227228
228229 pub fn symbol(lmr: LazyMapRef, coff: *const Coff) Symbol.Index {
......@@ -1053,6 +1054,7 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 {
10531054 .uav,
10541055 .lazy_code,
10551056 .lazy_const_data,
1057 .lazy_deferred_const_data,
10561058 => |mi| mi.symbol(coff),
10571059 };
10581060 break :parent_rva parent_si.get(coff).rva;
......@@ -1259,7 +1261,8 @@ fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.Na
12591261 if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity();
12601262 return @enumFromInt(sym_gop.index);
12611263}
1262pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
1264pub fn navSymbol(coff: *Coff, nav_index: InternPool.Nav.Index) !Symbol.Index {
1265 const zcu = coff.base.comp.zcu.?;
12631266 const ip = &zcu.intern_pool;
12641267 const nav = ip.getNav(nav_index);
12651268 if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(
......@@ -1282,24 +1285,38 @@ pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index {
12821285 return umi.symbol(coff);
12831286}
12841287
1285pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index {
1286 const gpa = coff.base.comp.gpa;
1287 try coff.symbol_table.ensureUnusedCapacity(gpa, 1);
1288 const sym_gop = try coff.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty);
1289 if (!sym_gop.found_existing) {
1290 sym_gop.value_ptr.* = try coff.initSymbolAssumeCapacity();
1291 coff.synth_prog_node.increaseEstimatedTotalItems(1);
1292 }
1293 return sym_gop.value_ptr.*;
1288fn lazySymbolIfExists(coff: *Coff, lazy_sym: link.File.LazySymbol) ?Symbol.Index {
1289 return coff.lazy.getPtr(lazy_sym.kind).map.get(lazy_sym.key);
1290}
1291fn lazySymbolAssumeCapacity(coff: *Coff, lazy_sym: link.File.LazySymbol) !struct { Symbol.Index, usize } {
1292 const gop = try coff.lazy.getPtr(lazy_sym.kind).map.getOrPut(coff.base.comp.gpa, lazy_sym.key);
1293 if (gop.found_existing) return .{ gop.value_ptr.*, gop.index };
1294 const si = try coff.initSymbolAssumeCapacity();
1295 gop.value_ptr.* = si;
1296 coff.synth_prog_node.increaseEstimatedTotalItems(1);
1297 return .{ si, gop.index };
1298}
1299pub fn lazySymbol(coff: *Coff, lazy_sym: link.File.LazySymbol) !Symbol.Index {
1300 // optimize for future lookups, at the cost of an extra initial key lookup
1301 if (coff.lazySymbolIfExists(lazy_sym)) |si| return si;
1302 const comp = coff.base.comp;
1303 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, comp.zcu.?);
1304 try coff.symbol_table.ensureUnusedCapacity(
1305 comp.gpa,
1306 @as(usize, @intFromBool(structure.parent != null)) + 1,
1307 );
1308 if (structure.parent) |parent_lazy_sym| _ = try coff.lazySymbolAssumeCapacity(parent_lazy_sym);
1309 if (structure.modify) |modification| _ = try coff.lazySymbolAssumeCapacity(modification.lazy_sym);
1310 const si, _ = try coff.lazySymbolAssumeCapacity(lazy_sym);
1311 return si;
12941312}
12951313
12961314pub fn getNavVAddr(
12971315 coff: *Coff,
1298 pt: Zcu.PerThread,
12991316 nav: InternPool.Nav.Index,
13001317 reloc_info: link.File.RelocInfo,
13011318) !u64 {
1302 return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav));
1319 return coff.getVAddr(reloc_info, try coff.navSymbol(nav));
13031320}
13041321
13051322pub fn getUavVAddr(
......@@ -1310,6 +1327,15 @@ pub fn getUavVAddr(
13101327 return coff.getVAddr(reloc_info, try coff.uavSymbol(uav));
13111328}
13121329
1330pub fn getLazySymbolVAddr(
1331 coff: *Coff,
1332 _: Zcu.PerThread,
1333 lazy_sym: link.File.LazySymbol,
1334 reloc_info: link.File.RelocInfo,
1335) !u64 {
1336 return coff.getVAddr(reloc_info, try coff.lazySymbol(lazy_sym));
1337}
1338
13131339pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {
13141340 try coff.addReloc(
13151341 @enumFromInt(reloc_info.parent.atom_index),
......@@ -1713,7 +1739,7 @@ fn updateFuncInner(
17131739
17141740pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
17151741 coff.flushLazy(pt, .{
1716 .kind = .const_data,
1742 .kind = .deferred_const_data,
17171743 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
17181744 }) catch |err| switch (err) {
17191745 error.OutOfMemory => |e| return e,
......@@ -1798,13 +1824,13 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
17981824 lazy.value.pending_index += 1;
17991825 const kind = switch (lmr.kind) {
18001826 .code => "code",
1801 .const_data => "data",
1827 .const_data, .deferred_const_data => "data",
18021828 };
18031829 var name: [std.Progress.Node.max_name_len]u8 = undefined;
18041830 const sub_prog_node = coff.synth_prog_node.start(
18051831 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{
18061832 kind,
1807 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
1833 Value.fromInterned(lmr.lazySymbol(coff).key).fmtValue(pt),
18081834 }) catch &name,
18091835 0,
18101836 );
......@@ -2092,24 +2118,36 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
20922118 const zcu = pt.zcu;
20932119 const gpa = zcu.gpa;
20942120
2095 const lazy = lmr.lazySymbol(coff);
2121 const lazy_sym = lmr.lazySymbol(coff);
20962122 const si = lmr.symbol(coff);
2123 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, zcu);
20972124 const ni = ni: {
20982125 const sym = si.get(coff);
20992126 switch (sym.ni) {
21002127 .none => {
21012128 try coff.nodes.ensureUnusedCapacity(gpa, 1);
2102 const sec_si: Symbol.Index = switch (lazy.kind) {
2129 const attrs = codegen.getLazySymbolInfo(.attributes, lazy_sym, zcu);
2130 const parent_si: Symbol.Index = if (structure.parent) |parent_lazy_sym|
2131 coff.lazySymbolIfExists(parent_lazy_sym).?
2132 else switch (lazy_sym.kind) {
21032133 .code => .text,
2104 .const_data => .rdata,
2134 .const_data, .deferred_const_data => .rdata,
21052135 };
2106 const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ .moved = true });
2107 coff.nodes.appendAssumeCapacity(switch (lazy.kind) {
2136 const addChildNode =
2137 if (attrs.header) &MappedFile.addOnlyChildNode else &MappedFile.addLastChildNode;
2138 const ni = try addChildNode(&coff.mf, coff.base.comp.gpa, parent_si.node(coff), .{
2139 .size = attrs.size orelse 0,
2140 .alignment = attrs.required_alignment.toStdMem(),
2141 .fixed = attrs.header,
2142 .moved = true,
2143 });
2144 coff.nodes.appendAssumeCapacity(switch (lazy_sym.kind) {
21082145 .code => .{ .lazy_code = @enumFromInt(lmr.index) },
21092146 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },
2147 .deferred_const_data => .{ .lazy_deferred_const_data = @enumFromInt(lmr.index) },
21102148 });
21112149 sym.ni = ni;
2112 sym.section_number = sec_si.get(coff).section_number;
2150 sym.section_number = parent_si.get(coff).section_number;
21132151 },
21142152 else => si.deleteLocationRelocs(coff),
21152153 }
......@@ -2118,22 +2156,25 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
21182156 break :ni sym.ni;
21192157 };
21202158
2121 var required_alignment: InternPool.Alignment = .none;
21222159 var nw: MappedFile.Node.Writer = undefined;
21232160 ni.writer(&coff.mf, gpa, &nw);
21242161 defer nw.deinit();
21252162 try codegen.generateLazySymbol(
21262163 &coff.base,
21272164 pt,
2128 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
2129 lazy,
2130 &required_alignment,
2165 Type.fromInterned(lazy_sym.key).srcLocOrNull(pt.zcu) orelse .unneeded,
2166 lazy_sym,
21312167 &nw.interface,
21322168 .none,
21332169 .{ .atom_index = @intFromEnum(si) },
21342170 );
21352171 si.get(coff).size = @intCast(nw.interface.end);
21362172 si.applyLocationRelocs(coff);
2173
2174 if (structure.modify) |modification| modification.operation.apply(
2175 coff.lazySymbolIfExists(modification.lazy_sym).?.node(coff).slice(&coff.mf),
2176 coff.targetEndian(),
2177 );
21372178}
21382179
21392180fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {
......@@ -2219,6 +2260,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {
22192260 .uav,
22202261 .lazy_code,
22212262 .lazy_const_data,
2263 .lazy_deferred_const_data,
22222264 => |mi| mi.symbol(coff).flushMoved(coff),
22232265 }
22242266 try ni.childrenMoved(coff.base.comp.gpa, &coff.mf);
......@@ -2269,7 +2311,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void {
22692311 inline .pseudo_section,
22702312 .object_section,
22712313 => |smi| smi.symbol(coff).get(coff).size = @intCast(size),
2272 .global, .nav, .uav, .lazy_code, .lazy_const_data => {},
2314 .global, .nav, .uav, .lazy_code, .lazy_const_data, .lazy_deferred_const_data => {},
22732315 }
22742316}
22752317fn virtualSlide(coff: *Coff, start_section_index: usize, start_rva: u32) !void {
......@@ -2322,7 +2364,7 @@ fn updateExportsInner(
23222364 }
23232365 try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len);
23242366 const exported_si: Symbol.Index = switch (exported) {
2325 .nav => |nav| try coff.navSymbol(zcu, nav),
2367 .nav => |nav| try coff.navSymbol(nav),
23262368 .uav => |uav| @enumFromInt(switch (try coff.lowerUav(
23272369 pt,
23282370 uav,
......@@ -2365,7 +2407,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
23652407 _ = name;
23662408}
23672409
2368pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void {
2410pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) !void {
23692411 const comp = coff.base.comp;
23702412 const io = comp.io;
23712413 var buffer: [512]u8 = undefined;
......@@ -2373,7 +2415,7 @@ pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void {
23732415 defer io.unlockStderr();
23742416 const w = &stderr.file_writer.interface;
23752417 coff.printNode(tid, w, .root, 0) catch |err| switch (err) {
2376 error.WriteFailed => return stderr.err.?,
2418 error.WriteFailed => return stderr.file_writer.err.?,
23772419 };
23782420}
23792421
......@@ -2412,7 +2454,7 @@ pub fn printNode(
24122454 const ip = &zcu.intern_pool;
24132455 const nav = ip.getNav(nmi.navIndex(coff));
24142456 try w.print("({f}, {f})", .{
2415 Type.fromInterned(nav.typeOf(ip)).fmt(.{ .zcu = zcu, .tid = tid }),
2457 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
24162458 nav.fqn.fmt(ip),
24172459 });
24182460 },
......@@ -2425,10 +2467,9 @@ pub fn printNode(
24252467 });
24262468 },
24272469 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{
2428 Type.fromInterned(lmi.lazySymbol(coff).ty).fmt(.{
2429 .zcu = coff.base.comp.zcu.?,
2430 .tid = tid,
2431 }),
2470 Value.fromInterned(lmi.lazySymbol(coff).key).fmtValue(
2471 .{ .zcu = coff.base.comp.zcu.?, .tid = tid },
2472 ),
24322473 }),
24332474 }
24342475 {
......@@ -2458,7 +2499,7 @@ pub fn printNode(
24582499 const line_len = 0x10;
24592500 var line_it = std.mem.window(
24602501 u8,
2461 coff.mf.contents[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)],
2502 coff.mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)],
24622503 line_len,
24632504 line_len,
24642505 );
src/link/Dwarf.zig+2-2
......@@ -3631,11 +3631,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
36313631 },
36323632 },
36333633 .restricted_ptr_type => |restricted_ptr_type| switch (Type.restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu)) {
3634 .double_pointer => continue :key .{ .ptr_type = .{
3634 .indirect => continue :key .{ .ptr_type = .{
36353635 .child = restricted_ptr_type.unrestricted_ptr_type,
36363636 .flags = .{ .is_const = true },
36373637 } },
3638 .single_pointer => continue :key .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type },
3638 .direct => continue :key .{ .ptr_type = ip.indexToKey(restricted_ptr_type.unrestricted_ptr_type).ptr_type },
36393639 },
36403640 .array_type => |array_type| {
36413641 const array_child_type: Type = .fromInterned(array_type.child);
src/link/Elf.zig+6-2
......@@ -467,8 +467,8 @@ pub fn deinit(self: *Elf) void {
467467 self.dump_argv_list.deinit(gpa);
468468}
469469
470pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
471 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);
470pub fn getNavVAddr(self: *Elf, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
471 return self.zigObjectPtr().?.getNavVAddr(self, nav_index, reloc_info);
472472}
473473
474474pub fn lowerUav(
......@@ -485,6 +485,10 @@ pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.Relo
485485 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
486486}
487487
488pub fn getLazySymbolVAddr(self: *Elf, pt: Zcu.PerThread, lazy_sym: link.File.LazySymbol, reloc_info: link.File.RelocInfo) !u64 {
489 return self.zigObjectPtr().?.getLazySymbolVAddr(self, pt, lazy_sym, reloc_info);
490}
491
488492/// Returns end pos of collision, if any.
489493fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
490494 const comp = self.base.comp;
src/link/Elf/ZigObject.zig+87-53
......@@ -31,16 +31,17 @@ dwarf: ?Dwarf = null,
3131
3232/// Table of tracked LazySymbols.
3333lazy_syms: LazySymbolTable = .{},
34/// Table of tracked LazySymbols that are deferred until flush.
35deferred_lazy_syms: LazySymbolTable = .{},
3436
3537/// Table of tracked `Nav`s.
3638navs: NavTable = .{},
39/// Table of tracked `Uav`s.
40uavs: UavTable = .{},
3741
3842/// TLS variables indexed by Atom.Index.
3943tls_variables: TlsTable = .{},
4044
41/// Table of tracked `Uav`s.
42uavs: UavTable = .{},
43
4445debug_info_section_dirty: bool = false,
4546debug_abbrev_section_dirty: bool = false,
4647debug_aranges_section_dirty: bool = false,
......@@ -246,13 +247,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
246247 }
247248 self.relocs.deinit(allocator);
248249
250 self.lazy_syms.deinit(allocator);
251 self.deferred_lazy_syms.deinit(allocator);
252
249253 for (self.navs.values()) |*meta| {
250254 meta.exports.deinit(allocator);
251255 }
252256 self.navs.deinit(allocator);
253257
254 self.lazy_syms.deinit(allocator);
255
256258 for (self.uavs.values()) |*meta| {
257259 meta.exports.deinit(allocator);
258260 }
......@@ -266,30 +268,22 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
266268
267269pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
268270 // Handle any lazy symbols that were emitted by incremental compilation.
269 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
271 {
270272 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);
271273 defer pt.deactivate();
272274
273 // Most lazy symbols can be updated on first use, but
274 // anyerror needs to wait for everything to be flushed.
275 if (metadata.text_state != .unused) self.updateLazySymbol(
276 elf_file,
277 pt,
278 .{ .kind = .code, .ty = .anyerror_type },
279 metadata.text_symbol_index,
280 ) catch |err| switch (err) {
281 error.CodegenFail => return error.LinkFailure,
282 else => |e| return e,
283 };
284 if (metadata.rodata_state != .unused) self.updateLazySymbol(
285 elf_file,
286 pt,
287 .{ .kind = .const_data, .ty = .anyerror_type },
288 metadata.rodata_symbol_index,
289 ) catch |err| switch (err) {
290 error.CodegenFail => return error.LinkFailure,
291 else => |e| return e,
292 };
275 for (self.deferred_lazy_syms.values(), self.deferred_lazy_syms.keys()) |*metadata, key| {
276 assert(metadata.text_state == .unused);
277 if (metadata.rodata_state != .unused) self.updateLazySymbol(
278 elf_file,
279 pt,
280 .{ .kind = .deferred_const_data, .key = key },
281 metadata.rodata_symbol_index,
282 ) catch |err| switch (err) {
283 error.CodegenFail => return error.LinkFailure,
284 else => |e| return e,
285 };
286 }
293287 }
294288 for (self.lazy_syms.values()) |*metadata| {
295289 if (metadata.text_state != .unused) metadata.text_state = .flushed;
......@@ -923,11 +917,10 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
923917pub fn getNavVAddr(
924918 self: *ZigObject,
925919 elf_file: *Elf,
926 pt: Zcu.PerThread,
927920 nav_index: InternPool.Nav.Index,
928921 reloc_info: link.File.RelocInfo,
929922) !u64 {
930 const zcu = pt.zcu;
923 const zcu = elf_file.base.comp.zcu.?;
931924 const ip = &zcu.intern_pool;
932925 const nav = ip.getNav(nav_index);
933926 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
......@@ -993,6 +986,44 @@ pub fn getUavVAddr(
993986 return @intCast(vaddr);
994987}
995988
989pub fn getLazySymbolVAddr(
990 self: *ZigObject,
991 elf_file: *Elf,
992 pt: Zcu.PerThread,
993 lazy_sym: link.File.LazySymbol,
994 reloc_info: link.File.RelocInfo,
995) !u64 {
996 log.debug("getLazySymbolVAddr {t} {f}({d})", .{
997 lazy_sym.kind,
998 Value.fromInterned(lazy_sym.key).fmtValue(pt),
999 lazy_sym.key,
1000 });
1001 const this_sym_index = try self.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym);
1002 const this_sym = self.symbol(this_sym_index);
1003 const vaddr = this_sym.address(.{}, elf_file);
1004 switch (reloc_info.parent) {
1005 .none => unreachable,
1006 .atom_index => |atom_index| {
1007 const parent_atom = self.symbol(atom_index).atom(elf_file).?;
1008 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
1009 try parent_atom.addReloc(elf_file.base.comp.gpa, .{
1010 .r_offset = reloc_info.offset,
1011 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
1012 .r_addend = reloc_info.addend,
1013 }, self);
1014 },
1015 .debug_output => |debug_output| switch (debug_output) {
1016 .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
1017 .source_off = @intCast(reloc_info.offset),
1018 .target_sym = this_sym_index,
1019 .target_off = reloc_info.addend,
1020 }),
1021 .none => unreachable,
1022 },
1023 }
1024 return @bitCast(vaddr);
1025}
1026
9961027pub fn lowerUav(
9971028 self: *ZigObject,
9981029 elf_file: *Elf,
......@@ -1063,12 +1094,16 @@ pub fn getOrCreateMetadataForLazySymbol(
10631094 pt: Zcu.PerThread,
10641095 lazy_sym: link.File.LazySymbol,
10651096) !Symbol.Index {
1066 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
1067 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1097 const lazy_syms = switch (lazy_sym.kind) {
1098 .code, .const_data => &self.lazy_syms,
1099 .deferred_const_data => &self.deferred_lazy_syms,
1100 };
1101 const gop = try lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.key);
1102 errdefer _ = if (!gop.found_existing) lazy_syms.pop();
10681103 if (!gop.found_existing) gop.value_ptr.* = .{};
10691104 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
10701105 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
1071 .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state },
1106 .const_data, .deferred_const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state },
10721107 };
10731108 switch (state_ptr.*) {
10741109 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0),
......@@ -1077,8 +1112,10 @@ pub fn getOrCreateMetadataForLazySymbol(
10771112 }
10781113 state_ptr.* = .pending_flush;
10791114 const symbol_index = symbol_index_ptr.*;
1080 // anyerror needs to be deferred until flush
1081 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);
1115 switch (lazy_sym.kind) {
1116 .code, .const_data => try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index),
1117 .deferred_const_data => {},
1118 }
10821119 return symbol_index;
10831120}
10841121
......@@ -1726,20 +1763,18 @@ fn updateLazySymbol(
17261763 self: *ZigObject,
17271764 elf_file: *Elf,
17281765 pt: Zcu.PerThread,
1729 sym: link.File.LazySymbol,
1766 lazy_sym: link.File.LazySymbol,
17301767 symbol_index: Symbol.Index,
17311768) !void {
17321769 const zcu = pt.zcu;
17331770 const gpa = zcu.gpa;
17341771
1735 var required_alignment: InternPool.Alignment = .none;
17361772 var aw: std.Io.Writer.Allocating = .init(gpa);
17371773 defer aw.deinit();
17381774
17391775 const name_str_index = blk: {
1740 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
1741 @tagName(sym.kind),
1742 Type.fromInterned(sym.ty).fmt(pt),
1776 const name = try std.fmt.allocPrint(gpa, "__lazy_{t}_{f}", .{
1777 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
17431778 });
17441779 defer gpa.free(name);
17451780 break :blk try self.strtab.insert(gpa, name);
......@@ -1748,9 +1783,8 @@ fn updateLazySymbol(
17481783 codegen.generateLazySymbol(
17491784 &elf_file.base,
17501785 pt,
1751 Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded,
1752 sym,
1753 &required_alignment,
1786 Type.fromInterned(lazy_sym.key).srcLocOrNull(zcu) orelse .unneeded,
1787 lazy_sym,
17541788 &aw.writer,
17551789 .none,
17561790 .{ .atom_index = symbol_index },
......@@ -1760,7 +1794,7 @@ fn updateLazySymbol(
17601794 };
17611795 const code = aw.written();
17621796
1763 const output_section_index = switch (sym.kind) {
1797 const output_section_index = switch (lazy_sym.kind) {
17641798 .code => if (self.text_index) |sym_index|
17651799 self.symbol(sym_index).outputShndx(elf_file).?
17661800 else osec: {
......@@ -1773,7 +1807,7 @@ fn updateLazySymbol(
17731807 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);
17741808 break :osec osec;
17751809 },
1776 .const_data => if (self.rodata_index) |sym_index|
1810 .const_data, .deferred_const_data => if (self.rodata_index) |sym_index|
17771811 self.symbol(sym_index).outputShndx(elf_file).?
17781812 else osec: {
17791813 const osec = try elf_file.addSection(.{
......@@ -1786,24 +1820,24 @@ fn updateLazySymbol(
17861820 break :osec osec;
17871821 },
17881822 };
1789 const local_sym = self.symbol(symbol_index);
1790 local_sym.name_offset = name_str_index;
1791 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
1792 local_esym.st_name = name_str_index;
1793 local_esym.st_info |= elf.STT_OBJECT;
1794 local_esym.st_size = code.len;
1795 const atom_ptr = local_sym.atom(elf_file).?;
1823 const sym = self.symbol(symbol_index);
1824 sym.name_offset = name_str_index;
1825 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
1826 esym.st_name = name_str_index;
1827 esym.st_info |= elf.STT_OBJECT;
1828 esym.st_size = code.len;
1829 const atom_ptr = sym.atom(elf_file).?;
17961830 atom_ptr.alive = true;
17971831 atom_ptr.name_offset = name_str_index;
1798 atom_ptr.alignment = required_alignment;
1832 atom_ptr.alignment = codegen.getLazySymbolInfo(.attributes, lazy_sym, zcu).required_alignment;
17991833 atom_ptr.size = code.len;
18001834 atom_ptr.output_section_index = output_section_index;
18011835
18021836 try self.allocateAtom(atom_ptr, true, elf_file);
18031837 errdefer self.freeNavMetadata(elf_file, symbol_index);
18041838
1805 local_sym.value = 0;
1806 local_esym.st_value = 0;
1839 sym.value = 0;
1840 esym.st_value = 0;
18071841
18081842 try elf_file.pwriteAll(code, atom_ptr.offset(elf_file));
18091843}
src/link/Elf2.zig+92-46
......@@ -75,6 +75,7 @@ pub const Node = union(enum) {
7575 uav: UavMapIndex,
7676 lazy_code: LazyMapRef.Index(.code),
7777 lazy_const_data: LazyMapRef.Index(.const_data),
78 lazy_deferred_const_data: LazyMapRef.Index(.deferred_const_data),
7879
7980 pub const InputIndex = enum(u32) {
8081 _,
......@@ -163,7 +164,7 @@ pub const Node = union(enum) {
163164 }
164165
165166 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {
166 return .{ .kind = lmr.kind, .ty = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
167 return .{ .kind = lmr.kind, .key = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
167168 }
168169
169170 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.Index {
......@@ -1680,7 +1681,12 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
16801681 },
16811682 .section => |si| si,
16821683 .input_section => unreachable,
1683 inline .nav, .uav, .lazy_code, .lazy_const_data => |mi| mi.symbol(elf),
1684 inline .nav,
1685 .uav,
1686 .lazy_code,
1687 .lazy_const_data,
1688 .lazy_deferred_const_data,
1689 => |mi| mi.symbol(elf),
16841690 };
16851691 break :parent_vaddr if (parent_si == elf.si.tdata) 0 else switch (elf.symPtr(parent_si)) {
16861692 inline else => |sym| elf.targetLoad(&sym.value),
......@@ -1927,7 +1933,8 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavM
19271933 });
19281934 return @enumFromInt(nav_gop.index);
19291935}
1930pub fn navSymbol(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
1936pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !Symbol.Index {
1937 const zcu = elf.base.comp.zcu.?;
19311938 const ip = &zcu.intern_pool;
19321939 const nav = ip.getNav(nav_index);
19331940 if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{
......@@ -1963,20 +1970,35 @@ pub fn uavSymbol(elf: *Elf, uav_val: InternPool.Index) !Symbol.Index {
19631970 return umi.symbol(elf);
19641971}
19651972
1966pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !Symbol.Index {
1967 const gpa = elf.base.comp.gpa;
1968 try elf.symtab.ensureUnusedCapacity(gpa, 1);
1969 const lazy_gop = try elf.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty);
1970 if (!lazy_gop.found_existing) {
1971 lazy_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{
1972 .type = switch (lazy.kind) {
1973 .code => .FUNC,
1974 .const_data => .OBJECT,
1975 },
1976 });
1977 elf.synth_prog_node.increaseEstimatedTotalItems(1);
1978 }
1979 return lazy_gop.value_ptr.*;
1973fn lazySymbolIfExists(elf: *Elf, lazy_sym: link.File.LazySymbol) ?Symbol.Index {
1974 return elf.lazy.getPtr(lazy_sym.kind).map.get(lazy_sym.key);
1975}
1976fn lazySymbolAssumeCapacity(elf: *Elf, lazy_sym: link.File.LazySymbol) !struct { Symbol.Index, usize } {
1977 const gop = try elf.lazy.getPtr(lazy_sym.kind).map.getOrPut(elf.base.comp.gpa, lazy_sym.key);
1978 if (gop.found_existing) return .{ gop.value_ptr.*, gop.index };
1979 const si = try elf.initSymbolAssumeCapacity(.{
1980 .type = switch (lazy_sym.kind) {
1981 .code => .FUNC,
1982 .const_data, .deferred_const_data => .OBJECT,
1983 },
1984 });
1985 gop.value_ptr.* = si;
1986 elf.synth_prog_node.increaseEstimatedTotalItems(1);
1987 return .{ si, gop.index };
1988}
1989pub fn lazySymbol(elf: *Elf, lazy_sym: link.File.LazySymbol) !Symbol.Index {
1990 // optimize for future lookups, at the cost of an extra initial key lookup
1991 if (elf.lazySymbolIfExists(lazy_sym)) |si| return si;
1992 const comp = elf.base.comp;
1993 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, comp.zcu.?);
1994 try elf.symtab.ensureUnusedCapacity(
1995 comp.gpa,
1996 @as(usize, @intFromBool(structure.parent != null)) + @intFromBool(structure.modify != null) + 1,
1997 );
1998 if (structure.parent) |parent_lazy_sym| _ = try elf.lazySymbolAssumeCapacity(parent_lazy_sym);
1999 if (structure.modify) |modification| _ = try elf.lazySymbolAssumeCapacity(modification.lazy_sym);
2000 const si, _ = try elf.lazySymbolAssumeCapacity(lazy_sym);
2001 return si;
19802002}
19812003
19822004pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||
......@@ -2531,11 +2553,10 @@ fn prelinkInner(elf: *Elf) !void {
25312553
25322554pub fn getNavVAddr(
25332555 elf: *Elf,
2534 pt: Zcu.PerThread,
25352556 nav: InternPool.Nav.Index,
25362557 reloc_info: link.File.RelocInfo,
25372558) !u64 {
2538 return elf.getVAddr(reloc_info, try elf.navSymbol(pt.zcu, nav));
2559 return elf.getVAddr(reloc_info, try elf.navSymbol(nav));
25392560}
25402561
25412562pub fn getUavVAddr(
......@@ -2546,6 +2567,15 @@ pub fn getUavVAddr(
25462567 return elf.getVAddr(reloc_info, try elf.uavSymbol(uav));
25472568}
25482569
2570pub fn getLazySymbolVAddr(
2571 elf: *Elf,
2572 _: Zcu.PerThread,
2573 lazy_sym: link.File.LazySymbol,
2574 reloc_info: link.File.RelocInfo,
2575) !u64 {
2576 return elf.getVAddr(reloc_info, try elf.lazySymbol(lazy_sym));
2577}
2578
25492579pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {
25502580 try elf.addReloc(
25512581 @enumFromInt(reloc_info.parent.atom_index),
......@@ -3106,13 +3136,13 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
31063136 lazy.value.pending_index += 1;
31073137 const kind = switch (lmr.kind) {
31083138 .code => "code",
3109 .const_data => "data",
3139 .const_data, .deferred_const_data => "data",
31103140 };
31113141 var name: [std.Progress.Node.max_name_len]u8 = undefined;
31123142 const sub_prog_node = elf.synth_prog_node.start(
31133143 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{
31143144 kind,
3115 Type.fromInterned(lmr.lazySymbol(elf).ty).fmt(pt),
3145 Value.fromInterned(lmr.lazySymbol(elf).key).fmtValue(pt),
31163146 }) catch &name,
31173147 0,
31183148 );
......@@ -3259,26 +3289,38 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
32593289 const zcu = pt.zcu;
32603290 const gpa = zcu.gpa;
32613291
3262 const lazy = lmr.lazySymbol(elf);
3292 const lazy_sym = lmr.lazySymbol(elf);
32633293 const si = lmr.symbol(elf);
3294 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, zcu);
32643295 const ni = ni: {
32653296 const sym = si.get(elf);
32663297 switch (sym.ni) {
32673298 .none => {
32683299 try elf.nodes.ensureUnusedCapacity(gpa, 1);
3269 const sec_si: Symbol.Index = switch (lazy.kind) {
3300 const attrs = codegen.getLazySymbolInfo(.attributes, lazy_sym, zcu);
3301 const parent_si: Symbol.Index = if (structure.parent) |parent_lazy_sym|
3302 elf.lazySymbolIfExists(parent_lazy_sym).?
3303 else switch (lazy_sym.kind) {
32703304 .code => .text,
3271 .const_data => .rodata,
3305 .const_data, .deferred_const_data => .rodata,
32723306 };
3273 const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ .moved = true });
3274 elf.nodes.appendAssumeCapacity(switch (lazy.kind) {
3307 const addChildNode =
3308 if (attrs.header) &MappedFile.addOnlyChildNode else &MappedFile.addLastChildNode;
3309 const ni = try addChildNode(&elf.mf, elf.base.comp.gpa, parent_si.node(elf), .{
3310 .size = attrs.size orelse 0,
3311 .alignment = attrs.required_alignment.toStdMem(),
3312 .fixed = attrs.header,
3313 .moved = true,
3314 });
3315 elf.nodes.appendAssumeCapacity(switch (lazy_sym.kind) {
32753316 .code => .{ .lazy_code = @enumFromInt(lmr.index) },
32763317 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },
3318 .deferred_const_data => .{ .lazy_deferred_const_data = @enumFromInt(lmr.index) },
32773319 });
32783320 sym.ni = ni;
32793321 switch (elf.symPtr(si)) {
32803322 inline else => |sym_ptr, class| sym_ptr.shndx =
3281 @field(elf.symPtr(sec_si), @tagName(class)).shndx,
3323 @field(elf.symPtr(parent_si), @tagName(class)).shndx,
32823324 }
32833325 },
32843326 else => si.deleteLocationRelocs(elf),
......@@ -3288,16 +3330,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
32883330 break :ni sym.ni;
32893331 };
32903332
3291 var required_alignment: InternPool.Alignment = .none;
32923333 var nw: MappedFile.Node.Writer = undefined;
32933334 ni.writer(&elf.mf, gpa, &nw);
32943335 defer nw.deinit();
32953336 try codegen.generateLazySymbol(
32963337 &elf.base,
32973338 pt,
3298 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
3299 lazy,
3300 &required_alignment,
3339 Type.fromInterned(lazy_sym.key).srcLocOrNull(pt.zcu) orelse .unneeded,
3340 lazy_sym,
33013341 &nw.interface,
33023342 .none,
33033343 .{ .atom_index = @intFromEnum(si) },
......@@ -3306,6 +3346,11 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
33063346 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
33073347 }
33083348 si.applyLocationRelocs(elf);
3349
3350 if (structure.modify) |modification| modification.operation.apply(
3351 elf.lazySymbolIfExists(modification.lazy_sym).?.node(elf).slice(&elf.mf),
3352 elf.targetEndian(),
3353 );
33093354}
33103355
33113356fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void {
......@@ -3501,10 +3546,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
35013546 } - old_addr + new_addr);
35023547 }
35033548 },
3504 inline .nav, .uav, .lazy_code, .lazy_const_data => |mi| mi.symbol(elf).flushMoved(
3505 elf,
3506 elf.computeNodeVAddr(ni),
3507 ),
3549 inline .nav,
3550 .uav,
3551 .lazy_code,
3552 .lazy_const_data,
3553 .lazy_deferred_const_data,
3554 => |mi| mi.symbol(elf).flushMoved(elf, elf.computeNodeVAddr(ni)),
35083555 }
35093556 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);
35103557}
......@@ -3614,7 +3661,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
36143661 elf.targetStore(&shdr.size, @intCast(size));
36153662 },
36163663 },
3617 .input_section, .nav, .uav, .lazy_code, .lazy_const_data => {},
3664 .input_section, .nav, .uav, .lazy_code, .lazy_const_data, .lazy_deferred_const_data => {},
36183665 }
36193666}
36203667
......@@ -3655,7 +3702,7 @@ fn updateExportsInner(
36553702 try elf.symtab.ensureUnusedCapacity(gpa, export_indices.len);
36563703 const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) {
36573704 .nav => |nav| .{
3658 try elf.navSymbol(zcu, nav),
3705 try elf.navSymbol(nav),
36593706 navType(ip, ip.getNav(nav).resolved.?, elf.base.comp.config.any_non_single_threaded),
36603707 },
36613708 .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav(
......@@ -3715,15 +3762,15 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
37153762 _ = name;
37163763}
37173764
3718pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void {
3765pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) !void {
37193766 const comp = elf.base.comp;
37203767 const io = comp.io;
37213768 var buffer: [512]u8 = undefined;
37223769 const stderr = try io.lockStderr(&buffer, null);
3723 defer io.lockStderr();
3770 defer io.unlockStderr();
37243771 const w = &stderr.file_writer.interface;
37253772 elf.printNode(tid, w, .root, 0) catch |err| switch (err) {
3726 error.WriteFailed => return stderr.err.?,
3773 error.WriteFailed => return stderr.file_writer.err.?,
37273774 };
37283775}
37293776
......@@ -3773,7 +3820,7 @@ pub fn printNode(
37733820 const ip = &zcu.intern_pool;
37743821 const nav = ip.getNav(nmi.navIndex(elf));
37753822 try w.print("({f}, {f})", .{
3776 Type.fromInterned(nav.typeOf(ip)).fmt(.{ .zcu = zcu, .tid = tid }),
3823 Type.fromInterned(nav.resolved.?.type).fmt(.{ .zcu = zcu, .tid = tid }),
37773824 nav.fqn.fmt(ip),
37783825 });
37793826 },
......@@ -3786,17 +3833,16 @@ pub fn printNode(
37863833 });
37873834 },
37883835 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{
3789 Type.fromInterned(lmi.lazySymbol(elf).ty).fmt(.{
3790 .zcu = elf.base.comp.zcu.?,
3791 .tid = tid,
3792 }),
3836 Value.fromInterned(lmi.lazySymbol(elf).key).fmtValue(
3837 .{ .zcu = elf.base.comp.zcu.?, .tid = tid },
3838 ),
37933839 }),
37943840 }
37953841 {
37963842 const mf_node = &elf.mf.nodes.items[@intFromEnum(ni)];
37973843 const off, const size = mf_node.location().resolve(&elf.mf);
37983844 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}\n", .{
3799 @intFromEnum(ni),
3845 ni,
38003846 off,
38013847 size,
38023848 mf_node.flags.alignment.toByteUnits(),
src/link/MachO.zig+6-2
......@@ -3116,8 +3116,8 @@ pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
31163116 return self.getZigObject().?.freeNav(nav);
31173117}
31183118
3119pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
3120 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);
3119pub fn getNavVAddr(self: *MachO, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
3120 return self.getZigObject().?.getNavVAddr(self, nav_index, reloc_info);
31213121}
31223122
31233123pub fn lowerUav(
......@@ -3134,6 +3134,10 @@ pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.Re
31343134 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
31353135}
31363136
3137pub fn getLazySymbolVAddr(self: *MachO, pt: Zcu.PerThread, lazy_sym: link.File.LazySymbol, reloc_info: link.File.RelocInfo) !u64 {
3138 return self.getZigObject().?.getLazySymbolVAddr(self, pt, lazy_sym, reloc_info);
3139}
3140
31373141pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {
31383142 return self.getZigObject().?.getGlobalSymbol(self, name, lib_name);
31393143}
src/link/MachO/ZigObject.zig+86-42
......@@ -18,10 +18,11 @@ atoms_extra: std.ArrayList(u32) = .empty,
1818
1919/// Table of tracked LazySymbols.
2020lazy_syms: LazySymbolTable = .{},
21/// Table of tracked LazySymbols that are deferred until flush.
22deferred_lazy_syms: LazySymbolTable = .{},
2123
2224/// Table of tracked Navs.
2325navs: NavTable = .{},
24
2526/// Table of tracked Uavs.
2627uavs: UavTable = .{},
2728
......@@ -78,13 +79,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
7879 self.atoms_indexes.deinit(allocator);
7980 self.atoms_extra.deinit(allocator);
8081
82 self.lazy_syms.deinit(allocator);
83 self.deferred_lazy_syms.deinit(allocator);
84
8185 for (self.navs.values()) |*meta| {
8286 meta.exports.deinit(allocator);
8387 }
8488 self.navs.deinit(allocator);
8589
86 self.lazy_syms.deinit(allocator);
87
8890 for (self.uavs.values()) |*meta| {
8991 meta.exports.deinit(allocator);
9092 }
......@@ -559,30 +561,23 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
559561 const diags = &macho_file.base.comp.link_diags;
560562
561563 // Handle any lazy symbols that were emitted by incremental compilation.
562 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
564 {
563565 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);
564566 defer pt.deactivate();
565567
566 // Most lazy symbols can be updated on first use, but
567 // anyerror needs to wait for everything to be flushed.
568 if (metadata.text_state != .unused) self.updateLazySymbol(
569 macho_file,
570 pt,
571 .{ .kind = .code, .ty = .anyerror_type },
572 metadata.text_symbol_index,
573 ) catch |err| switch (err) {
574 error.OutOfMemory, error.LinkFailure => |e| return e,
575 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
576 };
577 if (metadata.const_state != .unused) self.updateLazySymbol(
578 macho_file,
579 pt,
580 .{ .kind = .const_data, .ty = .anyerror_type },
581 metadata.const_symbol_index,
582 ) catch |err| switch (err) {
583 error.OutOfMemory, error.LinkFailure => |e| return e,
584 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
585 };
568 for (self.deferred_lazy_syms.values(), self.deferred_lazy_syms.keys()) |*metadata, key| {
569 assert(metadata.text_state == .unused);
570 if (metadata.const_state != .unused) self.updateLazySymbol(
571 macho_file,
572 pt,
573 .{ .kind = .deferred_const_data, .key = key },
574 metadata.const_symbol_index,
575 ) catch |err| switch (err) {
576 error.LinkFailure, error.CodegenFail => return error.LinkFailure,
577 error.OutOfMemory => |e| return e,
578 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
579 };
580 }
586581 }
587582 for (self.lazy_syms.values()) |*metadata| {
588583 if (metadata.text_state != .unused) metadata.text_state = .flushed;
......@@ -614,11 +609,10 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
614609pub fn getNavVAddr(
615610 self: *ZigObject,
616611 macho_file: *MachO,
617 pt: Zcu.PerThread,
618612 nav_index: InternPool.Nav.Index,
619613 reloc_info: link.File.RelocInfo,
620614) !u64 {
621 const zcu = pt.zcu;
615 const zcu = macho_file.base.comp.zcu.?;
622616 const ip = &zcu.intern_pool;
623617 const nav = ip.getNav(nav_index);
624618 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
......@@ -698,6 +692,51 @@ pub fn getUavVAddr(
698692 return vaddr;
699693}
700694
695pub fn getLazySymbolVAddr(
696 self: *ZigObject,
697 macho_file: *MachO,
698 pt: Zcu.PerThread,
699 lazy_sym: link.File.LazySymbol,
700 reloc_info: link.File.RelocInfo,
701) !u64 {
702 log.debug("getLazySymbolVAddr {t} {f}({d})", .{
703 lazy_sym.kind,
704 Value.fromInterned(lazy_sym.key).fmtValue(pt),
705 lazy_sym.key,
706 });
707 const sym_index = try self.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym);
708 const sym = self.symbols.items[sym_index];
709 const vaddr = sym.getAddress(.{}, macho_file);
710 switch (reloc_info.parent) {
711 .none => unreachable,
712 .atom_index => |atom_index| {
713 const parent_atom = self.symbols.items[atom_index].getAtom(macho_file).?;
714 try parent_atom.addReloc(macho_file, .{
715 .tag = .@"extern",
716 .offset = @intCast(reloc_info.offset),
717 .target = sym_index,
718 .addend = reloc_info.addend,
719 .type = .unsigned,
720 .meta = .{
721 .pcrel = false,
722 .has_subtractor = false,
723 .length = 3,
724 .symbolnum = @intCast(sym.nlist_idx),
725 },
726 });
727 },
728 .debug_output => |debug_output| switch (debug_output) {
729 .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{
730 .source_off = @intCast(reloc_info.offset),
731 .target_sym = sym_index,
732 .target_off = reloc_info.addend,
733 }),
734 .none => unreachable,
735 },
736 }
737 return vaddr;
738}
739
701740pub fn lowerUav(
702741 self: *ZigObject,
703742 macho_file: *MachO,
......@@ -1355,35 +1394,34 @@ fn updateLazySymbol(
13551394 const zcu = pt.zcu;
13561395 const gpa = zcu.gpa;
13571396
1358 var required_alignment: Atom.Alignment = .none;
13591397 var aw: std.Io.Writer.Allocating = .init(gpa);
13601398 defer aw.deinit();
13611399
13621400 const name_str = blk: {
1363 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
1364 @tagName(lazy_sym.kind),
1365 Type.fromInterned(lazy_sym.ty).fmt(pt),
1401 const name = try std.fmt.allocPrint(gpa, "__lazy_{t}_{f}", .{
1402 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
13661403 });
13671404 defer gpa.free(name);
13681405 break :blk try self.addString(gpa, name);
13691406 };
13701407
1371 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
1372 try codegen.generateLazySymbol(
1408 codegen.generateLazySymbol(
13731409 &macho_file.base,
13741410 pt,
1375 src,
1411 Type.fromInterned(lazy_sym.key).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded,
13761412 lazy_sym,
1377 &required_alignment,
13781413 &aw.writer,
13791414 .none,
13801415 .{ .atom_index = symbol_index },
1381 );
1416 ) catch |err| switch (err) {
1417 error.WriteFailed => return error.OutOfMemory,
1418 else => |e| return e,
1419 };
13821420 const code = aw.written();
13831421
13841422 const output_section_index = switch (lazy_sym.kind) {
13851423 .code => macho_file.zig_text_sect_index.?,
1386 .const_data => macho_file.zig_const_sect_index.?,
1424 .const_data, .deferred_const_data => macho_file.zig_const_sect_index.?,
13871425 };
13881426 const sym = &self.symbols.items[symbol_index];
13891427 sym.name = name_str;
......@@ -1398,7 +1436,7 @@ fn updateLazySymbol(
13981436 const atom = sym.getAtom(macho_file).?;
13991437 atom.setAlive(true);
14001438 atom.name = name_str;
1401 atom.alignment = required_alignment;
1439 atom.alignment = codegen.getLazySymbolInfo(.attributes, lazy_sym, zcu).required_alignment;
14021440 atom.size = code.len;
14031441 atom.out_n_sect = output_section_index;
14041442
......@@ -1516,12 +1554,16 @@ pub fn getOrCreateMetadataForLazySymbol(
15161554 pt: Zcu.PerThread,
15171555 lazy_sym: link.File.LazySymbol,
15181556) !Symbol.Index {
1519 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);
1520 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
1557 const lazy_syms = switch (lazy_sym.kind) {
1558 .code, .const_data => &self.lazy_syms,
1559 .deferred_const_data => &self.deferred_lazy_syms,
1560 };
1561 const gop = try lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.key);
1562 errdefer _ = if (!gop.found_existing) lazy_syms.pop();
15211563 if (!gop.found_existing) gop.value_ptr.* = .{};
15221564 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
15231565 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },
1524 .const_data => .{ &gop.value_ptr.const_symbol_index, &gop.value_ptr.const_state },
1566 .const_data, .deferred_const_data => .{ &gop.value_ptr.const_symbol_index, &gop.value_ptr.const_state },
15251567 };
15261568 switch (state_ptr.*) {
15271569 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, .{}, macho_file),
......@@ -1530,8 +1572,10 @@ pub fn getOrCreateMetadataForLazySymbol(
15301572 }
15311573 state_ptr.* = .pending_flush;
15321574 const symbol_index = symbol_index_ptr.*;
1533 // anyerror needs to be deferred until flush
1534 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);
1575 switch (lazy_sym.kind) {
1576 .code, .const_data => try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index),
1577 .deferred_const_data => {},
1578 }
15351579 return symbol_index;
15361580}
15371581
src/target.zig+4
......@@ -948,5 +948,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
948948 // being run in a separate thread from now on.
949949 else => true,
950950 },
951 .restricted_types => switch (backend) {
952 .stage2_c, .stage2_x86_64 => true,
953 else => false,
954 },
951955 };
952956}