x86_64: increase passing test coverage on windows

Now that codegen has no references to linker state this is much easier.

Closes #24153
This commit is contained in:
Jacob Young
2025-06-13 04:41:21 -04:00
parent ed37a1a33c
commit 1f98c98fff
51 changed files with 12489 additions and 8083 deletions

View File

@@ -810,7 +810,7 @@ fn lowerUavRef(
const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
.mcv => {},
.sym_index => {},
.fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
}
@@ -920,6 +920,90 @@ pub const LinkerLoad = struct {
sym_index: u32,
};
pub const SymbolResult = union(enum) { sym_index: u32, fail: *ErrorMsg };
pub fn genNavRef(
lf: *link.File,
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
nav_index: InternPool.Nav.Index,
target: *const std.Target,
) CodeGenError!SymbolResult {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const nav = ip.getNav(nav_index);
log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
.{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
else
.{ .none, .internal, false };
if (lf.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
switch (linkage) {
.internal => {
const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
return .{ .sym_index = sym_index };
},
.strong, .weak => {
const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
.weak => zo.symbol(sym_index).flags.weak = true,
.link_once => unreachable,
}
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
return .{ .sym_index = sym_index };
},
.link_once => unreachable,
}
} else if (lf.cast(.macho)) |macho_file| {
const zo = macho_file.getZigObject().?;
switch (linkage) {
.internal => {
const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
return .{ .sym_index = sym_index };
},
.strong, .weak => {
const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
.weak => zo.symbols.items[sym_index].flags.weak = true,
.link_once => unreachable,
}
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
return .{ .sym_index = sym_index };
},
.link_once => unreachable,
}
} else if (lf.cast(.coff)) |coff_file| {
// TODO audit this
switch (linkage) {
.internal => {
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
return .{ .sym_index = sym_index };
},
.strong, .weak => {
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
return .{ .sym_index = global_index };
},
.link_once => unreachable,
}
} else if (lf.cast(.plan9)) |p9| {
return .{ .sym_index = try p9.seeNav(pt, nav_index) };
} else {
const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
return .{ .fail = msg };
}
}
/// deprecated legacy type
pub const GenResult = union(enum) {
mcv: MCValue,
fail: *ErrorMsg,
@@ -951,89 +1035,6 @@ pub const GenResult = union(enum) {
};
};
pub fn genNavRef(
lf: *link.File,
pt: Zcu.PerThread,
src_loc: Zcu.LazySrcLoc,
nav_index: InternPool.Nav.Index,
target: *const std.Target,
) CodeGenError!GenResult {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
const nav = ip.getNav(nav_index);
log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
.{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
else
.{ .none, .internal, false };
if (lf.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
switch (linkage) {
.internal => {
const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.strong, .weak => {
const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
.weak => zo.symbol(sym_index).flags.weak = true,
.link_once => unreachable,
}
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.link_once => unreachable,
}
} else if (lf.cast(.macho)) |macho_file| {
const zo = macho_file.getZigObject().?;
switch (linkage) {
.internal => {
const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.strong, .weak => {
const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
switch (linkage) {
.internal => unreachable,
.strong => {},
.weak => zo.symbols.items[sym_index].flags.weak = true,
.link_once => unreachable,
}
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.link_once => unreachable,
}
} else if (lf.cast(.coff)) |coff_file| {
// TODO audit this
switch (linkage) {
.internal => {
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
return .{ .mcv = .{ .lea_symbol = sym_index } };
},
.strong, .weak => {
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
return .{ .mcv = .{ .lea_symbol = global_index } };
},
.link_once => unreachable,
}
} else if (lf.cast(.plan9)) |p9| {
const atom_index = try p9.seeNav(pt, nav_index);
const atom = p9.getAtom(atom_index);
return .{ .mcv = .{ .memory = atom.getOffsetTableAddress(p9) } };
} else {
const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
return .{ .fail = msg };
}
}
/// deprecated legacy code path
pub fn genTypedValue(
lf: *link.File,
@@ -1042,30 +1043,28 @@ pub fn genTypedValue(
val: Value,
target: *const std.Target,
) CodeGenError!GenResult {
return switch (try lowerValue(pt, val, target)) {
const res = try lowerValue(pt, val, target);
return switch (res) {
.none => .{ .mcv = .none },
.undef => .{ .mcv = .undef },
.immediate => |imm| .{ .mcv = .{ .immediate = imm } },
.lea_nav => |nav| genNavRef(lf, pt, src_loc, nav, target),
.lea_uav => |uav| switch (try lf.lowerUav(
.lea_nav => |nav| switch (try genNavRef(lf, pt, src_loc, nav, target)) {
.sym_index => |sym_index| .{ .mcv = .{ .lea_symbol = sym_index } },
.fail => |em| .{ .fail = em },
},
.load_uav, .lea_uav => |uav| switch (try lf.lowerUav(
pt,
uav.val,
Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
src_loc,
)) {
.mcv => |mcv| .{ .mcv = switch (mcv) {
.sym_index => |sym_index| .{ .mcv = switch (res) {
else => unreachable,
.load_direct => |sym_index| .{ .lea_direct = sym_index },
.load_symbol => |sym_index| .{ .lea_symbol = sym_index },
.load_uav => .{ .load_symbol = sym_index },
.lea_uav => .{ .lea_symbol = sym_index },
} },
.fail => |em| .{ .fail = em },
},
.load_uav => |uav| lf.lowerUav(
pt,
uav.val,
Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
src_loc,
),
};
}
@@ -1076,8 +1075,8 @@ const LowerResult = union(enum) {
/// such as ARM, the immediate will never exceed 32-bits.
immediate: u64,
lea_nav: InternPool.Nav.Index,
lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
};
pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {