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(...@@ -12358,7 +12358,11 @@ pub fn addFieldTagValue(
12358/// encoding instead of `Tag.ptr_uav_aligned` when possible.12358/// encoding instead of `Tag.ptr_uav_aligned` when possible.
12359fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {12359fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty: Index) bool {
12360 if (a_ty == b_ty) return true;12360 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 };
12362 return a_info.flags.alignment == b_info.flags.alignment and12366 return a_info.flags.alignment == b_info.flags.alignment and
12363 (a_info.child == b_info.child or a_info.flags.alignment != .none);12367 (a_info.child == b_info.child or a_info.flags.alignment != .none);
12364}12368}
src/Type.zig+8-4
...@@ -1350,14 +1350,17 @@ pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {...@@ -1350,14 +1350,17 @@ pub fn unrestrictedType(ty: Type, zcu: *const Zcu) ?Type {
1350 };1350 };
1351}1351}
13521352
1353const RestrictedRepr = enum { double_pointer, single_pointer };1353const RestrictedRepr = enum { indirect, direct };
1354pub fn restrictedRepr(ty: Type, zcu: *const Zcu) RestrictedRepr {1354pub 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 };
1356}1359}
1357pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {1360pub fn restrictedReprByZirIndex(zir_index: InternPool.TrackedInst.Index, zcu: *const Zcu) RestrictedRepr {
1358 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {1361 return switch (zcu.fileByIndex(zir_index.resolveFile(&zcu.intern_pool)).mod.?.optimize_mode) {
1359 .Debug, .ReleaseSafe => .double_pointer,1362 .Debug, .ReleaseSafe => if (zcu.backendSupportsFeature(.restricted_types)) .indirect else .direct,
1360 .ReleaseFast, .ReleaseSmall => .single_pointer,1363 .ReleaseFast, .ReleaseSmall => .direct,
1361 };1364 };
1362}1365}
13631366
...@@ -2670,6 +2673,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {...@@ -2670,6 +2673,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
2670 const ip = &zcu.intern_pool;2673 const ip = &zcu.intern_pool;
2671 return .{2674 return .{
2672 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {2675 .base_node_inst = switch (ip.indexToKey(ty.toIntern())) {
2676 .restricted_ptr_type => |restricted_ptr_type| restricted_ptr_type.zir_index,
2673 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {2677 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2674 .declared => |d| d.zir_index,2678 .declared => |d| d.zir_index,
2675 .reified => |r| r.zir_index,2679 .reified => |r| r.zir_index,
src/Zcu.zig+1
...@@ -3995,6 +3995,7 @@ pub const Feature = enum {...@@ -3995,6 +3995,7 @@ pub const Feature = enum {
3995 /// * With this feature disabled, semantic analysis, code generation, and linking all occur on the3995 /// * With this feature disabled, semantic analysis, code generation, and linking all occur on the
3996 /// same thread, and the "emit" stage has access to AIR.3996 /// same thread, and the "emit" stage has access to AIR.
3997 separate_thread,3997 separate_thread,
3998 restricted_types,
3998};3999};
39994000
4000pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {4001pub fn backendSupportsFeature(zcu: *const Zcu, comptime feature: Feature) bool {
src/codegen.zig+242-74
...@@ -210,7 +210,7 @@ pub fn generateLazyFunction(...@@ -210,7 +210,7 @@ pub fn generateLazyFunction(
210 debug_output: link.File.DebugInfoOutput,210 debug_output: link.File.DebugInfoOutput,
211) (CodeGenError || std.Io.Writer.Error)!void {211) (CodeGenError || std.Io.Writer.Error)!void {
212 const zcu = pt.zcu;212 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|
214 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result214 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
215 else215 else
216 zcu.getTarget();216 zcu.getTarget();
...@@ -223,13 +223,118 @@ pub fn generateLazyFunction(...@@ -223,13 +223,118 @@ pub fn generateLazyFunction(
223 }223 }
224}224}
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}
226pub fn generateLazySymbol(333pub fn generateLazySymbol(
227 bin_file: *link.File,334 bin_file: *link.File,
228 pt: Zcu.PerThread,335 pt: Zcu.PerThread,
229 src_loc: Zcu.LazySrcLoc,336 src_loc: Zcu.LazySrcLoc,
230 lazy_sym: link.File.LazySymbol,337 lazy_sym: link.File.LazySymbol,
231 // TODO don't use an "out" parameter like this; put it in the result instead
232 alignment: *Alignment,
233 w: *std.Io.Writer,338 w: *std.Io.Writer,
234 debug_output: link.File.DebugInfoOutput,339 debug_output: link.File.DebugInfoOutput,
235 reloc_parent: link.File.RelocInfo.Parent,340 reloc_parent: link.File.RelocInfo.Parent,
...@@ -243,51 +348,81 @@ pub fn generateLazySymbol(...@@ -243,51 +348,81 @@ pub fn generateLazySymbol(
243 const target = &comp.root_mod.resolved_target.result;348 const target = &comp.root_mod.resolved_target.result;
244 const endian = target.cpu.arch.endian();349 const endian = target.cpu.arch.endian();
245350
246 log.debug("generateLazySymbol: kind = {s}, ty = {f}", .{351 log.debug("generateLazySymbol: kind = {s}, key = {f}", .{
247 @tagName(lazy_sym.kind),352 @tagName(lazy_sym.kind),
248 Type.fromInterned(lazy_sym.ty).fmt(pt),353 Value.fromInterned(lazy_sym.key).fmtValue(pt),
249 });354 });
250355
251 if (lazy_sym.kind == .code) {356 switch (lazy_sym.kind) {
252 alignment.* = target_util.defaultFunctionAlignment(target);357 .code => return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, reloc_parent.atom_index, w, debug_output),
253 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 },
254 }418 }
255419 switch (ip.typeOf(lazy_sym.key)) {
256 if (lazy_sym.ty == .anyerror_type) {420 .type_type => return zcu.codegenFailType(lazy_sym.key, "TODO implement generateLazySymbol for {t} {f}", .{
257 alignment.* = .@"4";421 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
258 const err_names = ip.global_error_set.getNamesFromMainThread();422 }),
259 const strings_start: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));423 else => std.debug.panic("TODO implement generateLazySymbol for {t} {f}", .{
260 var string_index = strings_start;424 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
261 try w.rebase(w.end, string_index);425 }),
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 });
291 }426 }
292}427}
293428
...@@ -441,7 +576,10 @@ pub fn generateSymbol(...@@ -441,7 +576,10 @@ pub fn generateSymbol(
441 128 => try w.writeInt(u128, @bitCast(f128_val), endian),576 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
442 },577 },
443 },578 },
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 },
445 .slice => |slice| {583 .slice => |slice| {
446 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);584 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
447 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);585 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
...@@ -838,7 +976,7 @@ fn lowerNavRef(...@@ -838,7 +976,7 @@ fn lowerNavRef(
838 else => {},976 else => {},
839 }977 }
840978
841 const vaddr = lf.getNavVAddr(pt, nav_index, .{979 const vaddr = lf.getNavVAddr(nav_index, .{
842 .parent = reloc_parent,980 .parent = reloc_parent,
843 .offset = w.end,981 .offset = w.end,
844 .addend = @intCast(offset),982 .addend = @intCast(offset),
...@@ -906,7 +1044,7 @@ pub fn genNavRef(...@@ -906,7 +1044,7 @@ pub fn genNavRef(
906 .link_once => unreachable,1044 .link_once => unreachable,
907 }1045 }
908 } else if (lf.cast(.elf2)) |elf| {1046 } 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) {
910 error.OutOfMemory => |e| return e,1048 error.OutOfMemory => |e| return e,
911 else => |e| return .{ .fail = try ErrorMsg.create(1049 else => |e| return .{ .fail = try ErrorMsg.create(
912 zcu.gpa,1050 zcu.gpa,
...@@ -937,13 +1075,38 @@ pub fn genNavRef(...@@ -937,13 +1075,38 @@ pub fn genNavRef(
937 .link_once => unreachable,1075 .link_once => unreachable,
938 }1076 }
939 } else if (lf.cast(.coff2)) |coff| {1077 } 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)) };
941 } else {1079 } else {
942 const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});1080 const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
943 return .{ .fail = msg };1081 return .{ .fail = msg };
944 }1082 }
945}1083}
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
947/// deprecated legacy type1110/// deprecated legacy type
948pub const GenResult = union(enum) {1111pub const GenResult = union(enum) {
949 mcv: MCValue,1112 mcv: MCValue,
...@@ -1006,6 +1169,7 @@ pub fn genTypedValue(...@@ -1006,6 +1169,7 @@ pub fn genTypedValue(
1006 } },1169 } },
1007 .fail => |em| .{ .fail = em },1170 .fail => |em| .{ .fail = em },
1008 },1171 },
1172 .lea_lazy_sym => unreachable, // `Zcu.Feature.restricted_types` is not supported by this code path
1009 };1173 };
1010}1174}
10111175
...@@ -1018,6 +1182,7 @@ const LowerResult = union(enum) {...@@ -1018,6 +1182,7 @@ const LowerResult = union(enum) {
1018 lea_nav: InternPool.Nav.Index,1182 lea_nav: InternPool.Nav.Index,
1019 load_uav: InternPool.Key.Ptr.BaseAddr.Uav,1183 load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
1020 lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,1184 lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
1185 lea_lazy_sym: link.File.LazySymbol,
1021};1186};
10221187
1023pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {1188pub 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...@@ -1034,38 +1199,41 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
1034 .bool => return .{ .immediate = @intFromBool(val.toBool()) },1199 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
1035 .pointer => switch (ty.ptrSize(zcu)) {1200 .pointer => switch (ty.ptrSize(zcu)) {
1036 .slice => {},1201 .slice => {},
1037 .one, .many, .c => {1202 .one, .many, .c => switch (ty.restrictedRepr(zcu)) {
1038 const ptr = ip.indexToKey(val.toIntern()).ptr;1203 .indirect => return .{ .lea_lazy_sym = .{ .kind = .deferred_const_data, .key = val.toIntern() } },
1039 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };1204 .direct => {
1040 if (ptr.byte_offset == 0) switch (ptr.base_addr) {1205 const ptr = ip.indexToKey(val.toIntern()).ptr;
1041 .int => unreachable, // handled above1206 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
10421207 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1043 .nav => |nav_index| {1208 .int => unreachable, // handled above
1044 const nav = ip.getNav(nav_index);1209
1045 const nav_ty: Type = .fromInterned(nav.resolved.?.type);1210 .nav => |nav_index| {
1046 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {1211 const nav = ip.getNav(nav_index);
1047 return .{ .lea_nav = 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 };
1048 } else {1226 } else {
1049 // Create the 0xaa bit pattern...1227 // Create the 0xaa bit pattern...
1050 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);1228 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1051 // ...but align the pointer1229 // ...but align the pointer
1052 const alignment = zcu.navAlignment(nav_index);1230 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1053 return .{ .immediate = alignment.forward(undef_ptr_bits) };1231 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1054 }1232 },
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 },
10661233
1067 else => {},1234 else => {},
1068 };1235 };
1236 },
1069 },1237 },
1070 },1238 },
1071 .int => {1239 .int => {
src/codegen/aarch64/Select.zig+8-8
...@@ -663,8 +663,8 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void {...@@ -663,8 +663,8 @@ pub fn analyze(isel: *Select, air_body: []const Air.Inst.Index) !void {
663663
664 maybe_noop: {664 maybe_noop: {
665 switch (isel.air.typeOf(ty_op.operand, ip).restrictedRepr(zcu)) {665 switch (isel.air.typeOf(ty_op.operand, ip).restrictedRepr(zcu)) {
666 .double_pointer => break :maybe_noop,666 .indirect => break :maybe_noop,
667 .single_pointer => {},667 .direct => {},
668 }668 }
669 if (true) break :maybe_noop;669 if (true) break :maybe_noop;
670 if (ty_op.operand.toIndex()) |src_air_inst_index| {670 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,...@@ -5766,7 +5766,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5766 const unrestricted_ty = ty_op.ty.toType();5766 const unrestricted_ty = ty_op.ty.toType();
5767 const restricted_ty = isel.air.typeOf(ty_op.operand, ip);5767 const restricted_ty = isel.air.typeOf(ty_op.operand, ip);
5768 switch (restricted_ty.restrictedRepr(zcu)) {5768 switch (restricted_ty.restrictedRepr(zcu)) {
5769 .double_pointer => {5769 .indirect => {
5770 switch (air_tag) {5770 switch (air_tag) {
5771 else => unreachable,5771 else => unreachable,
5772 .unwrap_restricted => {},5772 .unwrap_restricted => {},
...@@ -5777,7 +5777,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -5777,7 +5777,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
5777 _ = try dst_vi.value.load(isel, unrestricted_ty, ptr_mat.ra, .{});5777 _ = try dst_vi.value.load(isel, unrestricted_ty, ptr_mat.ra, .{});
5778 try ptr_mat.finish(isel);5778 try ptr_mat.finish(isel);
5779 },5779 },
5780 .single_pointer => try dst_vi.value.move(isel, ty_op.operand),5780 .direct => try dst_vi.value.move(isel, ty_op.operand),
5781 }5781 }
5782 }5782 }
5783 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;5783 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,...@@ -6888,12 +6888,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
6888 },6888 },
6889 } }));6889 } }));
6890 try isel.lazy_relocs.append(gpa, .{6890 try isel.lazy_relocs.append(gpa, .{
6891 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },6891 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
6892 .reloc = .{ .label = @intCast(isel.instructions.items.len) },6892 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6893 });6893 });
6894 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));6894 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
6895 try isel.lazy_relocs.append(gpa, .{6895 try isel.lazy_relocs.append(gpa, .{
6896 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },6896 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
6897 .reloc = .{ .label = @intCast(isel.instructions.items.len) },6897 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
6898 });6898 });
6899 try isel.emit(.adrp(ptr_ra.x(), 0));6899 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,...@@ -7231,12 +7231,12 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7231 defer isel.freeReg(ptr_ra);7231 defer isel.freeReg(ptr_ra);
7232 try isel.emit(.subs(.wzr, error_mat.ra.w(), .{ .register = ptr_ra.w() }));7232 try isel.emit(.subs(.wzr, error_mat.ra.w(), .{ .register = ptr_ra.w() }));
7233 try isel.lazy_relocs.append(gpa, .{7233 try isel.lazy_relocs.append(gpa, .{
7234 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },7234 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
7235 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7235 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7236 });7236 });
7237 try isel.emit(.ldr(ptr_ra.w(), .{ .base = ptr_ra.x() }));7237 try isel.emit(.ldr(ptr_ra.w(), .{ .base = ptr_ra.x() }));
7238 try isel.lazy_relocs.append(gpa, .{7238 try isel.lazy_relocs.append(gpa, .{
7239 .symbol = .{ .kind = .const_data, .ty = .anyerror_type },7239 .symbol = .{ .kind = .deferred_const_data, .key = .anyerror_type },
7240 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7240 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7241 });7241 });
7242 try isel.emit(.adrp(ptr_ra.x(), 0));7242 try isel.emit(.adrp(ptr_ra.x(), 0));
src/codegen/c.zig+147-14
...@@ -61,6 +61,8 @@ pub const Mir = struct {...@@ -61,6 +61,8 @@ pub const Mir = struct {
61 /// less than the natural alignment.61 /// less than the natural alignment.
62 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),62 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
63 ctype_deps: CType.Dependencies,63 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),
64 /// Key is an enum type for which we need a generated `@tagName` function.66 /// Key is an enum type for which we need a generated `@tagName` function.
65 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),67 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
66 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.68 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.
...@@ -74,6 +76,7 @@ pub const Mir = struct {...@@ -74,6 +76,7 @@ pub const Mir = struct {
74 gpa.free(mir.code);76 gpa.free(mir.code);
75 mir.need_uavs.deinit(gpa);77 mir.need_uavs.deinit(gpa);
76 mir.ctype_deps.deinit(gpa);78 mir.ctype_deps.deinit(gpa);
79 mir.need_restricted.deinit(gpa);
77 mir.need_tag_name_funcs.deinit(gpa);80 mir.need_tag_name_funcs.deinit(gpa);
78 mir.need_never_tail_funcs.deinit(gpa);81 mir.need_never_tail_funcs.deinit(gpa);
79 mir.need_never_inline_funcs.deinit(gpa);82 mir.need_never_inline_funcs.deinit(gpa);
...@@ -549,6 +552,25 @@ pub const Function = struct {...@@ -549,6 +552,25 @@ pub const Function = struct {
549 try f.writeCValue(w, member, .other);552 try f.writeCValue(w, member, .other);
550 }553 }
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
552 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {574 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {
553 return f.dg.fail(format, args);575 return f.dg.fail(format, args);
554 }576 }
...@@ -645,6 +667,7 @@ pub const DeclGen = struct {...@@ -645,6 +667,7 @@ pub const DeclGen = struct {
645 /// `.none` for natural alignment. The specified alignment is never667 /// `.none` for natural alignment. The specified alignment is never
646 /// less than the natural alignment.668 /// less than the natural alignment.
647 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),669 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
670 need_restricted: std.array_hash_map.Auto(InternPool.Index, void),
648671
649 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {672 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
650 @branchHint(.cold);673 @branchHint(.cold);
...@@ -1055,11 +1078,24 @@ pub const DeclGen = struct {...@@ -1055,11 +1078,24 @@ pub const DeclGen = struct {
1055 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);1078 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
1056 try w.writeByte('}');1079 try w.writeByte('}');
1057 },1080 },
1058 .ptr => {1081 .ptr => switch (ty.restrictedRepr(zcu)) {
1059 const derivation = try val.pointerDerivation(dg.arena, pt, null);1082 .indirect => {
1060 try w.writeByte('(');1083 try dg.need_restricted.ensureUnusedCapacity(zcu.gpa, 2);
1061 try dg.renderPointer(w, derivation, location);1084 dg.need_restricted.putAssumeCapacity(ty.toIntern(), {});
1062 try w.writeByte(')');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 },
1063 },1099 },
1064 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {1100 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
1065 .npv_payload => unreachable, // opv optional1101 .npv_payload => unreachable, // opv optional
...@@ -2061,6 +2097,55 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {...@@ -2061,6 +2097,55 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
2061 }2097 }
2062}2098}
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
2064pub fn genErrDecls(2149pub fn genErrDecls(
2065 zcu: *const Zcu,2150 zcu: *const Zcu,
2066 w: *Writer,2151 w: *Writer,
...@@ -2220,6 +2305,7 @@ pub fn generate(...@@ -2220,6 +2305,7 @@ pub fn generate(
2220 .expected_block = null,2305 .expected_block = null,
2221 .ctype_deps = .empty,2306 .ctype_deps = .empty,
2222 .uavs = .empty,2307 .uavs = .empty,
2308 .need_restricted = .empty,
2223 },2309 },
2224 .code = .init(gpa),2310 .code = .init(gpa),
2225 .indent_counter = 0,2311 .indent_counter = 0,
...@@ -2231,6 +2317,7 @@ pub fn generate(...@@ -2231,6 +2317,7 @@ pub fn generate(
2231 function.code.deinit();2317 function.code.deinit();
2232 function.dg.ctype_deps.deinit(gpa);2318 function.dg.ctype_deps.deinit(gpa);
2233 function.dg.uavs.deinit(gpa);2319 function.dg.uavs.deinit(gpa);
2320 function.dg.need_restricted.deinit(gpa);
2234 function.deinit();2321 function.deinit();
2235 }2322 }
22362323
...@@ -2252,6 +2339,7 @@ pub fn generate(...@@ -2252,6 +2339,7 @@ pub fn generate(
2252 .code = &.{},2339 .code = &.{},
2253 .ctype_deps = function.dg.ctype_deps.move(),2340 .ctype_deps = function.dg.ctype_deps.move(),
2254 .need_uavs = function.dg.uavs.move(),2341 .need_uavs = function.dg.uavs.move(),
2342 .need_restricted = function.dg.need_restricted.move(),
2255 .need_tag_name_funcs = function.need_tag_name_funcs.move(),2343 .need_tag_name_funcs = function.need_tag_name_funcs.move(),
2256 .need_never_tail_funcs = function.need_never_tail_funcs.move(),2344 .need_never_tail_funcs = function.need_never_tail_funcs.move(),
2257 .need_never_inline_funcs = function.need_never_inline_funcs.move(),2345 .need_never_inline_funcs = function.need_never_inline_funcs.move(),
...@@ -5541,8 +5629,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5541,8 +5629,8 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5541}5629}
55425630
5543fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {5631fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
5544 const pt = f.dg.pt;5632 const zcu = f.dg.pt.zcu;
5545 const zcu = pt.zcu;5633 const ip = &zcu.intern_pool;
5546 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;5634 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
55475635
5548 const unrestricted_ty = ty_op.ty.toType();5636 const unrestricted_ty = ty_op.ty.toType();
...@@ -5553,14 +5641,57 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue...@@ -5553,14 +5641,57 @@ fn airUnwrapRestricted(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue
5553 const w = &f.code.writer;5641 const w = &f.code.writer;
5554 const local = try f.allocLocal(inst, unrestricted_ty);5642 const local = try f.allocLocal(inst, unrestricted_ty);
55555643
5556 try f.writeCValue(w, local, .other);
5557 try w.writeAll(" = ");
5558 switch (restricted_ty.restrictedRepr(zcu)) {5644 switch (restricted_ty.restrictedRepr(zcu)) {
5559 .double_pointer => {5645 .indirect => {
5560 _ = safety; // TODO5646 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(" = ");
5561 try f.writeCValueDeref(w, operand);5688 try f.writeCValueDeref(w, operand);
5562 },5689 },
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 },
5564 }5695 }
5565 try w.writeByte(';');5696 try w.writeByte(';');
5566 try f.newline();5697 try f.newline();
...@@ -5849,7 +5980,8 @@ fn airBinBuiltinCall(...@@ -5849,7 +5980,8 @@ fn airBinBuiltinCall(
5849 try f.writeCValue(w, rhs, .other);5980 try f.writeCValue(w, rhs, .other);
5850 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);5981 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
5851 try f.dg.renderBuiltinInfo(w, scalar_ty, info);5982 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
5852 try w.writeAll(");\n");5983 try w.writeAll(");");
5984 try f.newline();
5853 try v.end(f, inst, w);5985 try v.end(f, inst, w);
58545986
5855 return local;5987 return local;
...@@ -6459,7 +6591,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6459,7 +6591,8 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
6459 },6591 },
6460 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),6592 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
6461 }6593 }
6462 try w.writeAll(";\n");6594 try w.writeByte(';');
6595 try f.newline();
6463 }6596 }
64646597
6465 return local;6598 return local;
src/codegen/c/type.zig+2-2
...@@ -285,7 +285,7 @@ pub const CType = union(enum) {...@@ -285,7 +285,7 @@ pub const CType = union(enum) {
285 .pointer => {285 .pointer => {
286 const ptr = cur_ty.ptrInfo(zcu);286 const ptr = cur_ty.ptrInfo(zcu);
287 if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) {287 if (cur_ty.unrestrictedType(zcu)) |unrestricted_ty| switch (cur_ty.restrictedRepr(zcu)) {
288 .double_pointer => {288 .indirect => {
289 const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu);289 const unrestricted_cty = try lowerInner(unrestricted_ty, true, deps, arena, zcu);
290 const unrestricted_cty_buf = try arena.create(CType);290 const unrestricted_cty_buf = try arena.create(CType);
291 unrestricted_cty_buf.* = unrestricted_cty;291 unrestricted_cty_buf.* = unrestricted_cty;
...@@ -296,7 +296,7 @@ pub const CType = union(enum) {...@@ -296,7 +296,7 @@ pub const CType = union(enum) {
296 .nonstring = false,296 .nonstring = false,
297 } };297 } };
298 },298 },
299 .single_pointer => {},299 .direct => {},
300 };300 };
301 switch (ptr.flags.size) {301 switch (ptr.flags.size) {
302 .slice => {302 .slice => {
src/codegen/llvm/FuncGen.zig+5-3
...@@ -3261,11 +3261,13 @@ fn airUnwrapRestricted(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Alloc...@@ -3261,11 +3261,13 @@ fn airUnwrapRestricted(self: *FuncGen, inst: Air.Inst.Index, safety: bool) Alloc
3261 const restricted_ty = self.typeOf(ty_op.operand);3261 const restricted_ty = self.typeOf(ty_op.operand);
3262 const operand = try self.resolveInst(ty_op.operand);3262 const operand = try self.resolveInst(ty_op.operand);
3263 switch (restricted_ty.restrictedRepr(zcu)) {3263 switch (restricted_ty.restrictedRepr(zcu)) {
3264 .double_pointer => {3264 .indirect => {
3265 _ = safety; // TODO3265 if (safety) {
3266 // TODO
3267 }
3266 return self.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "restricted.unwrap");3268 return self.wip.load(.normal, .ptr, operand, unrestricted_ty.abiAlignment(zcu).toLlvm(), "restricted.unwrap");
3267 },3269 },
3268 .single_pointer => return operand,3270 .direct => return operand,
3269 }3271 }
3270}3272}
32713273
src/codegen/riscv64/CodeGen.zig+25-19
...@@ -1282,9 +1282,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1282,9 +1282,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1282 const pt = func.pt;1282 const pt = func.pt;
1283 const zcu = pt.zcu;1283 const zcu = pt.zcu;
1284 const ip = &zcu.intern_pool;1284 const ip = &zcu.intern_pool;
1285 switch (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu)) {1285 switch (ip.indexToKey(lazy_sym.key)) {
1286 .@"enum" => {1286 .enum_type => {
1287 const enum_ty = Type.fromInterned(lazy_sym.ty);1287 const enum_ty = Type.fromInterned(lazy_sym.key);
1288 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});1288 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
12891289
1290 const param_regs = abi.Registers.Integer.function_arg_regs;1290 const param_regs = abi.Registers.Integer.function_arg_regs;
...@@ -1301,9 +1301,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -1301,9 +1301,9 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1301 const zo = elf_file.zigObjectPtr().?;1301 const zo = elf_file.zigObjectPtr().?;
1302 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{1302 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
1303 .kind = .const_data,1303 .kind = .const_data,
1304 .ty = enum_ty.toIntern(),1304 .key = lazy_sym.key,
1305 }) catch |err|1305 }) catch |err|
1306 return func.fail("{s} creating lazy symbol", .{@errorName(err)});1306 return func.fail("{t} creating lazy symbol", .{err});
13071307
1308 try func.genSetReg(Type.u64, data_reg, .{ .lea_symbol = .{ .sym = sym_index } });1308 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 {...@@ -1367,8 +1367,8 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1367 });1367 });
1368 },1368 },
1369 else => return func.fail(1369 else => return func.fail(
1370 "TODO implement {s} for {f}",1370 "TODO implement {t} for {f}",
1371 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },1371 .{ lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt) },
1372 ),1372 ),
1373 }1373 }
1374}1374}
...@@ -8359,22 +8359,28 @@ fn wantSafety(func: *Func) bool {...@@ -8359,22 +8359,28 @@ fn wantSafety(func: *Func) bool {
83598359
8360fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {8360fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
8361 @branchHint(.cold);8361 @branchHint(.cold);
8362 const zcu = func.pt.zcu;8362 const pt = func.pt;
8363 switch (func.owner) {8363 const zcu = pt.zcu;
8364 .nav_index => |i| return zcu.codegenFail(i, format, args),8364 return switch (func.owner) {
8365 .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),8365 .nav_index => |i| zcu.codegenFail(i, format, args),
8366 }8366 .lazy_sym => |s| switch (zcu.intern_pool.typeOf(s.key)) {
8367 return error.CodegenFail;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 };
8368}8371}
83698372
8370fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {8373fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
8371 @branchHint(.cold);8374 @branchHint(.cold);
8372 const zcu = func.pt.zcu;8375 const pt = func.pt;
8373 switch (func.owner) {8376 const zcu = pt.zcu;
8374 .nav_index => |i| return zcu.codegenFailMsg(i, msg),8377 return switch (func.owner) {
8375 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),8378 .nav_index => |i| zcu.codegenFailMsg(i, msg),
8376 }8379 .lazy_sym => |s| switch (zcu.intern_pool.typeOf(s.key)) {
8377 return error.CodegenFail;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 };
8378}8384}
83798385
8380fn parseRegName(name: []const u8) ?Register {8386fn 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...@@ -6730,11 +6730,11 @@ fn airUnwrapRestricted(cg: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerEr
6730 const unrestricted_ty = ty_op.ty.toType();6730 const unrestricted_ty = ty_op.ty.toType();
6731 const restricted_ty = cg.typeOf(ty_op.operand);6731 const restricted_ty = cg.typeOf(ty_op.operand);
6732 const result = result: switch (restricted_ty.restrictedRepr(zcu)) {6732 const result = result: switch (restricted_ty.restrictedRepr(zcu)) {
6733 .double_pointer => {6733 .indirect => {
6734 _ = safety; // TODO6734 _ = safety; // TODO
6735 break :result try cg.load(operand, unrestricted_ty, 0);6735 break :result try cg.load(operand, unrestricted_ty, 0);
6736 },6736 },
6737 .single_pointer => cg.reuseOperand(ty_op.operand, operand),6737 .direct => cg.reuseOperand(ty_op.operand, operand),
6738 };6738 };
6739 return cg.finishAir(inst, result, &.{ty_op.operand});6739 return cg.finishAir(inst, result, &.{ty_op.operand});
6740}6740}
src/codegen/x86_64/CodeGen.zig+211-244
...@@ -527,45 +527,38 @@ pub const MCValue = union(enum) {...@@ -527,45 +527,38 @@ pub const MCValue = union(enum) {
527527
528 pub fn format(mcv: MCValue, w: *Writer) Writer.Error!void {528 pub fn format(mcv: MCValue, w: *Writer) Writer.Error!void {
529 switch (mcv) {529 switch (mcv) {
530 .none, .unreach, .dead, .undef => try w.print("({s})", .{@tagName(mcv)}),530 .none, .unreach, .dead, .undef => try w.print("({t})", .{mcv}),
531 .immediate => |pl| try w.print("0x{x}", .{pl}),531 .immediate => |pl| try w.print("0x{x}", .{pl}),
532 .memory => |pl| try w.print("[ds:0x{x}]", .{pl}),532 .memory => |pl| try w.print("[ds:0x{x}]", .{pl}),
533 inline .eflags, .register => |pl| try w.print("{s}", .{@tagName(pl)}),533 inline .eflags, .register => |pl| try w.print("{t}", .{pl}),
534 .register_pair => |pl| try w.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),534 .register_pair => |pl| try w.print("{t}:{t}", .{ pl[1], pl[0] }),
535 .register_triple => |pl| try w.print("{s}:{s}:{s}", .{535 .register_triple => |pl| try w.print("{t}:{t}:{t}", .{ pl[2], pl[1], pl[0] }),
536 @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),536 .register_quadruple => |pl| try w.print("{t}:{t}:{t}:{t}", .{ pl[3], pl[2], pl[1], pl[0] }),
537 }),537 .register_offset => |pl| try w.print("{t} + 0x{x}", .{ pl.reg, pl.off }),
538 .register_quadruple => |pl| try w.print("{s}:{s}:{s}:{s}", .{538 .register_overflow => |pl| try w.print("{t}:{t}", .{ pl.eflags, pl.reg }),
539 @tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),539 .register_mask => |pl| try w.print("mask({t},{f}):{c}{t}", .{
540 }),540 pl.info.kind,
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),
548 pl.info.scalar,541 pl.info.scalar,
549 @as(u8, if (pl.info.inverted) '!' else ' '),542 @as(u8, if (pl.info.inverted) '!' else ' '),
550 @tagName(pl.reg),543 pl.reg,
551 }),544 }),
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 }),
553 .indirect_load_frame => |pl| try w.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),546 .indirect_load_frame => |pl| try w.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),
554 .load_frame => |pl| try w.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),547 .load_frame => |pl| try w.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),
555 .lea_frame => |pl| try w.print("{f} + 0x{x}", .{ pl.index, pl.off }),548 .lea_frame => |pl| try w.print("{f} + 0x{x}", .{ pl.index, pl.off }),
556 .load_nav => |pl| try w.print("[nav:{d}]", .{@intFromEnum(pl)}),549 .load_nav => |pl| try w.print("[nav:{d}]", .{pl}),
557 .lea_nav => |pl| try w.print("nav:{d}", .{@intFromEnum(pl)}),550 .lea_nav => |pl| try w.print("nav:{d}", .{pl}),
558 .load_uav => |pl| try w.print("[uav:{d}]", .{@intFromEnum(pl.val)}),551 .load_uav => |pl| try w.print("[uav:{d}]", .{pl.val}),
559 .lea_uav => |pl| try w.print("uav:{d}", .{@intFromEnum(pl.val)}),552 .lea_uav => |pl| try w.print("uav:{d}", .{pl.val}),
560 .load_lazy_sym => |pl| try w.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),553 .load_lazy_sym => |pl| try w.print("[lazy:{t}:{d}]", .{ pl.kind, pl.key }),
561 .lea_lazy_sym => |pl| try w.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),554 .lea_lazy_sym => |pl| try w.print("lazy:{t}:{d}", .{ pl.kind, pl.key }),
562 .load_extern_func => |pl| try w.print("[extern:{d}]", .{@intFromEnum(pl)}),555 .load_extern_func => |pl| try w.print("[extern:{d}]", .{pl}),
563 .lea_extern_func => |pl| try w.print("extern:{d}", .{@intFromEnum(pl)}),556 .lea_extern_func => |pl| try w.print("extern:{d}", .{pl}),
564 .elementwise_args => |pl| try w.print("elementwise:{d}:[{f} + 0x{x}]", .{557 .elementwise_args => |pl| try w.print("elementwise:{d}:[{f} + 0x{x}]", .{
565 pl.regs, pl.frame_index, pl.frame_off,558 pl.regs, pl.frame_index, pl.frame_off,
566 }),559 }),
567 .reserved_frame => |pl| try w.print("(dead:{f})", .{pl}),560 .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}),
569 }562 }
570 }563 }
571};564};
...@@ -1138,7 +1131,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {...@@ -1138,7 +1131,7 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {
1138 if (first) {1131 if (first) {
1139 const ip = &data.self.pt.zcu.intern_pool;1132 const ip = &data.self.pt.zcu.intern_pool;
1140 const mir_inst = lower.mir.instructions.get(data.inst);1133 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});
1142 switch (mir_inst.ops) {1135 switch (mir_inst.ops) {
1143 else => unreachable,1136 else => unreachable,
1144 .pseudo_dbg_prologue_end_none,1137 .pseudo_dbg_prologue_end_none,
...@@ -2059,7 +2052,7 @@ fn gen(...@@ -2059,7 +2052,7 @@ fn gen(
2059 .{},2052 .{},
2060 );2053 );
2061 },2054 },
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}),
2063 };2056 };
20642057
2065 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);2058 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 {...@@ -4452,8 +4445,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4452 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },4445 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
4453 } },4446 } },
4454 } }) catch |err| switch (err) {4447 } }) catch |err| switch (err) {
4455 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{4448 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
4456 @tagName(air_tag),4449 air_tag,
4457 cg.typeOf(bin_op.lhs).fmt(pt),4450 cg.typeOf(bin_op.lhs).fmt(pt),
4458 ops[0].tracking(cg),4451 ops[0].tracking(cg),
4459 ops[1].tracking(cg),4452 ops[1].tracking(cg),
...@@ -4464,8 +4457,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -4464,8 +4457,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4464 else => unreachable,4457 else => unreachable,
4465 .add, .add_optimized => {},4458 .add, .add_optimized => {},
4466 .add_wrap => res[0].wrapInt(cg) catch |err| switch (err) {4459 .add_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
4467 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{4460 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
4468 @tagName(air_tag),4461 air_tag,
4469 cg.typeOf(bin_op.lhs).fmt(pt),4462 cg.typeOf(bin_op.lhs).fmt(pt),
4470 res[0].tracking(cg),4463 res[0].tracking(cg),
4471 }),4464 }),
...@@ -13029,8 +13022,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -13029,8 +13022,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
13029 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },13022 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
13030 } },13023 } },
13031 } }) catch |err| switch (err) {13024 } }) catch |err| switch (err) {
13032 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{13025 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
13033 @tagName(air_tag),13026 air_tag,
13034 cg.typeOf(bin_op.lhs).fmt(pt),13027 cg.typeOf(bin_op.lhs).fmt(pt),
13035 ops[0].tracking(cg),13028 ops[0].tracking(cg),
13036 ops[1].tracking(cg),13029 ops[1].tracking(cg),
...@@ -15203,8 +15196,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -15203,8 +15196,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
15203 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },15196 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
15204 } },15197 } },
15205 } }) catch |err| switch (err) {15198 } }) catch |err| switch (err) {
15206 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{15199 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
15207 @tagName(air_tag),15200 air_tag,
15208 cg.typeOf(bin_op.lhs).fmt(pt),15201 cg.typeOf(bin_op.lhs).fmt(pt),
15209 ops[0].tracking(cg),15202 ops[0].tracking(cg),
15210 ops[1].tracking(cg),15203 ops[1].tracking(cg),
...@@ -15215,8 +15208,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -15215,8 +15208,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
15215 else => unreachable,15208 else => unreachable,
15216 .sub, .sub_optimized => {},15209 .sub, .sub_optimized => {},
15217 .sub_wrap => res[0].wrapInt(cg) catch |err| switch (err) {15210 .sub_wrap => res[0].wrapInt(cg) catch |err| switch (err) {
15218 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{15211 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
15219 @tagName(air_tag),15212 air_tag,
15220 cg.typeOf(bin_op.lhs).fmt(pt),15213 cg.typeOf(bin_op.lhs).fmt(pt),
15221 res[0].tracking(cg),15214 res[0].tracking(cg),
15222 }),15215 }),
...@@ -22050,8 +22043,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -22050,8 +22043,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
22050 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },22043 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
22051 } },22044 } },
22052 } }) catch |err| switch (err) {22045 } }) catch |err| switch (err) {
22053 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{22046 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
22054 @tagName(air_tag),22047 air_tag,
22055 cg.typeOf(bin_op.lhs).fmt(pt),22048 cg.typeOf(bin_op.lhs).fmt(pt),
22056 ops[0].tracking(cg),22049 ops[0].tracking(cg),
22057 ops[1].tracking(cg),22050 ops[1].tracking(cg),
...@@ -24987,8 +24980,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -24987,8 +24980,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
24987 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },24980 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
24988 } },24981 } },
24989 } }) catch |err| switch (err) {24982 } }) catch |err| switch (err) {
24990 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{24983 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
24991 @tagName(air_tag),24984 air_tag,
24992 ty.fmt(pt),24985 ty.fmt(pt),
24993 ops[0].tracking(cg),24986 ops[0].tracking(cg),
24994 ops[1].tracking(cg),24987 ops[1].tracking(cg),
...@@ -26785,8 +26778,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26785,8 +26778,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26785 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },26778 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
26786 } },26779 } },
26787 } }) catch |err| switch (err) {26780 } }) catch |err| switch (err) {
26788 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{26781 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
26789 @tagName(air_tag),26782 air_tag,
26790 ty.fmt(pt),26783 ty.fmt(pt),
26791 ops[0].tracking(cg),26784 ops[0].tracking(cg),
26792 ops[1].tracking(cg),26785 ops[1].tracking(cg),
...@@ -26794,8 +26787,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -26794,8 +26787,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
26794 else => |e| return e,26787 else => |e| return e,
26795 };26788 };
26796 res[0].wrapInt(cg) catch |err| switch (err) {26789 res[0].wrapInt(cg) catch |err| switch (err) {
26797 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{26790 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
26798 @tagName(air_tag),26791 air_tag,
26799 cg.typeOf(bin_op.lhs).fmt(pt),26792 cg.typeOf(bin_op.lhs).fmt(pt),
26800 res[0].tracking(cg),26793 res[0].tracking(cg),
26801 }),26794 }),
...@@ -32010,8 +32003,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -32010,8 +32003,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
32010 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp3q, ._, ._ },32003 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp3q, ._, ._ },
32011 } },32004 } },
32012 } }) catch |err| switch (err) {32005 } }) catch |err| switch (err) {
32013 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{32006 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
32014 @tagName(air_tag),32007 air_tag,
32015 cg.typeOf(bin_op.lhs).fmt(pt),32008 cg.typeOf(bin_op.lhs).fmt(pt),
32016 ops[0].tracking(cg),32009 ops[0].tracking(cg),
32017 ops[1].tracking(cg),32010 ops[1].tracking(cg),
...@@ -33248,8 +33241,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -33248,8 +33241,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
33248 assert(air_tag == .div_exact);33241 assert(air_tag == .div_exact);
33249 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;33242 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
33250 }) catch |err| switch (err) {33243 }) catch |err| switch (err) {
33251 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{33244 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
33252 @tagName(air_tag),33245 air_tag,
33253 ty.fmt(pt),33246 ty.fmt(pt),
33254 ops[0].tracking(cg),33247 ops[0].tracking(cg),
33255 ops[1].tracking(cg),33248 ops[1].tracking(cg),
...@@ -34705,8 +34698,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -34705,8 +34698,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
34705 } }) else err: {34698 } }) else err: {
34706 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;34699 res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err;
34707 }) catch |err| switch (err) {34700 }) catch |err| switch (err) {
34708 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{34701 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
34709 @tagName(air_tag),34702 air_tag,
34710 ty.fmt(pt),34703 ty.fmt(pt),
34711 ops[0].tracking(cg),34704 ops[0].tracking(cg),
34712 ops[1].tracking(cg),34705 ops[1].tracking(cg),
...@@ -36266,8 +36259,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -36266,8 +36259,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
36266 } },36259 } },
36267 } },36260 } },
36268 }) catch |err| switch (err) {36261 }) catch |err| switch (err) {
36269 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{36262 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
36270 @tagName(air_tag),36263 air_tag,
36271 cg.typeOf(bin_op.lhs).fmt(pt),36264 cg.typeOf(bin_op.lhs).fmt(pt),
36272 ops[0].tracking(cg),36265 ops[0].tracking(cg),
36273 ops[1].tracking(cg),36266 ops[1].tracking(cg),
...@@ -37958,8 +37951,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -37958,8 +37951,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
37958 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },37951 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
37959 } },37952 } },
37960 } })) catch |err| switch (err) {37953 } })) catch |err| switch (err) {
37961 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{37954 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
37962 @tagName(air_tag),37955 air_tag,
37963 ty.fmt(pt),37956 ty.fmt(pt),
37964 ops[0].tracking(cg),37957 ops[0].tracking(cg),
37965 ops[1].tracking(cg),37958 ops[1].tracking(cg),
...@@ -39740,8 +39733,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -39740,8 +39733,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
39740 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },39733 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
39741 } },39734 } },
39742 } }) catch |err| switch (err) {39735 } }) catch |err| switch (err) {
39743 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{39736 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
39744 @tagName(air_tag),39737 air_tag,
39745 cg.typeOf(bin_op.lhs).fmt(pt),39738 cg.typeOf(bin_op.lhs).fmt(pt),
39746 ops[0].tracking(cg),39739 ops[0].tracking(cg),
39747 ops[1].tracking(cg),39740 ops[1].tracking(cg),
...@@ -43253,8 +43246,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43253,8 +43246,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43253 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },43246 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
43254 } },43247 } },
43255 } }) catch |err| switch (err) {43248 } }) catch |err| switch (err) {
43256 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{43249 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43257 @tagName(air_tag),43250 air_tag,
43258 cg.typeOf(bin_op.lhs).fmt(pt),43251 cg.typeOf(bin_op.lhs).fmt(pt),
43259 ops[0].tracking(cg),43252 ops[0].tracking(cg),
43260 ops[1].tracking(cg),43253 ops[1].tracking(cg),
...@@ -43367,8 +43360,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43367,8 +43360,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43367 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },43360 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
43368 } },43361 } },
43369 } }) catch |err| switch (err) {43362 } }) catch |err| switch (err) {
43370 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{43363 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43371 @tagName(air_tag),43364 air_tag,
43372 cg.typeOf(bin_op.lhs).fmt(pt),43365 cg.typeOf(bin_op.lhs).fmt(pt),
43373 ops[0].tracking(cg),43366 ops[0].tracking(cg),
43374 ops[1].tracking(cg),43367 ops[1].tracking(cg),
...@@ -43496,8 +43489,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -43496,8 +43489,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
43496 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },43489 .{ ._, ._, .lea, .dst0p, .leai(.src0, .dst0), ._, ._ },
43497 } },43490 } },
43498 } }) catch |err| switch (err) {43491 } }) catch |err| switch (err) {
43499 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{43492 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
43500 @tagName(air_tag),43493 air_tag,
43501 cg.typeOf(bin_op.lhs).fmt(pt),43494 cg.typeOf(bin_op.lhs).fmt(pt),
43502 ops[0].tracking(cg),43495 ops[0].tracking(cg),
43503 ops[1].tracking(cg),43496 ops[1].tracking(cg),
...@@ -47805,8 +47798,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -47805,8 +47798,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
47805 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },47798 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
47806 } },47799 } },
47807 } }) catch |err| switch (err) {47800 } }) catch |err| switch (err) {
47808 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{47801 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
47809 @tagName(air_tag),47802 air_tag,
47810 cg.typeOf(bin_op.lhs).fmt(pt),47803 cg.typeOf(bin_op.lhs).fmt(pt),
47811 ops[0].tracking(cg),47804 ops[0].tracking(cg),
47812 ops[1].tracking(cg),47805 ops[1].tracking(cg),
...@@ -52108,8 +52101,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52108,8 +52101,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52108 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },52101 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
52109 } },52102 } },
52110 } }) catch |err| switch (err) {52103 } }) catch |err| switch (err) {
52111 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{52104 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
52112 @tagName(air_tag),52105 air_tag,
52113 cg.typeOf(bin_op.lhs).fmt(pt),52106 cg.typeOf(bin_op.lhs).fmt(pt),
52114 ops[0].tracking(cg),52107 ops[0].tracking(cg),
52115 ops[1].tracking(cg),52108 ops[1].tracking(cg),
...@@ -52957,8 +52950,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -52957,8 +52950,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
52957 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },52950 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
52958 } },52951 } },
52959 } }) catch |err| switch (err) {52952 } }) catch |err| switch (err) {
52960 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{52953 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
52961 @tagName(air_tag),52954 air_tag,
52962 ty_pl.ty.toType().fmt(pt),52955 ty_pl.ty.toType().fmt(pt),
52963 ops[0].tracking(cg),52956 ops[0].tracking(cg),
52964 ops[1].tracking(cg),52957 ops[1].tracking(cg),
...@@ -53862,8 +53855,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -53862,8 +53855,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
53862 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },53855 .{ ._, ._, .mov, .memad(.dst0q, .add_src0_size, -8), .tmp0q, ._, ._ },
53863 } },53856 } },
53864 } }) catch |err| switch (err) {53857 } }) catch |err| switch (err) {
53865 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{53858 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
53866 @tagName(air_tag),53859 air_tag,
53867 ty_pl.ty.toType().fmt(pt),53860 ty_pl.ty.toType().fmt(pt),
53868 ops[0].tracking(cg),53861 ops[0].tracking(cg),
53869 ops[1].tracking(cg),53862 ops[1].tracking(cg),
...@@ -57459,8 +57452,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -57459,8 +57452,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
57459 .{ ._, ._, .@"or", .tmp2q, .tmp1q, ._, ._ },57452 .{ ._, ._, .@"or", .tmp2q, .tmp1q, ._, ._ },
57460 } },57453 } },
57461 } }) catch |err| switch (err) {57454 } }) catch |err| switch (err) {
57462 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{57455 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
57463 @tagName(air_tag),57456 air_tag,
57464 ty_pl.ty.toType().fmt(pt),57457 ty_pl.ty.toType().fmt(pt),
57465 ops[0].tracking(cg),57458 ops[0].tracking(cg),
57466 ops[1].tracking(cg),57459 ops[1].tracking(cg),
...@@ -60804,8 +60797,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -60804,8 +60797,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
60804 .{ ._, ._, .@"or", .tmp4q, .tmp5q, ._, ._ },60797 .{ ._, ._, .@"or", .tmp4q, .tmp5q, ._, ._ },
60805 } },60798 } },
60806 } }) catch |err| switch (err) {60799 } }) catch |err| switch (err) {
60807 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{60800 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
60808 @tagName(air_tag),60801 air_tag,
60809 ty_pl.ty.toType().fmt(pt),60802 ty_pl.ty.toType().fmt(pt),
60810 ops[0].tracking(cg),60803 ops[0].tracking(cg),
60811 ops[1].tracking(cg),60804 ops[1].tracking(cg),
...@@ -61199,8 +61192,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -61199,8 +61192,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61199 } },61192 } },
61200 } },61193 } },
61201 }) catch |err| switch (err) {61194 }) catch |err| switch (err) {
61202 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{61195 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
61203 @tagName(air_tag),61196 air_tag,
61204 cg.typeOf(bin_op.lhs).fmt(pt),61197 cg.typeOf(bin_op.lhs).fmt(pt),
61205 ops[0].tracking(cg),61198 ops[0].tracking(cg),
61206 ops[1].tracking(cg),61199 ops[1].tracking(cg),
...@@ -61762,8 +61755,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -61762,8 +61755,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
61762 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },61755 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
61763 } },61756 } },
61764 } }) catch |err| switch (err) {61757 } }) catch |err| switch (err) {
61765 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{61758 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
61766 @tagName(air_tag),61759 air_tag,
61767 cg.typeOf(bin_op.lhs).fmt(pt),61760 cg.typeOf(bin_op.lhs).fmt(pt),
61768 cg.typeOf(bin_op.rhs).fmt(pt),61761 cg.typeOf(bin_op.rhs).fmt(pt),
61769 ops[0].tracking(cg),61762 ops[0].tracking(cg),
...@@ -62124,8 +62117,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -62124,8 +62117,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62124 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },62117 .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
62125 } },62118 } },
62126 } }) catch |err| switch (err) {62119 } }) catch |err| switch (err) {
62127 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{62120 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
62128 @tagName(air_tag),62121 air_tag,
62129 cg.typeOf(bin_op.lhs).fmt(pt),62122 cg.typeOf(bin_op.lhs).fmt(pt),
62130 cg.typeOf(bin_op.rhs).fmt(pt),62123 cg.typeOf(bin_op.rhs).fmt(pt),
62131 ops[0].tracking(cg),62124 ops[0].tracking(cg),
...@@ -62136,8 +62129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -62136,8 +62129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62136 switch (air_tag) {62129 switch (air_tag) {
62137 else => unreachable,62130 else => unreachable,
62138 .shl => res[0].wrapInt(cg) catch |err| switch (err) {62131 .shl => res[0].wrapInt(cg) catch |err| switch (err) {
62139 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{62132 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
62140 @tagName(air_tag),62133 air_tag,
62141 cg.typeOf(bin_op.lhs).fmt(pt),62134 cg.typeOf(bin_op.lhs).fmt(pt),
62142 res[0].tracking(cg),62135 res[0].tracking(cg),
62143 }),62136 }),
...@@ -62303,8 +62296,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -62303,8 +62296,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
62303 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },62296 .{ ._, ._, .@"or", .dst0d, .tmp0d, ._, ._ },
62304 } },62297 } },
62305 } }) catch |err| switch (err) {62298 } }) catch |err| switch (err) {
62306 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{62299 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
62307 @tagName(air_tag),62300 air_tag,
62308 cg.typeOf(bin_op.rhs).fmt(pt),62301 cg.typeOf(bin_op.rhs).fmt(pt),
62309 ops[1].tracking(cg),62302 ops[1].tracking(cg),
62310 }),62303 }),
...@@ -65560,8 +65553,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -65560,8 +65553,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
65560 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp1q, ._, ._ },65553 .{ .@"0:", ._, .mov, .memad(.dst0q, .add_size, -8), .tmp1q, ._, ._ },
65561 } },65554 } },
65562 } }) catch |err| switch (err) {65555 } }) catch |err| switch (err) {
65563 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{65556 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
65564 @tagName(air_tag),65557 air_tag,
65565 lhs_ty.fmt(pt),65558 lhs_ty.fmt(pt),
65566 ops[0].tracking(cg),65559 ops[0].tracking(cg),
65567 ops[1].tracking(cg),65560 ops[1].tracking(cg),
...@@ -67345,8 +67338,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -67345,8 +67338,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
67345 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },67338 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
67346 } },67339 } },
67347 } }) catch |err| switch (err) {67340 } }) catch |err| switch (err) {
67348 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{67341 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
67349 @tagName(air_tag),67342 air_tag,
67350 ty_op.ty.toType().fmt(pt),67343 ty_op.ty.toType().fmt(pt),
67351 ops[0].tracking(cg),67344 ops[0].tracking(cg),
67352 }),67345 }),
...@@ -70497,8 +70490,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -70497,8 +70490,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
70497 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },70490 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
70498 } },70491 } },
70499 } }) catch |err| switch (err) {70492 } }) catch |err| switch (err) {
70500 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{70493 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
70501 @tagName(air_tag),70494 air_tag,
70502 cg.typeOf(ty_op.operand).fmt(pt),70495 cg.typeOf(ty_op.operand).fmt(pt),
70503 ops[0].tracking(cg),70496 ops[0].tracking(cg),
70504 }),70497 }),
...@@ -70894,8 +70887,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -70894,8 +70887,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
70894 .{ .@"0:", ._, .lea, .dst0d, .leasia(.dst0, .@"8", .tmp0, .add_8_src0_size), ._, ._ },70887 .{ .@"0:", ._, .lea, .dst0d, .leasia(.dst0, .@"8", .tmp0, .add_8_src0_size), ._, ._ },
70895 } },70888 } },
70896 } }) catch |err| switch (err) {70889 } }) catch |err| switch (err) {
70897 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{70890 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
70898 @tagName(air_tag),70891 air_tag,
70899 cg.typeOf(ty_op.operand).fmt(pt),70892 cg.typeOf(ty_op.operand).fmt(pt),
70900 ops[0].tracking(cg),70893 ops[0].tracking(cg),
70901 }),70894 }),
...@@ -71782,8 +71775,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -71782,8 +71775,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
71782 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },71775 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
71783 } },71776 } },
71784 } }) catch |err| switch (err) {71777 } }) catch |err| switch (err) {
71785 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{71778 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
71786 @tagName(air_tag),71779 air_tag,
71787 cg.typeOf(ty_op.operand).fmt(pt),71780 cg.typeOf(ty_op.operand).fmt(pt),
71788 ops[0].tracking(cg),71781 ops[0].tracking(cg),
71789 }),71782 }),
...@@ -72431,8 +72424,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -72431,8 +72424,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
72431 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },72424 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
72432 } },72425 } },
72433 } }) catch |err| switch (err) {72426 } }) catch |err| switch (err) {
72434 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{72427 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
72435 @tagName(air_tag),72428 air_tag,
72436 ty_op.ty.toType().fmt(pt),72429 ty_op.ty.toType().fmt(pt),
72437 ops[0].tracking(cg),72430 ops[0].tracking(cg),
72438 }),72431 }),
...@@ -75533,8 +75526,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -75533,8 +75526,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
75533 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },75526 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
75534 } },75527 } },
75535 } }) catch |err| switch (err) {75528 } }) catch |err| switch (err) {
75536 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{75529 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
75537 @tagName(air_tag),75530 air_tag,
75538 ty_op.ty.toType().fmt(pt),75531 ty_op.ty.toType().fmt(pt),
75539 ops[0].tracking(cg),75532 ops[0].tracking(cg),
75540 }),75533 }),
...@@ -76595,8 +76588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -76595,8 +76588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
76595 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },76588 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
76596 } },76589 } },
76597 } }) catch |err| switch (err) {76590 } }) catch |err| switch (err) {
76598 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{76591 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
76599 @tagName(air_tag),76592 air_tag,
76600 cg.typeOf(un_op).fmt(pt),76593 cg.typeOf(un_op).fmt(pt),
76601 ops[0].tracking(cg),76594 ops[0].tracking(cg),
76602 }),76595 }),
...@@ -77445,8 +77438,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -77445,8 +77438,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
77445 } },77438 } },
77446 } },77439 } },
77447 }) catch |err| switch (err) {77440 }) catch |err| switch (err) {
77448 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{77441 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
77449 @tagName(air_tag),77442 air_tag,
77450 cg.typeOf(un_op).fmt(pt),77443 cg.typeOf(un_op).fmt(pt),
77451 ops[0].tracking(cg),77444 ops[0].tracking(cg),
77452 }),77445 }),
...@@ -78996,8 +78989,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -78996,8 +78989,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
78996 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },78989 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
78997 } },78990 } },
78998 } }) catch |err| switch (err) {78991 } }) catch |err| switch (err) {
78999 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{78992 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
79000 @tagName(air_tag),78993 air_tag,
79001 cg.typeOf(ty_op.operand).fmt(pt),78994 cg.typeOf(ty_op.operand).fmt(pt),
79002 ops[0].tracking(cg),78995 ops[0].tracking(cg),
79003 }),78996 }),
...@@ -80332,8 +80325,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80332,8 +80325,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80332 } },80325 } },
80333 } },80326 } },
80334 }) catch |err| switch (err) {80327 }) catch |err| switch (err) {
80335 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{80328 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
80336 @tagName(air_tag),80329 air_tag,
80337 cg.typeOf(un_op).fmt(pt),80330 cg.typeOf(un_op).fmt(pt),
80338 ops[0].tracking(cg),80331 ops[0].tracking(cg),
80339 }),80332 }),
...@@ -80872,8 +80865,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -80872,8 +80865,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
80872 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },80865 .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
80873 } },80866 } },
80874 } }) catch |err| switch (err) {80867 } }) catch |err| switch (err) {
80875 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{80868 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
80876 @tagName(air_tag),80869 air_tag,
80877 cg.typeOf(un_op).fmt(pt),80870 cg.typeOf(un_op).fmt(pt),
80878 ops[0].tracking(cg),80871 ops[0].tracking(cg),
80879 }),80872 }),
...@@ -81352,8 +81345,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -81352,8 +81345,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
81352 } else err: {81345 } else err: {
81353 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;81346 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
81354 }) catch |err| switch (err) {81347 }) catch |err| switch (err) {
81355 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{81348 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
81356 @tagName(air_tag),81349 air_tag,
81357 cg.typeOf(bin_op.lhs).fmt(pt),81350 cg.typeOf(bin_op.lhs).fmt(pt),
81358 ops[0].tracking(cg),81351 ops[0].tracking(cg),
81359 ops[1].tracking(cg),81352 ops[1].tracking(cg),
...@@ -81927,8 +81920,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -81927,8 +81920,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
81927 .@"struct", .@"union" => {81920 .@"struct", .@"union" => {
81928 assert(ty.containerLayout(zcu) == .@"packed");81921 assert(ty.containerLayout(zcu) == .@"packed");
81929 for (&ops) |*op| op.wrapInt(cg) catch |err| switch (err) {81922 for (&ops) |*op| op.wrapInt(cg) catch |err| switch (err) {
81930 error.SelectFailed => return cg.fail("failed to select {s} wrap {f} {f}", .{81923 error.SelectFailed => return cg.fail("failed to select {t} wrap {f} {f}", .{
81931 @tagName(air_tag),81924 air_tag,
81932 ty.fmt(pt),81925 ty.fmt(pt),
81933 op.tracking(cg),81926 op.tracking(cg),
81934 }),81927 }),
...@@ -81939,8 +81932,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -81939,8 +81932,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
81939 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;81932 res[0] = ops[0].cmpInts(cmp_op, &ops[1], cg) catch |err| break :err err;
81940 },81933 },
81941 }) catch |err| switch (err) {81934 }) catch |err| switch (err) {
81942 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{81935 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
81943 @tagName(air_tag),81936 air_tag,
81944 ty.fmt(pt),81937 ty.fmt(pt),
81945 ops[0].tracking(cg),81938 ops[0].tracking(cg),
81946 ops[1].tracking(cg),81939 ops[1].tracking(cg),
...@@ -89017,9 +89010,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -89017,9 +89010,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
89017 } },89010 } },
89018 }),89011 }),
89019 }) catch |err| switch (err) {89012 }) catch |err| switch (err) {
89020 error.SelectFailed => return cg.fail("failed to select {s} {s} {f} {f} {f}", .{89013 error.SelectFailed => return cg.fail("failed to select {t} {t} {f} {f} {f}", .{
89021 @tagName(air_tag),89014 air_tag,
89022 @tagName(vector_cmp.compareOperator()),89015 vector_cmp.compareOperator(),
89023 cg.typeOf(vector_cmp.lhs).fmt(pt),89016 cg.typeOf(vector_cmp.lhs).fmt(pt),
89024 ops[0].tracking(cg),89017 ops[0].tracking(cg),
89025 ops[1].tracking(cg),89018 ops[1].tracking(cg),
...@@ -91595,8 +91588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -91595,8 +91588,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
91595 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },91588 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
91596 } },91589 } },
91597 } }) catch |err| switch (err) {91590 } }) catch |err| switch (err) {
91598 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{91591 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
91599 @tagName(air_tag),91592 air_tag,
91600 ty_op.ty.toType().fmt(pt),91593 ty_op.ty.toType().fmt(pt),
91601 cg.typeOf(ty_op.operand).fmt(pt),91594 cg.typeOf(ty_op.operand).fmt(pt),
91602 ops[0].tracking(cg),91595 ops[0].tracking(cg),
...@@ -93270,8 +93263,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -93270,8 +93263,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
93270 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },93263 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
93271 } },93264 } },
93272 } }) catch |err| switch (err) {93265 } }) catch |err| switch (err) {
93273 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{93266 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
93274 @tagName(air_tag),93267 air_tag,
93275 ty_op.ty.toType().fmt(pt),93268 ty_op.ty.toType().fmt(pt),
93276 cg.typeOf(ty_op.operand).fmt(pt),93269 cg.typeOf(ty_op.operand).fmt(pt),
93277 ops[0].tracking(cg),93270 ops[0].tracking(cg),
...@@ -98028,8 +98021,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -98028,8 +98021,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
98028 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },98021 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
98029 } },98022 } },
98030 } }) catch |err| switch (err) {98023 } }) catch |err| switch (err) {
98031 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{98024 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
98032 @tagName(air_tag),98025 air_tag,
98033 dst_ty.fmt(pt),98026 dst_ty.fmt(pt),
98034 src_ty.fmt(pt),98027 src_ty.fmt(pt),
98035 ops[0].tracking(cg),98028 ops[0].tracking(cg),
...@@ -103694,8 +103687,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103694,8 +103687,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103694 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },103687 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
103695 } },103688 } },
103696 } }) catch |err| switch (err) {103689 } }) catch |err| switch (err) {
103697 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{103690 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103698 @tagName(air_tag),103691 air_tag,
103699 ty_op.ty.toType().fmt(pt),103692 ty_op.ty.toType().fmt(pt),
103700 cg.typeOf(ty_op.operand).fmt(pt),103693 cg.typeOf(ty_op.operand).fmt(pt),
103701 ops[0].tracking(cg),103694 ops[0].tracking(cg),
...@@ -103835,8 +103828,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103835,8 +103828,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103835 const restricted_ty = cg.typeOf(ty_op.operand);103828 const restricted_ty = cg.typeOf(ty_op.operand);
103836 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});103829 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
103837 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {103830 const res = res: switch (restricted_ty.restrictedRepr(zcu)) {
103838 .double_pointer => {103831 .indirect => {
103839 switch (air_tag) {103832 if (zcu.comp.config.use_new_linker) switch (air_tag) {
103840 else => unreachable,103833 else => unreachable,
103841 .unwrap_restricted => {},103834 .unwrap_restricted => {},
103842 .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{103835 .unwrap_restricted_safe => cg.select(&.{}, &.{}, &ops, &.{ .{
...@@ -103848,7 +103841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103848,7 +103841,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103848 .call_frame = .{ .alignment = .@"32" },103841 .call_frame = .{ .alignment = .@"32" },
103849 .extra_temps = .{103842 .extra_temps = .{
103850 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103843 .{ .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 } } },
103852 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103845 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103853 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },103846 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103854 .unused,103847 .unused,
...@@ -103878,7 +103871,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103878,7 +103871,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103878 .call_frame = .{ .alignment = .@"16" },103871 .call_frame = .{ .alignment = .@"16" },
103879 .extra_temps = .{103872 .extra_temps = .{
103880 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103873 .{ .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 } } },
103882 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103875 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103883 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },103876 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103884 .unused,103877 .unused,
...@@ -103907,7 +103900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103907,7 +103900,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103907 .call_frame = .{ .alignment = .@"8" },103900 .call_frame = .{ .alignment = .@"8" },
103908 .extra_temps = .{103901 .extra_temps = .{
103909 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103902 .{ .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 } } },
103911 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },103904 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
103912 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },103905 .{ .type = .usize, .kind = .{ .panic_func = .corrupt_restricted_pointer } },
103913 .unused,103906 .unused,
...@@ -103929,18 +103922,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -103929,18 +103922,18 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103929 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },103922 .{ ._, ._, .call, .tmp3d, ._, ._, ._ },
103930 } },103923 } },
103931 } }) catch |err| switch (err) {103924 } }) catch |err| switch (err) {
103932 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{103925 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
103933 @tagName(air_tag),103926 air_tag,
103934 unrestricted_ty.fmt(pt),103927 unrestricted_ty.fmt(pt),
103935 restricted_ty.fmt(pt),103928 restricted_ty.fmt(pt),
103936 ops[0].tracking(cg),103929 ops[0].tracking(cg),
103937 }),103930 }),
103938 else => |e| return e,103931 else => |e| return e,
103939 },103932 },
103940 }103933 };
103941 break :res try ops[0].load(unrestricted_ty, .{}, cg);103934 break :res try ops[0].load(unrestricted_ty, .{}, cg);
103942 },103935 },
103943 .single_pointer => ops[0],103936 .direct => ops[0],
103944 };103937 };
103945 try res.finish(inst, &.{ty_op.operand}, &ops, cg);103938 try res.finish(inst, &.{ty_op.operand}, &ops, cg);
103946 },103939 },
...@@ -115178,8 +115171,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -115178,8 +115171,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
115178 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },115171 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
115179 } },115172 } },
115180 } }) catch |err| switch (err) {115173 } }) catch |err| switch (err) {
115181 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{115174 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
115182 @tagName(air_tag),115175 air_tag,
115183 ty_op.ty.toType().fmt(pt),115176 ty_op.ty.toType().fmt(pt),
115184 cg.typeOf(ty_op.operand).fmt(pt),115177 cg.typeOf(ty_op.operand).fmt(pt),
115185 ops[0].tracking(cg),115178 ops[0].tracking(cg),
...@@ -127197,8 +127190,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -127197,8 +127190,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
127197 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },127190 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
127198 } },127191 } },
127199 } }) catch |err| switch (err) {127192 } }) catch |err| switch (err) {
127200 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f}", .{127193 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f}", .{
127201 @tagName(air_tag),127194 air_tag,
127202 ty_op.ty.toType().fmt(pt),127195 ty_op.ty.toType().fmt(pt),
127203 cg.typeOf(ty_op.operand).fmt(pt),127196 cg.typeOf(ty_op.operand).fmt(pt),
127204 ops[0].tracking(cg),127197 ops[0].tracking(cg),
...@@ -161387,9 +161380,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161387,9 +161380,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161387 } },161380 } },
161388 } },161381 } },
161389 }) catch |err| switch (err) {161382 }) catch |err| switch (err) {
161390 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{161383 error.SelectFailed => return cg.fail("failed to select {t}.{t} {f} {f}", .{
161391 @tagName(air_tag),161384 air_tag,
161392 @tagName(reduce.operation),161385 reduce.operation,
161393 cg.typeOf(reduce.operand).fmt(pt),161386 cg.typeOf(reduce.operand).fmt(pt),
161394 ops[0].tracking(cg),161387 ops[0].tracking(cg),
161395 }),161388 }),
...@@ -161398,9 +161391,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -161398,9 +161391,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
161398 switch (reduce.operation) {161391 switch (reduce.operation) {
161399 .And, .Or, .Xor, .Min, .Max => {},161392 .And, .Or, .Xor, .Min, .Max => {},
161400 .Add, .Mul => if (cg.intInfo(res_ty)) |_| res[0].wrapInt(cg) catch |err| switch (err) {161393 .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}", .{161394 error.SelectFailed => return cg.fail("failed to select {t}.{t} wrap {f} {f}", .{
161402 @tagName(air_tag),161395 air_tag,
161403 @tagName(reduce.operation),161396 reduce.operation,
161404 res_ty.fmt(pt),161397 res_ty.fmt(pt),
161405 res[0].tracking(cg),161398 res[0].tracking(cg),
161406 }),161399 }),
...@@ -169101,9 +169094,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -169101,9 +169094,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
169101 } },169094 } },
169102 } },169095 } },
169103 }) catch |err| switch (err) {169096 }) catch |err| switch (err) {
169104 error.SelectFailed => return cg.fail("failed to select {s}.{s} {f} {f}", .{169097 error.SelectFailed => return cg.fail("failed to select {t}.{t} {f} {f}", .{
169105 @tagName(air_tag),169098 air_tag,
169106 @tagName(reduce.operation),169099 reduce.operation,
169107 cg.typeOf(reduce.operand).fmt(pt),169100 cg.typeOf(reduce.operand).fmt(pt),
169108 ops[0].tracking(cg),169101 ops[0].tracking(cg),
169109 }),169102 }),
...@@ -170898,8 +170891,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -170898,8 +170891,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170898 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },170891 .{ ._, ._nz, .j, .@"0b", ._, ._, ._ },
170899 } },170892 } },
170900 } }) catch |err| switch (err) {170893 } }) catch |err| switch (err) {
170901 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{170894 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
170902 @tagName(air_tag),170895 air_tag,
170903 ty_op.ty.toType().fmt(pt),170896 ty_op.ty.toType().fmt(pt),
170904 ops[0].tracking(cg),170897 ops[0].tracking(cg),
170905 }),170898 }),
...@@ -170914,8 +170907,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -170914,8 +170907,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170914 const bin_op = air_datas[@intFromEnum(inst)].bin_op;170907 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
170915 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }) ++ .{undefined};170908 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs }) ++ .{undefined};
170916 ops[2] = ops[0].getByteLen(cg) catch |err| switch (err) {170909 ops[2] = ops[0].getByteLen(cg) catch |err| switch (err) {
170917 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{170910 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
170918 @tagName(air_tag),170911 air_tag,
170919 cg.typeOf(bin_op.lhs).fmt(pt),170912 cg.typeOf(bin_op.lhs).fmt(pt),
170920 cg.typeOf(bin_op.rhs).fmt(pt),170913 cg.typeOf(bin_op.rhs).fmt(pt),
170921 ops[0].tracking(cg),170914 ops[0].tracking(cg),
...@@ -170955,8 +170948,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -170955,8 +170948,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
170955 } },170948 } },
170956 }},170949 }},
170957 }) catch |err| switch (err) {170950 }) catch |err| switch (err) {
170958 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f} {f}", .{170951 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f} {f}", .{
170959 @tagName(air_tag),170952 air_tag,
170960 cg.typeOf(bin_op.lhs).fmt(pt),170953 cg.typeOf(bin_op.lhs).fmt(pt),
170961 cg.typeOf(bin_op.rhs).fmt(pt),170954 cg.typeOf(bin_op.rhs).fmt(pt),
170962 ops[0].tracking(cg),170955 ops[0].tracking(cg),
...@@ -171136,8 +171129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171136,8 +171129,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171136 .{ ._, ._, .@"test", .tmp0p, .tmp0p, ._, ._ },171129 .{ ._, ._, .@"test", .tmp0p, .tmp0p, ._, ._ },
171137 } },171130 } },
171138 } }) catch |err| switch (err) {171131 } }) catch |err| switch (err) {
171139 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{171132 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171140 @tagName(air_tag),171133 air_tag,
171141 cg.typeOf(un_op).fmt(pt),171134 cg.typeOf(un_op).fmt(pt),
171142 ops[0].tracking(cg),171135 ops[0].tracking(cg),
171143 }),171136 }),
...@@ -171302,8 +171295,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171302,8 +171295,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171302 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },171295 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
171303 } },171296 } },
171304 } }) catch |err| switch (err) {171297 } }) catch |err| switch (err) {
171305 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{171298 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171306 @tagName(air_tag),171299 air_tag,
171307 cg.typeOf(un_op).fmt(pt),171300 cg.typeOf(un_op).fmt(pt),
171308 ops[0].tracking(cg),171301 ops[0].tracking(cg),
171309 }),171302 }),
...@@ -171323,7 +171316,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171323,7 +171316,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171323 .{ .src = .{ .to_gpr, .none, .none } },171316 .{ .src = .{ .to_gpr, .none, .none } },
171324 },171317 },
171325 .extra_temps = .{171318 .extra_temps = .{
171326 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },171319 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171327 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },171320 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171328 .unused,171321 .unused,
171329 .unused,171322 .unused,
...@@ -171352,7 +171345,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171352,7 +171345,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171352 .{ .src = .{ .to_gpr, .none, .none } },171345 .{ .src = .{ .to_gpr, .none, .none } },
171353 },171346 },
171354 .extra_temps = .{171347 .extra_temps = .{
171355 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },171348 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171356 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },171349 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171357 .unused,171350 .unused,
171358 .unused,171351 .unused,
...@@ -171381,7 +171374,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171381,7 +171374,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171381 .{ .src = .{ .to_gpr, .none, .none } },171374 .{ .src = .{ .to_gpr, .none, .none } },
171382 },171375 },
171383 .extra_temps = .{171376 .extra_temps = .{
171384 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },171377 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
171385 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },171378 .{ .type = .u32, .kind = .{ .mut_rc = .{ .ref = .src0, .rc = .general_purpose } } },
171386 .unused,171379 .unused,
171387 .unused,171380 .unused,
...@@ -171404,8 +171397,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171404,8 +171397,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171404 .{ ._, ._, .lea, .dst1d, .leai(.dst1, .tmp1), ._, ._ },171397 .{ ._, ._, .lea, .dst1d, .leai(.dst1, .tmp1), ._, ._ },
171405 } },171398 } },
171406 } }) catch |err| switch (err) {171399 } }) catch |err| switch (err) {
171407 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{171400 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171408 @tagName(air_tag),171401 air_tag,
171409 cg.typeOf(un_op).fmt(pt),171402 cg.typeOf(un_op).fmt(pt),
171410 ops[0].tracking(cg),171403 ops[0].tracking(cg),
171411 }),171404 }),
...@@ -171422,6 +171415,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171422,6 +171415,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171422 },171415 },
171423 .error_set_has_value => |air_tag| {171416 .error_set_has_value => |air_tag| {
171424 const ty_op = air_datas[@intFromEnum(inst)].ty_op;171417 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
171418 assert(ty_op.ty != .anyerror_type); // das a constant
171425 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}) ++ .{try cg.tempInit(ty_op.ty.toType(), .none)};171419 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand}) ++ .{try cg.tempInit(ty_op.ty.toType(), .none)};
171426 var res: [1]Temp = undefined;171420 var res: [1]Temp = undefined;
171427 cg.select(&res, &.{.bool}, &ops, comptime &.{ .{171421 cg.select(&res, &.{.bool}, &ops, comptime &.{ .{
...@@ -171502,8 +171496,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171502,8 +171496,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171502 .{ ._, ._, .@"test", .src0d, .src0d, ._, ._ },171496 .{ ._, ._, .@"test", .src0d, .src0d, ._, ._ },
171503 } },171497 } },
171504 } }) catch |err| switch (err) {171498 } }) catch |err| switch (err) {
171505 error.SelectFailed => return cg.fail("failed to select {s} {f} {f}", .{171499 error.SelectFailed => return cg.fail("failed to select {t} {f} {f}", .{
171506 @tagName(air_tag),171500 air_tag,
171507 ty_op.ty.toType().fmt(pt),171501 ty_op.ty.toType().fmt(pt),
171508 ops[0].tracking(cg),171502 ops[0].tracking(cg),
171509 }),171503 }),
...@@ -171575,8 +171569,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -171575,8 +171569,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171575 }171569 }
171576 }171570 }
171577 },171571 },
171578 else => return cg.fail("failed to select {s} {f}", .{171572 else => return cg.fail("failed to select {t} {f}", .{
171579 @tagName(air_tag),171573 air_tag,
171580 agg_ty.fmt(pt),171574 agg_ty.fmt(pt),
171581 }),171575 }),
171582 }171576 }
...@@ -173021,8 +173015,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173021,8 +173015,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173021 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },173015 .{ ._, ._ae, .j, .@"0b", ._, ._, ._ },
173022 } },173016 } },
173023 } }) catch |err| switch (err) {173017 } }) catch |err| switch (err) {
173024 error.SelectFailed => return cg.fail("failed to select {s} {f} {f} {f} {f}", .{173018 error.SelectFailed => return cg.fail("failed to select {t} {f} {f} {f} {f}", .{
173025 @tagName(air_tag),173019 air_tag,
173026 cg.typeOf(bin_op.lhs).fmt(pt),173020 cg.typeOf(bin_op.lhs).fmt(pt),
173027 ops[0].tracking(cg),173021 ops[0].tracking(cg),
173028 ops[1].tracking(cg),173022 ops[1].tracking(cg),
...@@ -173055,7 +173049,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173055,7 +173049,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173055 .{ .src = .{ .to_gpr, .none, .none } },173049 .{ .src = .{ .to_gpr, .none, .none } },
173056 },173050 },
173057 .extra_temps = .{173051 .extra_temps = .{
173058 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },173052 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173059 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },173053 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173060 .unused,173054 .unused,
173061 .unused,173055 .unused,
...@@ -173079,7 +173073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173079,7 +173073,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173079 .{ .src = .{ .to_gpr, .none, .none } },173073 .{ .src = .{ .to_gpr, .none, .none } },
173080 },173074 },
173081 .extra_temps = .{173075 .extra_temps = .{
173082 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },173076 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173083 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },173077 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173084 .unused,173078 .unused,
173085 .unused,173079 .unused,
...@@ -173103,7 +173097,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173103,7 +173097,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173103 .{ .src = .{ .to_gpr, .none, .none } },173097 .{ .src = .{ .to_gpr, .none, .none } },
173104 },173098 },
173105 .extra_temps = .{173099 .extra_temps = .{
173106 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .const_data } } },173100 .{ .type = .anyerror, .kind = .{ .lazy_sym = .{ .kind = .deferred_const_data } } },
173107 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },173101 .{ .type = .usize, .kind = .{ .rc = .general_purpose } },
173108 .unused,173102 .unused,
173109 .unused,173103 .unused,
...@@ -173122,8 +173116,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {...@@ -173122,8 +173116,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
173122 .{ ._, ._, .cmp, .src0d, .lea(.tmp1d), ._, ._ },173116 .{ ._, ._, .cmp, .src0d, .lea(.tmp1d), ._, ._ },
173123 } },173117 } },
173124 } }) catch |err| switch (err) {173118 } }) catch |err| switch (err) {
173125 error.SelectFailed => return cg.fail("failed to select {s} {f}", .{173119 error.SelectFailed => return cg.fail("failed to select {t} {f}", .{
173126 @tagName(air_tag),173120 air_tag,
173127 ops[0].tracking(cg),173121 ops[0].tracking(cg),
173128 }),173122 }),
173129 else => |e| return e,173123 else => |e| return e,
...@@ -173856,9 +173850,9 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173856,9 +173850,9 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173856 const pt = cg.pt;173850 const pt = cg.pt;
173857 const zcu = pt.zcu;173851 const zcu = pt.zcu;
173858 const ip = &zcu.intern_pool;173852 const ip = &zcu.intern_pool;
173859 switch (ip.indexToKey(lazy_sym.ty)) {173853 switch (ip.indexToKey(lazy_sym.key)) {
173860 .enum_type => {173854 .enum_type => {
173861 const enum_ty: Type = .fromInterned(lazy_sym.ty);173855 const enum_ty: Type = .fromInterned(lazy_sym.key);
173862 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});173856 wip_mir_log.debug("{f}.@tagName:", .{enum_ty.fmt(pt)});
173863173857
173864 const ret_regs = abi.getCAbiIntReturnRegs(.auto)[0..2].*;173858 const ret_regs = abi.getCAbiIntReturnRegs(.auto)[0..2].*;
...@@ -173875,12 +173869,12 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173875,12 +173869,12 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173875 const data_lock = cg.register_manager.lockRegAssumeUnused(data_reg);173869 const data_lock = cg.register_manager.lockRegAssumeUnused(data_reg);
173876 defer cg.register_manager.unlockReg(data_lock);173870 defer cg.register_manager.unlockReg(data_lock);
173877 try cg.asmRegisterMemory(.{ ._, .lea }, data_reg.to64(), .{173871 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 } },
173879 });173873 });
173880173874
173881 var data_off: i32 = 0;173875 var data_off: i32 = 0;
173882 const reset_index = cg.next_temp_index;173876 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;
173884 for (0..tag_names.len) |tag_index| {173878 for (0..tag_names.len) |tag_index| {
173885 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {173879 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {
173886 else => unreachable,173880 else => unreachable,
...@@ -173919,7 +173913,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173919,7 +173913,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173919 try cg.asmOpOnly(.{ ._, .ret });173913 try cg.asmOpOnly(.{ ._, .ret });
173920 },173914 },
173921 .error_set_type => |error_set_type| {173915 .error_set_type => |error_set_type| {
173922 const err_ty: Type = .fromInterned(lazy_sym.ty);173916 const err_ty: Type = .fromInterned(lazy_sym.key);
173923 wip_mir_log.debug("{f}.@errorCast:", .{err_ty.fmt(pt)});173917 wip_mir_log.debug("{f}.@errorCast:", .{err_ty.fmt(pt)});
173924173918
173925 const ret_reg = abi.getCAbiIntReturnRegs(.auto)[0];173919 const ret_reg = abi.getCAbiIntReturnRegs(.auto)[0];
...@@ -173964,8 +173958,8 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173964,8 +173958,8 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173964 try cg.asmOpOnly(.{ ._, .ret });173958 try cg.asmOpOnly(.{ ._, .ret });
173965 },173959 },
173966 else => return cg.fail(173960 else => return cg.fail(
173967 "TODO implement {s} for {f}",173961 "TODO implement {t} for {f}",
173968 .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) },173962 .{ lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt) },
173969 ),173963 ),
173970 }173964 }
173971 try cg.resetTemps(@enumFromInt(0));173965 try cg.resetTemps(@enumFromInt(0));
...@@ -175315,10 +175309,7 @@ fn genShiftBinOpMir(...@@ -175315,10 +175309,7 @@ fn genShiftBinOpMir(
175315 .mod = .{ .rm = .{175309 .mod = .{ .rm = .{
175316 .size = .fromSize(abi_size),175310 .size = .fromSize(abi_size),
175317 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse175311 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
175318 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{175312 return self.fail("TODO genShiftBinOpMir between {t} and {t}", .{ lhs_mcv, shift_mcv }),
175319 @tagName(lhs_mcv),
175320 @tagName(shift_mcv),
175321 }),
175322 } },175313 } },
175323 },175314 },
175324 .indirect => |reg_off| .{175315 .indirect => |reg_off| .{
...@@ -175349,10 +175340,7 @@ fn genShiftBinOpMir(...@@ -175349,10 +175340,7 @@ fn genShiftBinOpMir(
175349 },175340 },
175350 else => {},175341 else => {},
175351 }175342 }
175352 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{175343 return self.fail("TODO genShiftBinOpMir between {t} and {t}", .{ lhs_mcv, shift_mcv });
175353 @tagName(lhs_mcv),
175354 @tagName(shift_mcv),
175355 });
175356}175344}
175357175345
175358fn genBinOpMir(175346fn genBinOpMir(
...@@ -175401,9 +175389,7 @@ fn genBinOpMir(...@@ -175401,9 +175389,7 @@ fn genBinOpMir(
175401 .add => .{ ._, .adc },175389 .add => .{ ._, .adc },
175402 .sub, .cmp => .{ ._, .sbb },175390 .sub, .cmp => .{ ._, .sbb },
175403 .@"or", .@"and", .xor => mir_tag,175391 .@"or", .@"and", .xor => mir_tag,
175404 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{175392 else => return self.fail("TODO genBinOpMir implement large ABI for {t}", .{mir_tag[1]}),
175405 @tagName(mir_tag[1]),
175406 }),
175407 },175393 },
175408 else => unreachable,175394 else => unreachable,
175409 };175395 };
...@@ -175652,9 +175638,7 @@ fn genBinOpMir(...@@ -175652,9 +175638,7 @@ fn genBinOpMir(
175652 .add => .{ ._, .adc },175638 .add => .{ ._, .adc },
175653 .sub, .cmp => .{ ._, .sbb },175639 .sub, .cmp => .{ ._, .sbb },
175654 .@"or", .@"and", .xor => mir_tag,175640 .@"or", .@"and", .xor => mir_tag,
175655 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{175641 else => return self.fail("TODO genBinOpMir implement large ABI for {t}", .{mir_tag[1]}),
175656 @tagName(mir_tag[1]),
175657 }),
175658 },175642 },
175659 };175643 };
175660 const dst_limb_mem: Memory = switch (dst_mcv) {175644 const dst_limb_mem: Memory = switch (dst_mcv) {
...@@ -176527,7 +176511,7 @@ fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {...@@ -176527,7 +176511,7 @@ fn genCondBrMir(self: *CodeGen, ty: Type, mcv: MCValue) !Mir.Inst.Index {
176527 }176511 }
176528 return self.fail("TODO implement condbr when condition is {f} with abi larger than 8 bytes", .{mcv});176512 return self.fail("TODO implement condbr when condition is {f} with abi larger than 8 bytes", .{mcv});
176529 },176513 },
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}),
176531 }176515 }
176532}176516}
176533176517
...@@ -177551,10 +177535,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177551,10 +177535,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177551 label_gop.value_ptr.target = @intCast(self.mir_instructions.len);177535 label_gop.value_ptr.target = @intCast(self.mir_instructions.len);
177552 } else continue;177536 } else continue;
177553 if (mnem_str[0] == '.') {177537 if (mnem_str[0] == '.') {
177554 if (prefix != .none) return self.fail("prefixed directive: '{s} {s}'", .{177538 if (prefix != .none) return self.fail("prefixed directive: '{t} {s}'", .{ prefix, mnem_str });
177555 @tagName(prefix),
177556 mnem_str,
177557 });
177558 prefix = .directive;177539 prefix = .directive;
177559 }177540 }
177560177541
...@@ -177871,8 +177852,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177871,8 +177852,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177871 inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|177852 inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem|
177872 max_mnem_len = @max(mnem.name.len, max_mnem_len);177853 max_mnem_len = @max(mnem.name.len, max_mnem_len);
177873 var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;177854 var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined;
177874 const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{177855 const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{t}{c}", .{
177875 @tagName(mnem_tag),177856 mnem_tag,
177876 @as(u8, switch (mnem_size.size) {177857 @as(u8, switch (mnem_size.size) {
177877 .byte => 'b',177858 .byte => 'b',
177878 .word => 'w',177859 .word => 'w',
...@@ -177908,9 +177889,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177908,9 +177889,7 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177908 ) orelse continue };177889 ) orelse continue };
177909 } else {177890 } else {
177910 assert(prefix != .none); // no combination of fixes produced a known mnemonic177891 assert(prefix != .none); // no combination of fixes produced a known mnemonic
177911 return self.fail("invalid prefix for mnemonic: '{s} {s}'", .{177892 return self.fail("invalid prefix for mnemonic: '{t} {s}'", .{ prefix, mnem_name });
177912 @tagName(prefix), mnem_name,
177913 });
177914 };177893 };
177915177894
177916 (if (prefix == .directive) switch (mnem_tag) {177895 (if (prefix == .directive) switch (mnem_tag) {
...@@ -177969,12 +177948,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -177969,12 +177948,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177969 .@".cfi_escape" => error.InvalidInstruction,177948 .@".cfi_escape" => error.InvalidInstruction,
177970 else => unreachable,177949 else => unreachable,
177971 } else self.asmOps(mnem_fixed_tag, ops)) catch |err| switch (err) {177950 } else self.asmOps(mnem_fixed_tag, ops)) catch |err| switch (err) {
177972 error.InvalidInstruction => return self.fail("invalid instruction: '{s} {s} {s} {s} {s}'", .{177951 error.InvalidInstruction => return self.fail("invalid instruction: '{s} {t} {t} {t} {t}'", .{
177973 mnem_str,177952 mnem_str, ops[0], ops[1], ops[2], ops[3],
177974 @tagName(ops[0]),
177975 @tagName(ops[1]),
177976 @tagName(ops[2]),
177977 @tagName(ops[3]),
177978 }),177953 }),
177979 else => |e| return e,177954 else => |e| return e,
177980 };177955 };
...@@ -178537,9 +178512,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C...@@ -178537,9 +178512,7 @@ fn genCopy(self: *CodeGen, ty: Type, dst_mcv: MCValue, src_mcv: MCValue, opts: C
178537 break :src_info .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };178512 break :src_info .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };
178538 },178513 },
178539 .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref), opts),178514 .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}", .{178515 else => return self.fail("TODO implement genCopy for {t} of {f}", .{ src_mcv, ty.fmt(pt) }),
178541 @tagName(src_mcv), ty.fmt(pt),
178542 }),
178543 };178516 };
178544 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);178517 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
178545178518
...@@ -179347,9 +179320,7 @@ fn genSetMem(...@@ -179347,9 +179320,7 @@ fn genSetMem(
179347 opts,179320 opts,
179348 );179321 );
179349 },179322 },
179350 else => return self.fail("TODO implement genSetMem for {s} of {f}", .{179323 else => return self.fail("TODO implement genSetMem for {t} of {f}", .{ src_mcv, ty.fmt(pt) }),
179351 @tagName(src_mcv), ty.fmt(pt),
179352 }),
179353 },179324 },
179354 .register_offset => |reg_off| {179325 .register_offset => |reg_off| {
179355 const src_reg = self.copyToTmpRegister(ty, src_mcv) catch |err| switch (err) {179326 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 {...@@ -179705,7 +179676,7 @@ fn airCmpxchg(self: *CodeGen, inst: Air.Inst.Index) !void {
179705 };179676 };
179706 switch (ptr_mem.mod) {179677 switch (ptr_mem.mod) {
179707 .rm => {},179678 .rm => {},
179708 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),179679 .off => return self.fail("TODO airCmpxchg with {t}", .{ptr_mcv}),
179709 }179680 }
179710 const ptr_lock = switch (ptr_mem.base) {179681 const ptr_lock = switch (ptr_mem.base) {
179711 .none, .frame, .nav, .uav => null,179682 .none, .frame, .nav, .uav => null,
...@@ -179788,7 +179759,7 @@ fn atomicOp(...@@ -179788,7 +179759,7 @@ fn atomicOp(
179788 };179759 };
179789 switch (ptr_mem.mod) {179760 switch (ptr_mem.mod) {
179790 .rm => {},179761 .rm => {},
179791 .off => return self.fail("TODO airCmpxchg with {s}", .{@tagName(ptr_mcv)}),179762 .off => return self.fail("TODO airCmpxchg with {t}", .{ptr_mcv}),
179792 }179763 }
179793 const mem_lock = switch (ptr_mem.base) {179764 const mem_lock = switch (ptr_mem.base) {
179794 .none, .frame, .nav, .uav => null,179765 .none, .frame, .nav, .uav => null,
...@@ -179883,8 +179854,8 @@ fn atomicOp(...@@ -179883,8 +179854,8 @@ fn atomicOp(
179883 else => null,179854 else => null,
179884 },179855 },
179885 else => unreachable,179856 else => unreachable,
179886 }) orelse return self.fail("TODO implement atomicOp of {s} for {f}", .{179857 }) orelse return self.fail("TODO implement atomicOp of {t} for {f}", .{
179887 @tagName(op), val_ty.fmt(pt),179858 op, val_ty.fmt(pt),
179888 });179859 });
179889 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});179860 try self.genSetReg(sse_reg, val_ty, .{ .register = .rax }, .{});
179890 switch (mir_tag[0]) {179861 switch (mir_tag[0]) {
...@@ -180952,7 +180923,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -180952,7 +180923,7 @@ fn airVaStart(self: *CodeGen, inst: Air.Inst.Index) !void {
180952 );180923 );
180953 break :result .{ .load_frame = .{ .index = dst_fi } };180924 break :result .{ .load_frame = .{ .index = dst_fi } };
180954 },180925 },
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}),
180956 };180927 };
180957 return self.finishAir(inst, result, .{ .none, .none, .none });180928 return self.finishAir(inst, result, .{ .none, .none, .none });
180958}180929}
...@@ -181139,7 +181110,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -181139,7 +181110,7 @@ fn airVaArg(self: *CodeGen, inst: Air.Inst.Index) !void {
181139 try self.convertFloatVarArg(inst, ty, promote_ty, promote_mcv);181110 try self.convertFloatVarArg(inst, ty, promote_ty, promote_mcv);
181140 break :result promote_mcv;181111 break :result promote_mcv;
181141 },181112 },
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}),
181143 };181114 };
181144 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });181115 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
181145}181116}
...@@ -181236,6 +181207,7 @@ fn lowerValue(cg: *CodeGen, val: Value) Allocator.Error!MCValue {...@@ -181236,6 +181207,7 @@ fn lowerValue(cg: *CodeGen, val: Value) Allocator.Error!MCValue {
181236 .lea_nav => |nav| .{ .lea_nav = nav },181207 .lea_nav => |nav| .{ .lea_nav = nav },
181237 .lea_uav => |uav| .{ .lea_uav = uav },181208 .lea_uav => |uav| .{ .lea_uav = uav },
181238 .load_uav => |uav| .{ .load_uav = uav },181209 .load_uav => |uav| .{ .load_uav = uav },
181210 .lea_lazy_sym => |lazy_sym| .{ .lea_lazy_sym = lazy_sym },
181239 };181211 };
181240}181212}
181241181213
...@@ -181630,10 +181602,14 @@ fn resolveCallingConventionValues(...@@ -181630,10 +181602,14 @@ fn resolveCallingConventionValues(
181630181602
181631fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {181603fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
181632 @branchHint(.cold);181604 @branchHint(.cold);
181633 const zcu = cg.pt.zcu;181605 const pt = cg.pt;
181606 const zcu = pt.zcu;
181634 return switch (cg.owner) {181607 return switch (cg.owner) {
181635 .nav_index => |i| zcu.codegenFail(i, format, args),181608 .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 },
181637 };181613 };
181638}181614}
181639181615
...@@ -187899,14 +187875,14 @@ const Select = struct {...@@ -187899,14 +187875,14 @@ const Select = struct {
187899 error.InvalidInstruction => {187875 error.InvalidInstruction => {
187900 const fixes = @tagName(mir_tag[0]);187876 const fixes = @tagName(mir_tag[0]);
187901 const fixes_blank = std.mem.indexOfScalar(u8, fixes, '_').?;187877 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}'", .{
187903 fixes[0..fixes_blank],187879 fixes[0..fixes_blank],
187904 @tagName(mir_tag[1]),187880 mir_tag[1],
187905 fixes[fixes_blank + 1 ..],187881 fixes[fixes_blank + 1 ..],
187906 @tagName(mir_ops[0]),187882 mir_ops[0],
187907 @tagName(mir_ops[1]),187883 mir_ops[1],
187908 @tagName(mir_ops[2]),187884 mir_ops[2],
187909 @tagName(mir_ops[3]),187885 mir_ops[3],
187910 });187886 });
187911 },187887 },
187912 else => |e| return e,187888 else => |e| return e,
...@@ -187976,16 +187952,7 @@ const Select = struct {...@@ -187976,16 +187952,7 @@ const Select = struct {
187976 },187952 },
187977 .f_p => switch (mir_tag[1]) {187953 .f_p => switch (mir_tag[1]) {
187978 .add, .com, .comi, .div, .divr, .mul, .st, .sub, .subr, .ucom, .ucomi => s.top +%= 1,187954 .add, .com, .comi, .div, .divr, .mul, .st, .sub, .subr, .ucom, .ucomi => s.top +%= 1,
187979 else => {187955 else => unreachable,
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 },
187989 },187956 },
187990 .f_pp => switch (mir_tag[1]) {187957 .f_pp => switch (mir_tag[1]) {
187991 .com, .ucom => s.top +%= 2,187958 .com, .ucom => s.top +%= 2,
...@@ -189095,7 +189062,7 @@ const Select = struct {...@@ -189095,7 +189062,7 @@ const Select = struct {
189095 const ty = if (lazy_symbol_spec.ref == .none) spec.type else lazy_symbol_spec.ref.typeOf(s);189062 const ty = if (lazy_symbol_spec.ref == .none) spec.type else lazy_symbol_spec.ref.typeOf(s);
189096 return .{ try cg.tempInit(.usize, .{ .lea_lazy_sym = .{189063 return .{ try cg.tempInit(.usize, .{ .lea_lazy_sym = .{
189097 .kind = lazy_symbol_spec.kind,189064 .kind = lazy_symbol_spec.kind,
189098 .ty = switch (ip.indexToKey(ty.toIntern())) {189065 .key = switch (ip.indexToKey(ty.toIntern())) {
189099 .inferred_error_set_type => |func_index| switch (ip.funcIesResolvedUnordered(func_index)) {189066 .inferred_error_set_type => |func_index| switch (ip.funcIesResolvedUnordered(func_index)) {
189100 .none => unreachable,189067 .none => unreachable,
189101 else => |ty_index| ty_index,189068 else => |ty_index| ty_index,
src/codegen/x86_64/Emit.zig+2-2
...@@ -163,8 +163,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -163,8 +163,8 @@ pub fn emitMir(emit: *Emit) Error!void {
163 else if (emit.bin_file.cast(.macho)) |macho_file|163 else if (emit.bin_file.cast(.macho)) |macho_file|
164 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|164 macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
165 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})165 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})
166 else if (emit.bin_file.cast(.coff2)) |elf|166 else if (emit.bin_file.cast(.coff2)) |coff|
167 @intFromEnum(try elf.lazySymbol(lazy_sym))167 @intFromEnum(try coff.lazySymbol(lazy_sym))
168 else168 else
169 return emit.fail("lazy symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),169 return emit.fail("lazy symbols unimplemented for {s}", .{@tagName(emit.bin_file.tag)}),
170 .is_extern = false,170 .is_extern = false,
src/codegen/x86_64/Mir.zig+28-7
...@@ -1867,7 +1867,7 @@ pub const Memory = struct {...@@ -1867,7 +1867,7 @@ pub const Memory = struct {
1867 size: bits.Memory.Size,1867 size: bits.Memory.Size,
1868 index: Register,1868 index: Register,
1869 scale: bits.Memory.Scale,1869 scale: bits.Memory.Scale,
1870 _: u13 = undefined,1870 unused: u13 = 0,
1871 };1871 };
18721872
1873 pub fn encode(mem: bits.Memory) Memory {1873 pub fn encode(mem: bits.Memory) Memory {
...@@ -1895,7 +1895,7 @@ pub const Memory = struct {...@@ -1895,7 +1895,7 @@ pub const Memory = struct {
1895 .rip_inst => |inst_index| inst_index,1895 .rip_inst => |inst_index| inst_index,
1896 .nav => |nav| @intFromEnum(nav),1896 .nav => |nav| @intFromEnum(nav),
1897 .uav => |uav| @intFromEnum(uav.val),1897 .uav => |uav| @intFromEnum(uav.val),
1898 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.ty),1898 .lazy_sym => |lazy_sym| @intFromEnum(lazy_sym.key),
1899 .extern_func => |extern_func| @intFromEnum(extern_func),1899 .extern_func => |extern_func| @intFromEnum(extern_func),
1900 },1900 },
1901 .off = switch (mem.mod) {1901 .off = switch (mem.mod) {
...@@ -1933,7 +1933,10 @@ pub const Memory = struct {...@@ -1933,7 +1933,10 @@ pub const Memory = struct {
1933 .rip_inst => .{ .rip_inst = mem.base },1933 .rip_inst => .{ .rip_inst = mem.base },
1934 .nav => .{ .nav = @enumFromInt(mem.base) },1934 .nav => .{ .nav = @enumFromInt(mem.base) },
1935 .uav => .{ .uav = .{ .val = @enumFromInt(mem.base), .orig_ty = @enumFromInt(mem.extra) } },1935 .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 } },
1937 .extern_func => .{ .extern_func = @enumFromInt(mem.base) },1940 .extern_func => .{ .extern_func = @enumFromInt(mem.base) },
1938 },1941 },
1939 .scale_index = switch (mem.info.index) {1942 .scale_index = switch (mem.info.index) {
...@@ -2061,10 +2064,28 @@ pub fn emitLazy(...@@ -2061,10 +2064,28 @@ pub fn emitLazy(
2061 .table_relocs = .empty,2064 .table_relocs = .empty,
2062 };2065 };
2063 defer e.deinit();2066 defer e.deinit();
2064 e.emitMir() catch |err| switch (err) {2067 e.emitMir() catch |err| switch (zcu.intern_pool.typeOf(lazy_sym.key)) {
2065 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, e.lower.err_msg.?),2068 .type_type => switch (err) {
2066 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),2069 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.key, e.lower.err_msg.?),
2067 else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),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 },
2068 };2089 };
2069}2090}
20702091
src/codegen/x86_64/encoder.zig+10-16
...@@ -238,7 +238,7 @@ pub const Instruction = struct {...@@ -238,7 +238,7 @@ pub const Instruction = struct {
238 try w.print("{f} ", .{sib.ptr_size});238 try w.print("{f} ", .{sib.ptr_size});
239239
240 if (mem.isSegmentRegister()) {240 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 });
242 }242 }
243243
244 try w.writeByte('[');244 try w.writeByte('[');
...@@ -246,21 +246,18 @@ pub const Instruction = struct {...@@ -246,21 +246,18 @@ pub const Instruction = struct {
246 var any = true;246 var any = true;
247 switch (sib.base) {247 switch (sib.base) {
248 .none => any = false,248 .none => any = false,
249 .reg => |reg| try w.print("{s}", .{@tagName(reg)}),249 .reg => |reg| try w.print("{t}", .{reg}),
250 .frame => |frame_index| try w.print("{f}", .{frame_index}),250 .frame => |frame_index| try w.print("{f}", .{frame_index}),
251 .table => try w.print("Table", .{}),251 .table => try w.print("Table", .{}),
252 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),252 .rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
253 .nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),253 .nav => |nav| try w.print("Nav({d})", .{nav}),
254 .uav => |uav| try w.print("Uav({d})", .{@intFromEnum(uav.val)}),254 .uav => |uav| try w.print("Uav({d})", .{uav.val}),
255 .lazy_sym => |lazy_sym| try w.print("LazySym({s}, {d})", .{255 .lazy_sym => |lazy_sym| try w.print("LazySym({t}, {d})", .{ lazy_sym.kind, lazy_sym.key }),
256 @tagName(lazy_sym.kind),256 .extern_func => |extern_func| try w.print("ExternFunc({d})", .{extern_func}),
257 @intFromEnum(lazy_sym.ty),
258 }),
259 .extern_func => |extern_func| try w.print("ExternFunc({d})", .{@intFromEnum(extern_func)}),
260 }257 }
261 if (mem.scaleIndex()) |si| {258 if (mem.scaleIndex()) |si| {
262 if (any) try w.writeAll(" + ");259 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 });
264 any = true;261 any = true;
265 }262 }
266 if (sib.disp != 0 or !any) {263 if (sib.disp != 0 or !any) {
...@@ -274,10 +271,7 @@ pub const Instruction = struct {...@@ -274,10 +271,7 @@ pub const Instruction = struct {
274271
275 try w.writeByte(']');272 try w.writeByte(']');
276 },273 },
277 .moffs => |moffs| try w.print("{s}:0x{x}", .{274 .moffs => |moffs| try w.print("{t}:0x{x}", .{ moffs.seg, moffs.offset }),
278 @tagName(moffs.seg),
279 moffs.offset,
280 }),
281 },275 },
282 .imm => |imm| if (enc_op.isSigned()) {276 .imm => |imm| if (enc_op.isSigned()) {
283 const imms = imm.asSigned(enc_op.immBitSize());277 const imms = imm.asSigned(enc_op.immBitSize());
...@@ -344,9 +338,9 @@ pub const Instruction = struct {...@@ -344,9 +338,9 @@ pub const Instruction = struct {
344 pub fn format(inst: Instruction, w: *Writer) Writer.Error!void {338 pub fn format(inst: Instruction, w: *Writer) Writer.Error!void {
345 switch (inst.prefix) {339 switch (inst.prefix) {
346 .none, .directive => {},340 .none, .directive => {},
347 else => try w.print("{s} ", .{@tagName(inst.prefix)}),341 else => try w.print("{t} ", .{inst.prefix}),
348 }342 }
349 try w.print("{s}", .{@tagName(inst.encoding.mnemonic)});343 try w.print("{t}", .{inst.encoding.mnemonic});
350 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {344 for (inst.ops, inst.encoding.data.ops, 0..) |op, enc, i| {
351 if (op == .none) break;345 if (op == .none) break;
352 if (i > 0) try w.writeByte(',');346 if (i > 0) try w.writeByte(',');
src/link.zig+18-4
...@@ -1019,7 +1019,7 @@ pub const File = struct {...@@ -1019,7 +1019,7 @@ pub const File = struct {
1019 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate1019 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
1020 /// the block/atom.1020 /// the block/atom.
1021 /// Never called when LLVM is codegenning the ZCU.1021 /// 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 {
1023 assert(base.comp.zcu.?.llvm_object == null);1023 assert(base.comp.zcu.?.llvm_object == null);
1024 switch (base.tag) {1024 switch (base.tag) {
1025 .lld => unreachable,1025 .lld => unreachable,
...@@ -1029,7 +1029,7 @@ pub const File = struct {...@@ -1029,7 +1029,7 @@ pub const File = struct {
1029 .plan9 => unreachable,1029 .plan9 => unreachable,
1030 inline else => |tag| {1030 inline else => |tag| {
1031 dev.check(tag.devFeature());1031 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);
1033 },1033 },
1034 }1034 }
1035 }1035 }
...@@ -1290,11 +1290,25 @@ pub const File = struct {...@@ -1290,11 +1290,25 @@ pub const File = struct {
1290 };1290 };
12911291
1292 pub const LazySymbol = struct {1292 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
1295 kind: Kind,1295 kind: Kind,
1296 ty: InternPool.Index,1296 key: InternPool.Index,
1297 };1297 };
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
1299 pub fn determinePermissions(1313 pub fn determinePermissions(
1300 output_mode: std.builtin.OutputMode,1314 output_mode: std.builtin.OutputMode,
src/link/C.zig+50-3
...@@ -134,6 +134,7 @@ const RenderedDecl = struct {...@@ -134,6 +134,7 @@ const RenderedDecl = struct {
134 code: String,134 code: String,
135 ctype_deps: CTypeDependencies,135 ctype_deps: CTypeDependencies,
136 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),136 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
137 need_restricted: std.array_hash_map.Auto(InternPool.Index, void),
137 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),138 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
138 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),139 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
139 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),140 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
...@@ -143,6 +144,7 @@ const RenderedDecl = struct {...@@ -143,6 +144,7 @@ const RenderedDecl = struct {
143 .code = .empty,144 .code = .empty,
144 .ctype_deps = .empty,145 .ctype_deps = .empty,
145 .need_uavs = .empty,146 .need_uavs = .empty,
147 .need_restricted = .empty,
146 .need_tag_name_funcs = .empty,148 .need_tag_name_funcs = .empty,
147 .need_never_tail_funcs = .empty,149 .need_never_tail_funcs = .empty,
148 .need_never_inline_funcs = .empty,150 .need_never_inline_funcs = .empty,
...@@ -150,6 +152,7 @@ const RenderedDecl = struct {...@@ -150,6 +152,7 @@ const RenderedDecl = struct {
150152
151 fn deinit(rd: *RenderedDecl, gpa: Allocator) void {153 fn deinit(rd: *RenderedDecl, gpa: Allocator) void {
152 rd.need_uavs.deinit(gpa);154 rd.need_uavs.deinit(gpa);
155 rd.need_restricted.deinit(gpa);
153 rd.need_tag_name_funcs.deinit(gpa);156 rd.need_tag_name_funcs.deinit(gpa);
154 rd.need_never_tail_funcs.deinit(gpa);157 rd.need_never_tail_funcs.deinit(gpa);
155 rd.need_never_inline_funcs.deinit(gpa);158 rd.need_never_inline_funcs.deinit(gpa);
...@@ -162,6 +165,7 @@ const RenderedDecl = struct {...@@ -162,6 +165,7 @@ const RenderedDecl = struct {
162 fn clearRetainingCapacity(rd: *RenderedDecl) void {165 fn clearRetainingCapacity(rd: *RenderedDecl) void {
163 rd.fwd_decl = undefined;166 rd.fwd_decl = undefined;
164 rd.code = undefined;167 rd.code = undefined;
168 rd.need_restricted.clearRetainingCapacity();
165 rd.need_uavs.clearRetainingCapacity();169 rd.need_uavs.clearRetainingCapacity();
166 rd.need_tag_name_funcs.clearRetainingCapacity();170 rd.need_tag_name_funcs.clearRetainingCapacity();
167 rd.need_never_tail_funcs.clearRetainingCapacity();171 rd.need_never_tail_funcs.clearRetainingCapacity();
...@@ -501,6 +505,7 @@ pub fn updateFunc(...@@ -501,6 +505,7 @@ pub fn updateFunc(
501 .code = try c.addString(&.{ mir.c.code_header, mir.c.code }),505 .code = try c.addString(&.{ mir.c.code_header, mir.c.code }),
502 .ctype_deps = try c.addCTypeDependencies(pt, &mir.c.ctype_deps),506 .ctype_deps = try c.addCTypeDependencies(pt, &mir.c.ctype_deps),
503 .need_uavs = mir.c.need_uavs.move(),507 .need_uavs = mir.c.need_uavs.move(),
508 .need_restricted = mir.c.need_restricted.move(),
504 .need_tag_name_funcs = mir.c.need_tag_name_funcs.move(),509 .need_tag_name_funcs = mir.c.need_tag_name_funcs.move(),
505 .need_never_tail_funcs = mir.c.need_never_tail_funcs.move(),510 .need_never_tail_funcs = mir.c.need_never_tail_funcs.move(),
506 .need_never_inline_funcs = mir.c.need_never_inline_funcs.move(),511 .need_never_inline_funcs = mir.c.need_never_inline_funcs.move(),
...@@ -576,11 +581,13 @@ pub fn updateNav(...@@ -576,11 +581,13 @@ pub fn updateNav(
576 .expected_block = null,581 .expected_block = null,
577 .ctype_deps = .empty,582 .ctype_deps = .empty,
578 .uavs = rendered_decl.need_uavs.move(),583 .uavs = rendered_decl.need_uavs.move(),
584 .need_restricted = .empty,
579 };585 };
580586
581 defer {587 defer {
582 rendered_decl.need_uavs = dg.uavs.move();588 rendered_decl.need_uavs = dg.uavs.move();
583 dg.ctype_deps.deinit(gpa);589 dg.ctype_deps.deinit(gpa);
590 dg.need_restricted.deinit(gpa);
584 }591 }
585592
586 rendered_decl.fwd_decl = fwd_decl: {593 rendered_decl.fwd_decl = fwd_decl: {
...@@ -618,6 +625,7 @@ pub fn updateNav(...@@ -618,6 +625,7 @@ pub fn updateNav(
618 };625 };
619626
620 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);627 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
628 rendered_decl.need_restricted = dg.need_restricted.move();
621 }629 }
622630
623 const old_uavs_len = c.uavs.count();631 const old_uavs_len = c.uavs.count();
...@@ -667,10 +675,12 @@ fn updateUav(...@@ -667,10 +675,12 @@ fn updateUav(
667 .expected_block = null,675 .expected_block = null,
668 .ctype_deps = .empty,676 .ctype_deps = .empty,
669 .uavs = .empty,677 .uavs = .empty,
678 .need_restricted = .empty,
670 };679 };
671 defer {680 defer {
672 rendered_decl.need_uavs = dg.uavs.move();681 rendered_decl.need_uavs = dg.uavs.move();
673 dg.ctype_deps.deinit(gpa);682 dg.ctype_deps.deinit(gpa);
683 dg.need_restricted.deinit(gpa);
674 }684 }
675685
676 rendered_decl.fwd_decl = fwd_decl: {686 rendered_decl.fwd_decl = fwd_decl: {
...@@ -716,6 +726,7 @@ fn updateUav(...@@ -716,6 +726,7 @@ fn updateUav(
716 };726 };
717727
718 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);728 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
729 rendered_decl.need_restricted = dg.need_restricted.move();
719}730}
720731
721pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) error{}!void {732pub 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...@@ -795,6 +806,10 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
795 var need_aligned_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64) = .empty;806 var need_aligned_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64) = .empty;
796 defer need_aligned_types.deinit(gpa);807 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
798 var need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;813 var need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;
799 defer need_tag_name_funcs.deinit(gpa);814 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...@@ -816,7 +831,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
816 if (!gop.found_existing) gop.value_ptr.* = .none;831 if (!gop.found_existing) gop.value_ptr.* = .none;
817 }832 }
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.
820 for (need_navs.keys()) |nav| {835 for (need_navs.keys()) |nav| {
821 const rendered = c.navs.getPtr(nav).?;836 const rendered = c.navs.getPtr(nav).?;
822 try mergeNeededCTypes(837 try mergeNeededCTypes(
...@@ -827,6 +842,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -827,6 +842,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
827 &rendered.ctype_deps,842 &rendered.ctype_deps,
828 );843 );
829 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);844 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
845 try mergeNeededRestricted(zcu, &need_restricted, &rendered.need_restricted);
830846
831 try need_tag_name_funcs.ensureUnusedCapacity(gpa, rendered.need_tag_name_funcs.count());847 try need_tag_name_funcs.ensureUnusedCapacity(gpa, rendered.need_tag_name_funcs.count());
832 for (rendered.need_tag_name_funcs.keys()) |enum_type| {848 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...@@ -844,7 +860,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
844 }860 }
845 }861 }
846862
847 // UAVs may reference other UAVs or C types.863 // UAVs may reference other UAVs, restricted types, or C types.
848 {864 {
849 var index: usize = 0;865 var index: usize = 0;
850 while (need_uavs.count() > index) : (index += 1) {866 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...@@ -858,6 +874,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
858 &rendered.ctype_deps,874 &rendered.ctype_deps,
859 );875 );
860 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);876 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
877 try mergeNeededRestricted(zcu, &need_restricted, &rendered.need_restricted);
861 }878 }
862 }879 }
863880
...@@ -962,7 +979,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -962,7 +979,7 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
962 // * NAV exports979 // * NAV exports
963 // * UAV forward declarations980 // * UAV forward declarations
964 // * NAV forward declarations981 // * 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)
966 // * UAV definitions983 // * UAV definitions
967 // * NAV definitions984 // * NAV definitions
968 //985 //
...@@ -1115,11 +1132,18 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -1115,11 +1132,18 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
1115 .error_msg = null,1132 .error_msg = null,
1116 .ctype_deps = .empty,1133 .ctype_deps = .empty,
1117 .uavs = .empty,1134 .uavs = .empty,
1135 .need_restricted = .empty,
1118 };1136 };
1119 defer {1137 defer {
1120 assert(lazy_dg.uavs.count() == 0);1138 assert(lazy_dg.uavs.count() == 0);
1121 lazy_dg.ctype_deps.deinit(gpa);1139 lazy_dg.ctype_deps.deinit(gpa);
1140 assert(lazy_dg.need_restricted.count() == 0);
1122 }1141 }
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 };
1123 const slice_const_u8_sentinel_0_cty: codegen.CType = try .lower(1147 const slice_const_u8_sentinel_0_cty: codegen.CType = try .lower(
1124 .slice_const_u8_sentinel_0,1148 .slice_const_u8_sentinel_0,
1125 &lazy_dg.ctype_deps,1149 &lazy_dg.ctype_deps,
...@@ -1259,10 +1283,12 @@ pub fn updateExports(...@@ -1259,10 +1283,12 @@ pub fn updateExports(
1259 .error_msg = null,1283 .error_msg = null,
1260 .ctype_deps = .empty,1284 .ctype_deps = .empty,
1261 .uavs = .empty,1285 .uavs = .empty,
1286 .need_restricted = .empty,
1262 };1287 };
1263 defer {1288 defer {
1264 assert(dg.uavs.count() == 0);1289 assert(dg.uavs.count() == 0);
1265 dg.ctype_deps.deinit(gpa);1290 dg.ctype_deps.deinit(gpa);
1291 assert(dg.need_restricted.count() == 0);
1266 }1292 }
12671293
1268 const code: String = code: {1294 const code: String = code: {
...@@ -1347,6 +1373,27 @@ fn mergeNeededUavs(...@@ -1347,6 +1373,27 @@ fn mergeNeededUavs(
1347 }1373 }
1348}1374}
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
1350fn addCTypeDependencies(1397fn addCTypeDependencies(
1351 c: *C,1398 c: *C,
1352 pt: Zcu.PerThread,1399 pt: Zcu.PerThread,
src/link/Coff.zig+77-36
...@@ -138,6 +138,7 @@ pub const Node = union(enum) {...@@ -138,6 +138,7 @@ pub const Node = union(enum) {
138 uav: UavMapIndex,138 uav: UavMapIndex,
139 lazy_code: LazyMapRef.Index(.code),139 lazy_code: LazyMapRef.Index(.code),
140 lazy_const_data: LazyMapRef.Index(.const_data),140 lazy_const_data: LazyMapRef.Index(.const_data),
141 lazy_deferred_const_data: LazyMapRef.Index(.deferred_const_data),
141142
142 pub const PseudoSectionMapIndex = enum(u32) {143 pub const PseudoSectionMapIndex = enum(u32) {
143 _,144 _,
...@@ -222,7 +223,7 @@ pub const Node = union(enum) {...@@ -222,7 +223,7 @@ pub const Node = union(enum) {
222 }223 }
223224
224 pub fn lazySymbol(lmr: LazyMapRef, coff: *const Coff) link.File.LazySymbol {225 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] };
226 }227 }
227228
228 pub fn symbol(lmr: LazyMapRef, coff: *const Coff) Symbol.Index {229 pub fn symbol(lmr: LazyMapRef, coff: *const Coff) Symbol.Index {
...@@ -1053,6 +1054,7 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 {...@@ -1053,6 +1054,7 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 {
1053 .uav,1054 .uav,
1054 .lazy_code,1055 .lazy_code,
1055 .lazy_const_data,1056 .lazy_const_data,
1057 .lazy_deferred_const_data,
1056 => |mi| mi.symbol(coff),1058 => |mi| mi.symbol(coff),
1057 };1059 };
1058 break :parent_rva parent_si.get(coff).rva;1060 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...@@ -1259,7 +1261,8 @@ fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.Na
1259 if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity();1261 if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity();
1260 return @enumFromInt(sym_gop.index);1262 return @enumFromInt(sym_gop.index);
1261}1263}
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.?;
1263 const ip = &zcu.intern_pool;1266 const ip = &zcu.intern_pool;
1264 const nav = ip.getNav(nav_index);1267 const nav = ip.getNav(nav_index);
1265 if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(1268 if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(
...@@ -1282,24 +1285,38 @@ pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index {...@@ -1282,24 +1285,38 @@ pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index {
1282 return umi.symbol(coff);1285 return umi.symbol(coff);
1283}1286}
12841287
1285pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index {1288fn lazySymbolIfExists(coff: *Coff, lazy_sym: link.File.LazySymbol) ?Symbol.Index {
1286 const gpa = coff.base.comp.gpa;1289 return coff.lazy.getPtr(lazy_sym.kind).map.get(lazy_sym.key);
1287 try coff.symbol_table.ensureUnusedCapacity(gpa, 1);1290}
1288 const sym_gop = try coff.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty);1291fn lazySymbolAssumeCapacity(coff: *Coff, lazy_sym: link.File.LazySymbol) !struct { Symbol.Index, usize } {
1289 if (!sym_gop.found_existing) {1292 const gop = try coff.lazy.getPtr(lazy_sym.kind).map.getOrPut(coff.base.comp.gpa, lazy_sym.key);
1290 sym_gop.value_ptr.* = try coff.initSymbolAssumeCapacity();1293 if (gop.found_existing) return .{ gop.value_ptr.*, gop.index };
1291 coff.synth_prog_node.increaseEstimatedTotalItems(1);1294 const si = try coff.initSymbolAssumeCapacity();
1292 }1295 gop.value_ptr.* = si;
1293 return sym_gop.value_ptr.*;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;
1294}1312}
12951313
1296pub fn getNavVAddr(1314pub fn getNavVAddr(
1297 coff: *Coff,1315 coff: *Coff,
1298 pt: Zcu.PerThread,
1299 nav: InternPool.Nav.Index,1316 nav: InternPool.Nav.Index,
1300 reloc_info: link.File.RelocInfo,1317 reloc_info: link.File.RelocInfo,
1301) !u64 {1318) !u64 {
1302 return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav));1319 return coff.getVAddr(reloc_info, try coff.navSymbol(nav));
1303}1320}
13041321
1305pub fn getUavVAddr(1322pub fn getUavVAddr(
...@@ -1310,6 +1327,15 @@ pub fn getUavVAddr(...@@ -1310,6 +1327,15 @@ pub fn getUavVAddr(
1310 return coff.getVAddr(reloc_info, try coff.uavSymbol(uav));1327 return coff.getVAddr(reloc_info, try coff.uavSymbol(uav));
1311}1328}
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
1313pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {1339pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {
1314 try coff.addReloc(1340 try coff.addReloc(
1315 @enumFromInt(reloc_info.parent.atom_index),1341 @enumFromInt(reloc_info.parent.atom_index),
...@@ -1713,7 +1739,7 @@ fn updateFuncInner(...@@ -1713,7 +1739,7 @@ fn updateFuncInner(
17131739
1714pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {1740pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
1715 coff.flushLazy(pt, .{1741 coff.flushLazy(pt, .{
1716 .kind = .const_data,1742 .kind = .deferred_const_data,
1717 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),1743 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
1718 }) catch |err| switch (err) {1744 }) catch |err| switch (err) {
1719 error.OutOfMemory => |e| return e,1745 error.OutOfMemory => |e| return e,
...@@ -1798,13 +1824,13 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {...@@ -1798,13 +1824,13 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
1798 lazy.value.pending_index += 1;1824 lazy.value.pending_index += 1;
1799 const kind = switch (lmr.kind) {1825 const kind = switch (lmr.kind) {
1800 .code => "code",1826 .code => "code",
1801 .const_data => "data",1827 .const_data, .deferred_const_data => "data",
1802 };1828 };
1803 var name: [std.Progress.Node.max_name_len]u8 = undefined;1829 var name: [std.Progress.Node.max_name_len]u8 = undefined;
1804 const sub_prog_node = coff.synth_prog_node.start(1830 const sub_prog_node = coff.synth_prog_node.start(
1805 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{1831 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{
1806 kind,1832 kind,
1807 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),1833 Value.fromInterned(lmr.lazySymbol(coff).key).fmtValue(pt),
1808 }) catch &name,1834 }) catch &name,
1809 0,1835 0,
1810 );1836 );
...@@ -2092,24 +2118,36 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {...@@ -2092,24 +2118,36 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
2092 const zcu = pt.zcu;2118 const zcu = pt.zcu;
2093 const gpa = zcu.gpa;2119 const gpa = zcu.gpa;
20942120
2095 const lazy = lmr.lazySymbol(coff);2121 const lazy_sym = lmr.lazySymbol(coff);
2096 const si = lmr.symbol(coff);2122 const si = lmr.symbol(coff);
2123 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, zcu);
2097 const ni = ni: {2124 const ni = ni: {
2098 const sym = si.get(coff);2125 const sym = si.get(coff);
2099 switch (sym.ni) {2126 switch (sym.ni) {
2100 .none => {2127 .none => {
2101 try coff.nodes.ensureUnusedCapacity(gpa, 1);2128 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) {
2103 .code => .text,2133 .code => .text,
2104 .const_data => .rdata,2134 .const_data, .deferred_const_data => .rdata,
2105 };2135 };
2106 const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{ .moved = true });2136 const addChildNode =
2107 coff.nodes.appendAssumeCapacity(switch (lazy.kind) {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) {
2108 .code => .{ .lazy_code = @enumFromInt(lmr.index) },2145 .code => .{ .lazy_code = @enumFromInt(lmr.index) },
2109 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },2146 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },
2147 .deferred_const_data => .{ .lazy_deferred_const_data = @enumFromInt(lmr.index) },
2110 });2148 });
2111 sym.ni = ni;2149 sym.ni = ni;
2112 sym.section_number = sec_si.get(coff).section_number;2150 sym.section_number = parent_si.get(coff).section_number;
2113 },2151 },
2114 else => si.deleteLocationRelocs(coff),2152 else => si.deleteLocationRelocs(coff),
2115 }2153 }
...@@ -2118,22 +2156,25 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {...@@ -2118,22 +2156,25 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
2118 break :ni sym.ni;2156 break :ni sym.ni;
2119 };2157 };
21202158
2121 var required_alignment: InternPool.Alignment = .none;
2122 var nw: MappedFile.Node.Writer = undefined;2159 var nw: MappedFile.Node.Writer = undefined;
2123 ni.writer(&coff.mf, gpa, &nw);2160 ni.writer(&coff.mf, gpa, &nw);
2124 defer nw.deinit();2161 defer nw.deinit();
2125 try codegen.generateLazySymbol(2162 try codegen.generateLazySymbol(
2126 &coff.base,2163 &coff.base,
2127 pt,2164 pt,
2128 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,2165 Type.fromInterned(lazy_sym.key).srcLocOrNull(pt.zcu) orelse .unneeded,
2129 lazy,2166 lazy_sym,
2130 &required_alignment,
2131 &nw.interface,2167 &nw.interface,
2132 .none,2168 .none,
2133 .{ .atom_index = @intFromEnum(si) },2169 .{ .atom_index = @intFromEnum(si) },
2134 );2170 );
2135 si.get(coff).size = @intCast(nw.interface.end);2171 si.get(coff).size = @intCast(nw.interface.end);
2136 si.applyLocationRelocs(coff);2172 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 );
2137}2178}
21382179
2139fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {2180fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {
...@@ -2219,6 +2260,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {...@@ -2219,6 +2260,7 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void {
2219 .uav,2260 .uav,
2220 .lazy_code,2261 .lazy_code,
2221 .lazy_const_data,2262 .lazy_const_data,
2263 .lazy_deferred_const_data,
2222 => |mi| mi.symbol(coff).flushMoved(coff),2264 => |mi| mi.symbol(coff).flushMoved(coff),
2223 }2265 }
2224 try ni.childrenMoved(coff.base.comp.gpa, &coff.mf);2266 try ni.childrenMoved(coff.base.comp.gpa, &coff.mf);
...@@ -2269,7 +2311,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void {...@@ -2269,7 +2311,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void {
2269 inline .pseudo_section,2311 inline .pseudo_section,
2270 .object_section,2312 .object_section,
2271 => |smi| smi.symbol(coff).get(coff).size = @intCast(size),2313 => |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 => {},
2273 }2315 }
2274}2316}
2275fn virtualSlide(coff: *Coff, start_section_index: usize, start_rva: u32) !void {2317fn virtualSlide(coff: *Coff, start_section_index: usize, start_rva: u32) !void {
...@@ -2322,7 +2364,7 @@ fn updateExportsInner(...@@ -2322,7 +2364,7 @@ fn updateExportsInner(
2322 }2364 }
2323 try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len);2365 try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len);
2324 const exported_si: Symbol.Index = switch (exported) {2366 const exported_si: Symbol.Index = switch (exported) {
2325 .nav => |nav| try coff.navSymbol(zcu, nav),2367 .nav => |nav| try coff.navSymbol(nav),
2326 .uav => |uav| @enumFromInt(switch (try coff.lowerUav(2368 .uav => |uav| @enumFromInt(switch (try coff.lowerUav(
2327 pt,2369 pt,
2328 uav,2370 uav,
...@@ -2365,7 +2407,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe...@@ -2365,7 +2407,7 @@ pub fn deleteExport(coff: *Coff, exported: Zcu.Exported, name: InternPool.NullTe
2365 _ = name;2407 _ = name;
2366}2408}
23672409
2368pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void {2410pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) !void {
2369 const comp = coff.base.comp;2411 const comp = coff.base.comp;
2370 const io = comp.io;2412 const io = comp.io;
2371 var buffer: [512]u8 = undefined;2413 var buffer: [512]u8 = undefined;
...@@ -2373,7 +2415,7 @@ pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void {...@@ -2373,7 +2415,7 @@ pub fn dump(coff: *Coff, tid: Zcu.PerThread.Id) Io.Cancelable!void {
2373 defer io.unlockStderr();2415 defer io.unlockStderr();
2374 const w = &stderr.file_writer.interface;2416 const w = &stderr.file_writer.interface;
2375 coff.printNode(tid, w, .root, 0) catch |err| switch (err) {2417 coff.printNode(tid, w, .root, 0) catch |err| switch (err) {
2376 error.WriteFailed => return stderr.err.?,2418 error.WriteFailed => return stderr.file_writer.err.?,
2377 };2419 };
2378}2420}
23792421
...@@ -2412,7 +2454,7 @@ pub fn printNode(...@@ -2412,7 +2454,7 @@ pub fn printNode(
2412 const ip = &zcu.intern_pool;2454 const ip = &zcu.intern_pool;
2413 const nav = ip.getNav(nmi.navIndex(coff));2455 const nav = ip.getNav(nmi.navIndex(coff));
2414 try w.print("({f}, {f})", .{2456 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 }),
2416 nav.fqn.fmt(ip),2458 nav.fqn.fmt(ip),
2417 });2459 });
2418 },2460 },
...@@ -2425,10 +2467,9 @@ pub fn printNode(...@@ -2425,10 +2467,9 @@ pub fn printNode(
2425 });2467 });
2426 },2468 },
2427 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{2469 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{
2428 Type.fromInterned(lmi.lazySymbol(coff).ty).fmt(.{2470 Value.fromInterned(lmi.lazySymbol(coff).key).fmtValue(
2429 .zcu = coff.base.comp.zcu.?,2471 .{ .zcu = coff.base.comp.zcu.?, .tid = tid },
2430 .tid = tid,2472 ),
2431 }),
2432 }),2473 }),
2433 }2474 }
2434 {2475 {
...@@ -2458,7 +2499,7 @@ pub fn printNode(...@@ -2458,7 +2499,7 @@ pub fn printNode(
2458 const line_len = 0x10;2499 const line_len = 0x10;
2459 var line_it = std.mem.window(2500 var line_it = std.mem.window(
2460 u8,2501 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)],
2462 line_len,2503 line_len,
2463 line_len,2504 line_len,
2464 );2505 );
src/link/Dwarf.zig+2-2
...@@ -3631,11 +3631,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co...@@ -3631,11 +3631,11 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
3631 },3631 },
3632 },3632 },
3633 .restricted_ptr_type => |restricted_ptr_type| switch (Type.restrictedReprByZirIndex(restricted_ptr_type.zir_index, zcu)) {3633 .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 = .{
3635 .child = restricted_ptr_type.unrestricted_ptr_type,3635 .child = restricted_ptr_type.unrestricted_ptr_type,
3636 .flags = .{ .is_const = true },3636 .flags = .{ .is_const = true },
3637 } },3637 } },
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 },
3639 },3639 },
3640 .array_type => |array_type| {3640 .array_type => |array_type| {
3641 const array_child_type: Type = .fromInterned(array_type.child);3641 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 {...@@ -467,8 +467,8 @@ pub fn deinit(self: *Elf) void {
467 self.dump_argv_list.deinit(gpa);467 self.dump_argv_list.deinit(gpa);
468}468}
469469
470pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {470pub fn getNavVAddr(self: *Elf, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
471 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);471 return self.zigObjectPtr().?.getNavVAddr(self, nav_index, reloc_info);
472}472}
473473
474pub fn lowerUav(474pub fn lowerUav(
...@@ -485,6 +485,10 @@ pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.Relo...@@ -485,6 +485,10 @@ pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.Relo
485 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);485 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
486}486}
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
488/// Returns end pos of collision, if any.492/// Returns end pos of collision, if any.
489fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {493fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
490 const comp = self.base.comp;494 const comp = self.base.comp;
src/link/Elf/ZigObject.zig+87-53
...@@ -31,16 +31,17 @@ dwarf: ?Dwarf = null,...@@ -31,16 +31,17 @@ dwarf: ?Dwarf = null,
3131
32/// Table of tracked LazySymbols.32/// Table of tracked LazySymbols.
33lazy_syms: LazySymbolTable = .{},33lazy_syms: LazySymbolTable = .{},
34/// Table of tracked LazySymbols that are deferred until flush.
35deferred_lazy_syms: LazySymbolTable = .{},
3436
35/// Table of tracked `Nav`s.37/// Table of tracked `Nav`s.
36navs: NavTable = .{},38navs: NavTable = .{},
39/// Table of tracked `Uav`s.
40uavs: UavTable = .{},
3741
38/// TLS variables indexed by Atom.Index.42/// TLS variables indexed by Atom.Index.
39tls_variables: TlsTable = .{},43tls_variables: TlsTable = .{},
4044
41/// Table of tracked `Uav`s.
42uavs: UavTable = .{},
43
44debug_info_section_dirty: bool = false,45debug_info_section_dirty: bool = false,
45debug_abbrev_section_dirty: bool = false,46debug_abbrev_section_dirty: bool = false,
46debug_aranges_section_dirty: bool = false,47debug_aranges_section_dirty: bool = false,
...@@ -246,13 +247,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -246,13 +247,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
246 }247 }
247 self.relocs.deinit(allocator);248 self.relocs.deinit(allocator);
248249
250 self.lazy_syms.deinit(allocator);
251 self.deferred_lazy_syms.deinit(allocator);
252
249 for (self.navs.values()) |*meta| {253 for (self.navs.values()) |*meta| {
250 meta.exports.deinit(allocator);254 meta.exports.deinit(allocator);
251 }255 }
252 self.navs.deinit(allocator);256 self.navs.deinit(allocator);
253257
254 self.lazy_syms.deinit(allocator);
255
256 for (self.uavs.values()) |*meta| {258 for (self.uavs.values()) |*meta| {
257 meta.exports.deinit(allocator);259 meta.exports.deinit(allocator);
258 }260 }
...@@ -266,30 +268,22 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -266,30 +268,22 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
266268
267pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {269pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
268 // Handle any lazy symbols that were emitted by incremental compilation.270 // Handle any lazy symbols that were emitted by incremental compilation.
269 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {271 {
270 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);272 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);
271 defer pt.deactivate();273 defer pt.deactivate();
272274
273 // Most lazy symbols can be updated on first use, but275 for (self.deferred_lazy_syms.values(), self.deferred_lazy_syms.keys()) |*metadata, key| {
274 // anyerror needs to wait for everything to be flushed.276 assert(metadata.text_state == .unused);
275 if (metadata.text_state != .unused) self.updateLazySymbol(277 if (metadata.rodata_state != .unused) self.updateLazySymbol(
276 elf_file,278 elf_file,
277 pt,279 pt,
278 .{ .kind = .code, .ty = .anyerror_type },280 .{ .kind = .deferred_const_data, .key = key },
279 metadata.text_symbol_index,281 metadata.rodata_symbol_index,
280 ) catch |err| switch (err) {282 ) catch |err| switch (err) {
281 error.CodegenFail => return error.LinkFailure,283 error.CodegenFail => return error.LinkFailure,
282 else => |e| return e,284 else => |e| return e,
283 };285 };
284 if (metadata.rodata_state != .unused) self.updateLazySymbol(286 }
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 };
293 }287 }
294 for (self.lazy_syms.values()) |*metadata| {288 for (self.lazy_syms.values()) |*metadata| {
295 if (metadata.text_state != .unused) metadata.text_state = .flushed;289 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...@@ -923,11 +917,10 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
923pub fn getNavVAddr(917pub fn getNavVAddr(
924 self: *ZigObject,918 self: *ZigObject,
925 elf_file: *Elf,919 elf_file: *Elf,
926 pt: Zcu.PerThread,
927 nav_index: InternPool.Nav.Index,920 nav_index: InternPool.Nav.Index,
928 reloc_info: link.File.RelocInfo,921 reloc_info: link.File.RelocInfo,
929) !u64 {922) !u64 {
930 const zcu = pt.zcu;923 const zcu = elf_file.base.comp.zcu.?;
931 const ip = &zcu.intern_pool;924 const ip = &zcu.intern_pool;
932 const nav = ip.getNav(nav_index);925 const nav = ip.getNav(nav_index);
933 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });926 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
...@@ -993,6 +986,44 @@ pub fn getUavVAddr(...@@ -993,6 +986,44 @@ pub fn getUavVAddr(
993 return @intCast(vaddr);986 return @intCast(vaddr);
994}987}
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
996pub fn lowerUav(1027pub fn lowerUav(
997 self: *ZigObject,1028 self: *ZigObject,
998 elf_file: *Elf,1029 elf_file: *Elf,
...@@ -1063,12 +1094,16 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1063,12 +1094,16 @@ pub fn getOrCreateMetadataForLazySymbol(
1063 pt: Zcu.PerThread,1094 pt: Zcu.PerThread,
1064 lazy_sym: link.File.LazySymbol,1095 lazy_sym: link.File.LazySymbol,
1065) !Symbol.Index {1096) !Symbol.Index {
1066 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);1097 const lazy_syms = switch (lazy_sym.kind) {
1067 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();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();
1068 if (!gop.found_existing) gop.value_ptr.* = .{};1103 if (!gop.found_existing) gop.value_ptr.* = .{};
1069 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {1104 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
1070 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },1105 .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 },
1072 };1107 };
1073 switch (state_ptr.*) {1108 switch (state_ptr.*) {
1074 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0),1109 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0),
...@@ -1077,8 +1112,10 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1077,8 +1112,10 @@ pub fn getOrCreateMetadataForLazySymbol(
1077 }1112 }
1078 state_ptr.* = .pending_flush;1113 state_ptr.* = .pending_flush;
1079 const symbol_index = symbol_index_ptr.*;1114 const symbol_index = symbol_index_ptr.*;
1080 // anyerror needs to be deferred until flush1115 switch (lazy_sym.kind) {
1081 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index);1116 .code, .const_data => try self.updateLazySymbol(elf_file, pt, lazy_sym, symbol_index),
1117 .deferred_const_data => {},
1118 }
1082 return symbol_index;1119 return symbol_index;
1083}1120}
10841121
...@@ -1726,20 +1763,18 @@ fn updateLazySymbol(...@@ -1726,20 +1763,18 @@ fn updateLazySymbol(
1726 self: *ZigObject,1763 self: *ZigObject,
1727 elf_file: *Elf,1764 elf_file: *Elf,
1728 pt: Zcu.PerThread,1765 pt: Zcu.PerThread,
1729 sym: link.File.LazySymbol,1766 lazy_sym: link.File.LazySymbol,
1730 symbol_index: Symbol.Index,1767 symbol_index: Symbol.Index,
1731) !void {1768) !void {
1732 const zcu = pt.zcu;1769 const zcu = pt.zcu;
1733 const gpa = zcu.gpa;1770 const gpa = zcu.gpa;
17341771
1735 var required_alignment: InternPool.Alignment = .none;
1736 var aw: std.Io.Writer.Allocating = .init(gpa);1772 var aw: std.Io.Writer.Allocating = .init(gpa);
1737 defer aw.deinit();1773 defer aw.deinit();
17381774
1739 const name_str_index = blk: {1775 const name_str_index = blk: {
1740 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{1776 const name = try std.fmt.allocPrint(gpa, "__lazy_{t}_{f}", .{
1741 @tagName(sym.kind),1777 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
1742 Type.fromInterned(sym.ty).fmt(pt),
1743 });1778 });
1744 defer gpa.free(name);1779 defer gpa.free(name);
1745 break :blk try self.strtab.insert(gpa, name);1780 break :blk try self.strtab.insert(gpa, name);
...@@ -1748,9 +1783,8 @@ fn updateLazySymbol(...@@ -1748,9 +1783,8 @@ fn updateLazySymbol(
1748 codegen.generateLazySymbol(1783 codegen.generateLazySymbol(
1749 &elf_file.base,1784 &elf_file.base,
1750 pt,1785 pt,
1751 Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded,1786 Type.fromInterned(lazy_sym.key).srcLocOrNull(zcu) orelse .unneeded,
1752 sym,1787 lazy_sym,
1753 &required_alignment,
1754 &aw.writer,1788 &aw.writer,
1755 .none,1789 .none,
1756 .{ .atom_index = symbol_index },1790 .{ .atom_index = symbol_index },
...@@ -1760,7 +1794,7 @@ fn updateLazySymbol(...@@ -1760,7 +1794,7 @@ fn updateLazySymbol(
1760 };1794 };
1761 const code = aw.written();1795 const code = aw.written();
17621796
1763 const output_section_index = switch (sym.kind) {1797 const output_section_index = switch (lazy_sym.kind) {
1764 .code => if (self.text_index) |sym_index|1798 .code => if (self.text_index) |sym_index|
1765 self.symbol(sym_index).outputShndx(elf_file).?1799 self.symbol(sym_index).outputShndx(elf_file).?
1766 else osec: {1800 else osec: {
...@@ -1773,7 +1807,7 @@ fn updateLazySymbol(...@@ -1773,7 +1807,7 @@ fn updateLazySymbol(
1773 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);1807 self.text_index = try self.addSectionSymbol(gpa, try self.addString(gpa, ".text"), osec);
1774 break :osec osec;1808 break :osec osec;
1775 },1809 },
1776 .const_data => if (self.rodata_index) |sym_index|1810 .const_data, .deferred_const_data => if (self.rodata_index) |sym_index|
1777 self.symbol(sym_index).outputShndx(elf_file).?1811 self.symbol(sym_index).outputShndx(elf_file).?
1778 else osec: {1812 else osec: {
1779 const osec = try elf_file.addSection(.{1813 const osec = try elf_file.addSection(.{
...@@ -1786,24 +1820,24 @@ fn updateLazySymbol(...@@ -1786,24 +1820,24 @@ fn updateLazySymbol(
1786 break :osec osec;1820 break :osec osec;
1787 },1821 },
1788 };1822 };
1789 const local_sym = self.symbol(symbol_index);1823 const sym = self.symbol(symbol_index);
1790 local_sym.name_offset = name_str_index;1824 sym.name_offset = name_str_index;
1791 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];1825 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
1792 local_esym.st_name = name_str_index;1826 esym.st_name = name_str_index;
1793 local_esym.st_info |= elf.STT_OBJECT;1827 esym.st_info |= elf.STT_OBJECT;
1794 local_esym.st_size = code.len;1828 esym.st_size = code.len;
1795 const atom_ptr = local_sym.atom(elf_file).?;1829 const atom_ptr = sym.atom(elf_file).?;
1796 atom_ptr.alive = true;1830 atom_ptr.alive = true;
1797 atom_ptr.name_offset = name_str_index;1831 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;
1799 atom_ptr.size = code.len;1833 atom_ptr.size = code.len;
1800 atom_ptr.output_section_index = output_section_index;1834 atom_ptr.output_section_index = output_section_index;
18011835
1802 try self.allocateAtom(atom_ptr, true, elf_file);1836 try self.allocateAtom(atom_ptr, true, elf_file);
1803 errdefer self.freeNavMetadata(elf_file, symbol_index);1837 errdefer self.freeNavMetadata(elf_file, symbol_index);
18041838
1805 local_sym.value = 0;1839 sym.value = 0;
1806 local_esym.st_value = 0;1840 esym.st_value = 0;
18071841
1808 try elf_file.pwriteAll(code, atom_ptr.offset(elf_file));1842 try elf_file.pwriteAll(code, atom_ptr.offset(elf_file));
1809}1843}
src/link/Elf2.zig+92-46
...@@ -75,6 +75,7 @@ pub const Node = union(enum) {...@@ -75,6 +75,7 @@ pub const Node = union(enum) {
75 uav: UavMapIndex,75 uav: UavMapIndex,
76 lazy_code: LazyMapRef.Index(.code),76 lazy_code: LazyMapRef.Index(.code),
77 lazy_const_data: LazyMapRef.Index(.const_data),77 lazy_const_data: LazyMapRef.Index(.const_data),
78 lazy_deferred_const_data: LazyMapRef.Index(.deferred_const_data),
7879
79 pub const InputIndex = enum(u32) {80 pub const InputIndex = enum(u32) {
80 _,81 _,
...@@ -163,7 +164,7 @@ pub const Node = union(enum) {...@@ -163,7 +164,7 @@ pub const Node = union(enum) {
163 }164 }
164165
165 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {166 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] };
167 }168 }
168169
169 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.Index {170 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.Index {
...@@ -1680,7 +1681,12 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -1680,7 +1681,12 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
1680 },1681 },
1681 .section => |si| si,1682 .section => |si| si,
1682 .input_section => unreachable,1683 .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),
1684 };1690 };
1685 break :parent_vaddr if (parent_si == elf.si.tdata) 0 else switch (elf.symPtr(parent_si)) {1691 break :parent_vaddr if (parent_si == elf.si.tdata) 0 else switch (elf.symPtr(parent_si)) {
1686 inline else => |sym| elf.targetLoad(&sym.value),1692 inline else => |sym| elf.targetLoad(&sym.value),
...@@ -1927,7 +1933,8 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavM...@@ -1927,7 +1933,8 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavM
1927 });1933 });
1928 return @enumFromInt(nav_gop.index);1934 return @enumFromInt(nav_gop.index);
1929}1935}
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.?;
1931 const ip = &zcu.intern_pool;1938 const ip = &zcu.intern_pool;
1932 const nav = ip.getNav(nav_index);1939 const nav = ip.getNav(nav_index);
1933 if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{1940 if (nav.getExtern(ip)) |@"extern"| return elf.globalSymbol(.{
...@@ -1963,20 +1970,35 @@ pub fn uavSymbol(elf: *Elf, uav_val: InternPool.Index) !Symbol.Index {...@@ -1963,20 +1970,35 @@ pub fn uavSymbol(elf: *Elf, uav_val: InternPool.Index) !Symbol.Index {
1963 return umi.symbol(elf);1970 return umi.symbol(elf);
1964}1971}
19651972
1966pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !Symbol.Index {1973fn lazySymbolIfExists(elf: *Elf, lazy_sym: link.File.LazySymbol) ?Symbol.Index {
1967 const gpa = elf.base.comp.gpa;1974 return elf.lazy.getPtr(lazy_sym.kind).map.get(lazy_sym.key);
1968 try elf.symtab.ensureUnusedCapacity(gpa, 1);1975}
1969 const lazy_gop = try elf.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty);1976fn lazySymbolAssumeCapacity(elf: *Elf, lazy_sym: link.File.LazySymbol) !struct { Symbol.Index, usize } {
1970 if (!lazy_gop.found_existing) {1977 const gop = try elf.lazy.getPtr(lazy_sym.kind).map.getOrPut(elf.base.comp.gpa, lazy_sym.key);
1971 lazy_gop.value_ptr.* = try elf.initSymbolAssumeCapacity(.{1978 if (gop.found_existing) return .{ gop.value_ptr.*, gop.index };
1972 .type = switch (lazy.kind) {1979 const si = try elf.initSymbolAssumeCapacity(.{
1973 .code => .FUNC,1980 .type = switch (lazy_sym.kind) {
1974 .const_data => .OBJECT,1981 .code => .FUNC,
1975 },1982 .const_data, .deferred_const_data => .OBJECT,
1976 });1983 },
1977 elf.synth_prog_node.increaseEstimatedTotalItems(1);1984 });
1978 }1985 gop.value_ptr.* = si;
1979 return lazy_gop.value_ptr.*;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;
1980}2002}
19812003
1982pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||2004pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||
...@@ -2531,11 +2553,10 @@ fn prelinkInner(elf: *Elf) !void {...@@ -2531,11 +2553,10 @@ fn prelinkInner(elf: *Elf) !void {
25312553
2532pub fn getNavVAddr(2554pub fn getNavVAddr(
2533 elf: *Elf,2555 elf: *Elf,
2534 pt: Zcu.PerThread,
2535 nav: InternPool.Nav.Index,2556 nav: InternPool.Nav.Index,
2536 reloc_info: link.File.RelocInfo,2557 reloc_info: link.File.RelocInfo,
2537) !u64 {2558) !u64 {
2538 return elf.getVAddr(reloc_info, try elf.navSymbol(pt.zcu, nav));2559 return elf.getVAddr(reloc_info, try elf.navSymbol(nav));
2539}2560}
25402561
2541pub fn getUavVAddr(2562pub fn getUavVAddr(
...@@ -2546,6 +2567,15 @@ pub fn getUavVAddr(...@@ -2546,6 +2567,15 @@ pub fn getUavVAddr(
2546 return elf.getVAddr(reloc_info, try elf.uavSymbol(uav));2567 return elf.getVAddr(reloc_info, try elf.uavSymbol(uav));
2547}2568}
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
2549pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {2579pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 {
2550 try elf.addReloc(2580 try elf.addReloc(
2551 @enumFromInt(reloc_info.parent.atom_index),2581 @enumFromInt(reloc_info.parent.atom_index),
...@@ -3106,13 +3136,13 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {...@@ -3106,13 +3136,13 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
3106 lazy.value.pending_index += 1;3136 lazy.value.pending_index += 1;
3107 const kind = switch (lmr.kind) {3137 const kind = switch (lmr.kind) {
3108 .code => "code",3138 .code => "code",
3109 .const_data => "data",3139 .const_data, .deferred_const_data => "data",
3110 };3140 };
3111 var name: [std.Progress.Node.max_name_len]u8 = undefined;3141 var name: [std.Progress.Node.max_name_len]u8 = undefined;
3112 const sub_prog_node = elf.synth_prog_node.start(3142 const sub_prog_node = elf.synth_prog_node.start(
3113 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{3143 std.fmt.bufPrint(&name, "lazy {s} for {f}", .{
3114 kind,3144 kind,
3115 Type.fromInterned(lmr.lazySymbol(elf).ty).fmt(pt),3145 Value.fromInterned(lmr.lazySymbol(elf).key).fmtValue(pt),
3116 }) catch &name,3146 }) catch &name,
3117 0,3147 0,
3118 );3148 );
...@@ -3259,26 +3289,38 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {...@@ -3259,26 +3289,38 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
3259 const zcu = pt.zcu;3289 const zcu = pt.zcu;
3260 const gpa = zcu.gpa;3290 const gpa = zcu.gpa;
32613291
3262 const lazy = lmr.lazySymbol(elf);3292 const lazy_sym = lmr.lazySymbol(elf);
3263 const si = lmr.symbol(elf);3293 const si = lmr.symbol(elf);
3294 const structure = codegen.getLazySymbolInfo(.structure, lazy_sym, zcu);
3264 const ni = ni: {3295 const ni = ni: {
3265 const sym = si.get(elf);3296 const sym = si.get(elf);
3266 switch (sym.ni) {3297 switch (sym.ni) {
3267 .none => {3298 .none => {
3268 try elf.nodes.ensureUnusedCapacity(gpa, 1);3299 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) {
3270 .code => .text,3304 .code => .text,
3271 .const_data => .rodata,3305 .const_data, .deferred_const_data => .rodata,
3272 };3306 };
3273 const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{ .moved = true });3307 const addChildNode =
3274 elf.nodes.appendAssumeCapacity(switch (lazy.kind) {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) {
3275 .code => .{ .lazy_code = @enumFromInt(lmr.index) },3316 .code => .{ .lazy_code = @enumFromInt(lmr.index) },
3276 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },3317 .const_data => .{ .lazy_const_data = @enumFromInt(lmr.index) },
3318 .deferred_const_data => .{ .lazy_deferred_const_data = @enumFromInt(lmr.index) },
3277 });3319 });
3278 sym.ni = ni;3320 sym.ni = ni;
3279 switch (elf.symPtr(si)) {3321 switch (elf.symPtr(si)) {
3280 inline else => |sym_ptr, class| sym_ptr.shndx =3322 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,
3282 }3324 }
3283 },3325 },
3284 else => si.deleteLocationRelocs(elf),3326 else => si.deleteLocationRelocs(elf),
...@@ -3288,16 +3330,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {...@@ -3288,16 +3330,14 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
3288 break :ni sym.ni;3330 break :ni sym.ni;
3289 };3331 };
32903332
3291 var required_alignment: InternPool.Alignment = .none;
3292 var nw: MappedFile.Node.Writer = undefined;3333 var nw: MappedFile.Node.Writer = undefined;
3293 ni.writer(&elf.mf, gpa, &nw);3334 ni.writer(&elf.mf, gpa, &nw);
3294 defer nw.deinit();3335 defer nw.deinit();
3295 try codegen.generateLazySymbol(3336 try codegen.generateLazySymbol(
3296 &elf.base,3337 &elf.base,
3297 pt,3338 pt,
3298 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,3339 Type.fromInterned(lazy_sym.key).srcLocOrNull(pt.zcu) orelse .unneeded,
3299 lazy,3340 lazy_sym,
3300 &required_alignment,
3301 &nw.interface,3341 &nw.interface,
3302 .none,3342 .none,
3303 .{ .atom_index = @intFromEnum(si) },3343 .{ .atom_index = @intFromEnum(si) },
...@@ -3306,6 +3346,11 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {...@@ -3306,6 +3346,11 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
3306 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),3346 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
3307 }3347 }
3308 si.applyLocationRelocs(elf);3348 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 );
3309}3354}
33103355
3311fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void {3356fn flushInputSection(elf: *Elf, isi: Node.InputSectionIndex) !void {
...@@ -3501,10 +3546,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {...@@ -3501,10 +3546,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
3501 } - old_addr + new_addr);3546 } - old_addr + new_addr);
3502 }3547 }
3503 },3548 },
3504 inline .nav, .uav, .lazy_code, .lazy_const_data => |mi| mi.symbol(elf).flushMoved(3549 inline .nav,
3505 elf,3550 .uav,
3506 elf.computeNodeVAddr(ni),3551 .lazy_code,
3507 ),3552 .lazy_const_data,
3553 .lazy_deferred_const_data,
3554 => |mi| mi.symbol(elf).flushMoved(elf, elf.computeNodeVAddr(ni)),
3508 }3555 }
3509 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);3556 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);
3510}3557}
...@@ -3614,7 +3661,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {...@@ -3614,7 +3661,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
3614 elf.targetStore(&shdr.size, @intCast(size));3661 elf.targetStore(&shdr.size, @intCast(size));
3615 },3662 },
3616 },3663 },
3617 .input_section, .nav, .uav, .lazy_code, .lazy_const_data => {},3664 .input_section, .nav, .uav, .lazy_code, .lazy_const_data, .lazy_deferred_const_data => {},
3618 }3665 }
3619}3666}
36203667
...@@ -3655,7 +3702,7 @@ fn updateExportsInner(...@@ -3655,7 +3702,7 @@ fn updateExportsInner(
3655 try elf.symtab.ensureUnusedCapacity(gpa, export_indices.len);3702 try elf.symtab.ensureUnusedCapacity(gpa, export_indices.len);
3656 const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) {3703 const exported_si: Symbol.Index, const @"type": std.elf.STT = switch (exported) {
3657 .nav => |nav| .{3704 .nav => |nav| .{
3658 try elf.navSymbol(zcu, nav),3705 try elf.navSymbol(nav),
3659 navType(ip, ip.getNav(nav).resolved.?, elf.base.comp.config.any_non_single_threaded),3706 navType(ip, ip.getNav(nav).resolved.?, elf.base.comp.config.any_non_single_threaded),
3660 },3707 },
3661 .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav(3708 .uav => |uav| .{ @enumFromInt(switch (try elf.lowerUav(
...@@ -3715,15 +3762,15 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm...@@ -3715,15 +3762,15 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm
3715 _ = name;3762 _ = name;
3716}3763}
37173764
3718pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void {3765pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) !void {
3719 const comp = elf.base.comp;3766 const comp = elf.base.comp;
3720 const io = comp.io;3767 const io = comp.io;
3721 var buffer: [512]u8 = undefined;3768 var buffer: [512]u8 = undefined;
3722 const stderr = try io.lockStderr(&buffer, null);3769 const stderr = try io.lockStderr(&buffer, null);
3723 defer io.lockStderr();3770 defer io.unlockStderr();
3724 const w = &stderr.file_writer.interface;3771 const w = &stderr.file_writer.interface;
3725 elf.printNode(tid, w, .root, 0) catch |err| switch (err) {3772 elf.printNode(tid, w, .root, 0) catch |err| switch (err) {
3726 error.WriteFailed => return stderr.err.?,3773 error.WriteFailed => return stderr.file_writer.err.?,
3727 };3774 };
3728}3775}
37293776
...@@ -3773,7 +3820,7 @@ pub fn printNode(...@@ -3773,7 +3820,7 @@ pub fn printNode(
3773 const ip = &zcu.intern_pool;3820 const ip = &zcu.intern_pool;
3774 const nav = ip.getNav(nmi.navIndex(elf));3821 const nav = ip.getNav(nmi.navIndex(elf));
3775 try w.print("({f}, {f})", .{3822 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 }),
3777 nav.fqn.fmt(ip),3824 nav.fqn.fmt(ip),
3778 });3825 });
3779 },3826 },
...@@ -3786,17 +3833,16 @@ pub fn printNode(...@@ -3786,17 +3833,16 @@ pub fn printNode(
3786 });3833 });
3787 },3834 },
3788 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{3835 inline .lazy_code, .lazy_const_data => |lmi| try w.print("({f})", .{
3789 Type.fromInterned(lmi.lazySymbol(elf).ty).fmt(.{3836 Value.fromInterned(lmi.lazySymbol(elf).key).fmtValue(
3790 .zcu = elf.base.comp.zcu.?,3837 .{ .zcu = elf.base.comp.zcu.?, .tid = tid },
3791 .tid = tid,3838 ),
3792 }),
3793 }),3839 }),
3794 }3840 }
3795 {3841 {
3796 const mf_node = &elf.mf.nodes.items[@intFromEnum(ni)];3842 const mf_node = &elf.mf.nodes.items[@intFromEnum(ni)];
3797 const off, const size = mf_node.location().resolve(&elf.mf);3843 const off, const size = mf_node.location().resolve(&elf.mf);
3798 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}\n", .{3844 try w.print(" index={d} offset=0x{x} size=0x{x} align=0x{x}{s}{s}{s}{s}\n", .{
3799 @intFromEnum(ni),3845 ni,
3800 off,3846 off,
3801 size,3847 size,
3802 mf_node.flags.alignment.toByteUnits(),3848 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 {...@@ -3116,8 +3116,8 @@ pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
3116 return self.getZigObject().?.freeNav(nav);3116 return self.getZigObject().?.freeNav(nav);
3117}3117}
31183118
3119pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {3119pub fn getNavVAddr(self: *MachO, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
3120 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);3120 return self.getZigObject().?.getNavVAddr(self, nav_index, reloc_info);
3121}3121}
31223122
3123pub fn lowerUav(3123pub fn lowerUav(
...@@ -3134,6 +3134,10 @@ pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.Re...@@ -3134,6 +3134,10 @@ pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.Re
3134 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);3134 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
3135}3135}
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
3137pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {3141pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {
3138 return self.getZigObject().?.getGlobalSymbol(self, name, lib_name);3142 return self.getZigObject().?.getGlobalSymbol(self, name, lib_name);
3139}3143}
src/link/MachO/ZigObject.zig+86-42
...@@ -18,10 +18,11 @@ atoms_extra: std.ArrayList(u32) = .empty,...@@ -18,10 +18,11 @@ atoms_extra: std.ArrayList(u32) = .empty,
1818
19/// Table of tracked LazySymbols.19/// Table of tracked LazySymbols.
20lazy_syms: LazySymbolTable = .{},20lazy_syms: LazySymbolTable = .{},
21/// Table of tracked LazySymbols that are deferred until flush.
22deferred_lazy_syms: LazySymbolTable = .{},
2123
22/// Table of tracked Navs.24/// Table of tracked Navs.
23navs: NavTable = .{},25navs: NavTable = .{},
24
25/// Table of tracked Uavs.26/// Table of tracked Uavs.
26uavs: UavTable = .{},27uavs: UavTable = .{},
2728
...@@ -78,13 +79,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -78,13 +79,14 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
78 self.atoms_indexes.deinit(allocator);79 self.atoms_indexes.deinit(allocator);
79 self.atoms_extra.deinit(allocator);80 self.atoms_extra.deinit(allocator);
8081
82 self.lazy_syms.deinit(allocator);
83 self.deferred_lazy_syms.deinit(allocator);
84
81 for (self.navs.values()) |*meta| {85 for (self.navs.values()) |*meta| {
82 meta.exports.deinit(allocator);86 meta.exports.deinit(allocator);
83 }87 }
84 self.navs.deinit(allocator);88 self.navs.deinit(allocator);
8589
86 self.lazy_syms.deinit(allocator);
87
88 for (self.uavs.values()) |*meta| {90 for (self.uavs.values()) |*meta| {
89 meta.exports.deinit(allocator);91 meta.exports.deinit(allocator);
90 }92 }
...@@ -559,30 +561,23 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F...@@ -559,30 +561,23 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
559 const diags = &macho_file.base.comp.link_diags;561 const diags = &macho_file.base.comp.link_diags;
560562
561 // Handle any lazy symbols that were emitted by incremental compilation.563 // Handle any lazy symbols that were emitted by incremental compilation.
562 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {564 {
563 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);565 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);
564 defer pt.deactivate();566 defer pt.deactivate();
565567
566 // Most lazy symbols can be updated on first use, but568 for (self.deferred_lazy_syms.values(), self.deferred_lazy_syms.keys()) |*metadata, key| {
567 // anyerror needs to wait for everything to be flushed.569 assert(metadata.text_state == .unused);
568 if (metadata.text_state != .unused) self.updateLazySymbol(570 if (metadata.const_state != .unused) self.updateLazySymbol(
569 macho_file,571 macho_file,
570 pt,572 pt,
571 .{ .kind = .code, .ty = .anyerror_type },573 .{ .kind = .deferred_const_data, .key = key },
572 metadata.text_symbol_index,574 metadata.const_symbol_index,
573 ) catch |err| switch (err) {575 ) catch |err| switch (err) {
574 error.OutOfMemory, error.LinkFailure => |e| return e,576 error.LinkFailure, error.CodegenFail => return error.LinkFailure,
575 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),577 error.OutOfMemory => |e| return e,
576 };578 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
577 if (metadata.const_state != .unused) self.updateLazySymbol(579 };
578 macho_file,580 }
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 };
586 }581 }
587 for (self.lazy_syms.values()) |*metadata| {582 for (self.lazy_syms.values()) |*metadata| {
588 if (metadata.text_state != .unused) metadata.text_state = .flushed;583 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...@@ -614,11 +609,10 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
614pub fn getNavVAddr(609pub fn getNavVAddr(
615 self: *ZigObject,610 self: *ZigObject,
616 macho_file: *MachO,611 macho_file: *MachO,
617 pt: Zcu.PerThread,
618 nav_index: InternPool.Nav.Index,612 nav_index: InternPool.Nav.Index,
619 reloc_info: link.File.RelocInfo,613 reloc_info: link.File.RelocInfo,
620) !u64 {614) !u64 {
621 const zcu = pt.zcu;615 const zcu = macho_file.base.comp.zcu.?;
622 const ip = &zcu.intern_pool;616 const ip = &zcu.intern_pool;
623 const nav = ip.getNav(nav_index);617 const nav = ip.getNav(nav_index);
624 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });618 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
...@@ -698,6 +692,51 @@ pub fn getUavVAddr(...@@ -698,6 +692,51 @@ pub fn getUavVAddr(
698 return vaddr;692 return vaddr;
699}693}
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
701pub fn lowerUav(740pub fn lowerUav(
702 self: *ZigObject,741 self: *ZigObject,
703 macho_file: *MachO,742 macho_file: *MachO,
...@@ -1355,35 +1394,34 @@ fn updateLazySymbol(...@@ -1355,35 +1394,34 @@ fn updateLazySymbol(
1355 const zcu = pt.zcu;1394 const zcu = pt.zcu;
1356 const gpa = zcu.gpa;1395 const gpa = zcu.gpa;
13571396
1358 var required_alignment: Atom.Alignment = .none;
1359 var aw: std.Io.Writer.Allocating = .init(gpa);1397 var aw: std.Io.Writer.Allocating = .init(gpa);
1360 defer aw.deinit();1398 defer aw.deinit();
13611399
1362 const name_str = blk: {1400 const name_str = blk: {
1363 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{1401 const name = try std.fmt.allocPrint(gpa, "__lazy_{t}_{f}", .{
1364 @tagName(lazy_sym.kind),1402 lazy_sym.kind, Value.fromInterned(lazy_sym.key).fmtValue(pt),
1365 Type.fromInterned(lazy_sym.ty).fmt(pt),
1366 });1403 });
1367 defer gpa.free(name);1404 defer gpa.free(name);
1368 break :blk try self.addString(gpa, name);1405 break :blk try self.addString(gpa, name);
1369 };1406 };
13701407
1371 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;1408 codegen.generateLazySymbol(
1372 try codegen.generateLazySymbol(
1373 &macho_file.base,1409 &macho_file.base,
1374 pt,1410 pt,
1375 src,1411 Type.fromInterned(lazy_sym.key).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded,
1376 lazy_sym,1412 lazy_sym,
1377 &required_alignment,
1378 &aw.writer,1413 &aw.writer,
1379 .none,1414 .none,
1380 .{ .atom_index = symbol_index },1415 .{ .atom_index = symbol_index },
1381 );1416 ) catch |err| switch (err) {
1417 error.WriteFailed => return error.OutOfMemory,
1418 else => |e| return e,
1419 };
1382 const code = aw.written();1420 const code = aw.written();
13831421
1384 const output_section_index = switch (lazy_sym.kind) {1422 const output_section_index = switch (lazy_sym.kind) {
1385 .code => macho_file.zig_text_sect_index.?,1423 .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.?,
1387 };1425 };
1388 const sym = &self.symbols.items[symbol_index];1426 const sym = &self.symbols.items[symbol_index];
1389 sym.name = name_str;1427 sym.name = name_str;
...@@ -1398,7 +1436,7 @@ fn updateLazySymbol(...@@ -1398,7 +1436,7 @@ fn updateLazySymbol(
1398 const atom = sym.getAtom(macho_file).?;1436 const atom = sym.getAtom(macho_file).?;
1399 atom.setAlive(true);1437 atom.setAlive(true);
1400 atom.name = name_str;1438 atom.name = name_str;
1401 atom.alignment = required_alignment;1439 atom.alignment = codegen.getLazySymbolInfo(.attributes, lazy_sym, zcu).required_alignment;
1402 atom.size = code.len;1440 atom.size = code.len;
1403 atom.out_n_sect = output_section_index;1441 atom.out_n_sect = output_section_index;
14041442
...@@ -1516,12 +1554,16 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1516,12 +1554,16 @@ pub fn getOrCreateMetadataForLazySymbol(
1516 pt: Zcu.PerThread,1554 pt: Zcu.PerThread,
1517 lazy_sym: link.File.LazySymbol,1555 lazy_sym: link.File.LazySymbol,
1518) !Symbol.Index {1556) !Symbol.Index {
1519 const gop = try self.lazy_syms.getOrPut(pt.zcu.gpa, lazy_sym.ty);1557 const lazy_syms = switch (lazy_sym.kind) {
1520 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();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();
1521 if (!gop.found_existing) gop.value_ptr.* = .{};1563 if (!gop.found_existing) gop.value_ptr.* = .{};
1522 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {1564 const symbol_index_ptr, const state_ptr = switch (lazy_sym.kind) {
1523 .code => .{ &gop.value_ptr.text_symbol_index, &gop.value_ptr.text_state },1565 .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 },
1525 };1567 };
1526 switch (state_ptr.*) {1568 switch (state_ptr.*) {
1527 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, .{}, macho_file),1569 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, .{}, macho_file),
...@@ -1530,8 +1572,10 @@ pub fn getOrCreateMetadataForLazySymbol(...@@ -1530,8 +1572,10 @@ pub fn getOrCreateMetadataForLazySymbol(
1530 }1572 }
1531 state_ptr.* = .pending_flush;1573 state_ptr.* = .pending_flush;
1532 const symbol_index = symbol_index_ptr.*;1574 const symbol_index = symbol_index_ptr.*;
1533 // anyerror needs to be deferred until flush1575 switch (lazy_sym.kind) {
1534 if (lazy_sym.ty != .anyerror_type) try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index);1576 .code, .const_data => try self.updateLazySymbol(macho_file, pt, lazy_sym, symbol_index),
1577 .deferred_const_data => {},
1578 }
1535 return symbol_index;1579 return symbol_index;
1536}1580}
15371581
src/target.zig+4
...@@ -948,5 +948,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt...@@ -948,5 +948,9 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
948 // being run in a separate thread from now on.948 // being run in a separate thread from now on.
949 else => true,949 else => true,
950 },950 },
951 .restricted_types => switch (backend) {
952 .stage2_c, .stage2_x86_64 => true,
953 else => false,
954 },
951 };955 };
952}956}