zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit f133bcba9f75562c324cced5385356ac2e08ae43 (tree)
parent 37295696ec5b1350333b88173187a3db8b199925
Author: Jacob Young <jacobly0@users.noreply.github.com>
Date:   Sat, 28 Oct 2023 15:10:27 -0400

x86_64: fix hazard between pic call and sysv cc

Diffstat:
Msrc/arch/x86_64/CodeGen.zig | 25++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig @@ -9971,6 +9971,7 @@ fn genCall(self: *Self, info: union(enum) { }), }; const fn_info = mod.typeToFunc(fn_ty).?; + const resolved_cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); const ExpectedContents = extern struct { var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)), @@ -10012,9 +10013,7 @@ fn genCall(self: *Self, info: union(enum) { } try self.spillEflagsIfOccupied(); - try self.spillRegisters(abi.getCallerPreservedRegs( - abi.resolveCallingConvention(fn_info.cc, self.target.*), - )); + try self.spillRegisters(abi.getCallerPreservedRegs(resolved_cc)); // set stack arguments first because this can clobber registers // also clobber spill arguments as we go @@ -10109,8 +10108,24 @@ fn genCall(self: *Self, info: union(enum) { const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); if (self.bin_file.options.pic) { - try self.genSetReg(.rax, Type.usize, .{ .load_symbol = sym.esym_index }); - try self.asmRegister(.{ ._, .call }, .rax); + const callee_reg: Register = switch (resolved_cc) { + .SysV => callee: { + if (!fn_info.is_var_args) break :callee .rax; + const param_regs = abi.getCAbiIntParamRegs(resolved_cc); + break :callee if (call_info.gp_count < param_regs.len) + param_regs[call_info.gp_count] + else + .r10; + }, + .Win64 => .rax, + else => unreachable, + }; + try self.genSetReg( + callee_reg, + Type.usize, + .{ .load_symbol = sym.esym_index }, + ); + try self.asmRegister(.{ ._, .call }, callee_reg); } else { _ = try self.addInst(.{ .tag = .call,