diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-10-08 16:08:05 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-10-10 22:47:47 -0700 |
| commit | 2e31077fe0e021858cf2f92f85e5fcfd12c41501 (patch) | |
| tree | 5f1e04aebfe2e0f440cd3d8426c645d1a723b97b /src/codegen | |
| parent | b2bc6073c8ada065906da9e3b5a4a2e7db04c21d (diff) | |
| download | zig-2e31077fe0e021858cf2f92f85e5fcfd12c41501.tar.gz zig-2e31077fe0e021858cf2f92f85e5fcfd12c41501.zip | |
Coff: implement threadlocal variables
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/x86_64/CodeGen.zig | 2 | ||||
| -rw-r--r-- | src/codegen/x86_64/Emit.zig | 84 |
2 files changed, 84 insertions, 2 deletions
diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index 2278a3df83..4fb935f01d 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -173685,7 +173685,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { const ty_nav = air_datas[@intFromEnum(inst)].ty_nav; const nav = ip.getNav(ty_nav.nav); const is_threadlocal = zcu.comp.config.any_non_single_threaded and nav.isThreadlocal(ip); - if (is_threadlocal) if (cg.mod.pic) { + if (is_threadlocal) if (cg.target.ofmt == .coff or cg.mod.pic) { try cg.spillRegisters(&.{ .rdi, .rax }); } else { try cg.spillRegisters(&.{.rax}); diff --git a/src/codegen/x86_64/Emit.zig b/src/codegen/x86_64/Emit.zig index 377171683b..3f4ef1b999 100644 --- a/src/codegen/x86_64/Emit.zig +++ b/src/codegen/x86_64/Emit.zig @@ -386,6 +386,82 @@ pub fn emitMir(emit: *Emit) Error!void { }, emit.lower.target), &.{}); }, else => unreachable, + } else if (emit.bin_file.cast(.coff2)) |coff| { + switch (emit.lower.target.cpu.arch) { + else => unreachable, + .x86 => { + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .eax }, + .{ .mem = .initSib(.qword, .{ + .base = .{ .reg = .fs }, + .disp = 4 * 11, + }) }, + }, emit.lower.target), &.{}); + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .edi }, + .{ .mem = .initSib(.dword, .{}) }, + }, emit.lower.target), &.{.{ + .op_index = 1, + .target = .{ + .index = @intFromEnum( + try coff.globalSymbol("__tls_index", null), + ), + .is_extern = false, + .type = .symbol, + }, + }}); + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .eax }, + .{ .mem = .initSib(.dword, .{ + .base = .{ .reg = .eax }, + .scale_index = .{ .index = .edi, .scale = 4 }, + }) }, + }, emit.lower.target), &.{}); + try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{ + lowered_inst.ops[0], + .{ .mem = .initSib(lowered_inst.ops[1].mem.sib.ptr_size, .{ + .base = .{ .reg = .eax }, + .disp = std.math.minInt(i32), + }) }, + }, emit.lower.target), reloc_info); + }, + .x86_64 => { + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .rax }, + .{ .mem = .initSib(.qword, .{ + .base = .{ .reg = .gs }, + .disp = 8 * 11, + }) }, + }, emit.lower.target), &.{}); + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .edi }, + .{ .mem = .initRip(.dword, 0) }, + }, emit.lower.target), &.{.{ + .op_index = 1, + .target = .{ + .index = @intFromEnum( + try coff.globalSymbol("_tls_index", null), + ), + .is_extern = false, + .type = .symbol, + }, + }}); + try emit.encodeInst(try .new(.none, .mov, &.{ + .{ .reg = .rax }, + .{ .mem = .initSib(.qword, .{ + .base = .{ .reg = .rax }, + .scale_index = .{ .index = .rdi, .scale = 8 }, + }) }, + }, emit.lower.target), &.{}); + try emit.encodeInst(try .new(.none, lowered_inst.encoding.mnemonic, &.{ + lowered_inst.ops[0], + .{ .mem = .initSib(lowered_inst.ops[1].mem.sib.ptr_size, .{ + .base = .{ .reg = .rax }, + .disp = std.math.minInt(i32), + }) }, + }, emit.lower.target), reloc_info); + }, + } } else return emit.fail("TODO implement relocs for {s}", .{ @tagName(emit.bin_file.tag), }); @@ -870,7 +946,13 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI .symbolnum = @intCast(reloc.target.index), }, }); - } else return emit.fail("TODO implement {s} reloc for {s}", .{ + } else if (emit.bin_file.cast(.coff2)) |coff| try coff.addReloc( + @enumFromInt(emit.atom_index), + end_offset - 4, + @enumFromInt(reloc.target.index), + reloc.off, + .{ .AMD64 = .SECREL }, + ) else return emit.fail("TODO implement {s} reloc for {s}", .{ @tagName(reloc.target.type), @tagName(emit.bin_file.tag), }), }; |
