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