authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-28 15:10:27-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-29 05:15:35-04:00
logf133bcba9f75562c324cced5385356ac2e08ae43
tree0c7682b8058e8db12beb7b5cfdd0493f78765518
parent37295696ec5b1350333b88173187a3db8b199925

x86_64: fix hazard between pic call and sysv cc


1 files changed, 20 insertions(+), 5 deletions(-)

src/arch/x86_64/CodeGen.zig+20-5
...@@ -9971,6 +9971,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -9971,6 +9971,7 @@ fn genCall(self: *Self, info: union(enum) {
9971 }),9971 }),
9972 };9972 };
9973 const fn_info = mod.typeToFunc(fn_ty).?;9973 const fn_info = mod.typeToFunc(fn_ty).?;
9974 const resolved_cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);
99749975
9975 const ExpectedContents = extern struct {9976 const ExpectedContents = extern struct {
9976 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),9977 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),
...@@ -10012,9 +10013,7 @@ fn genCall(self: *Self, info: union(enum) {...@@ -10012,9 +10013,7 @@ fn genCall(self: *Self, info: union(enum) {
10012 }10013 }
1001310014
10014 try self.spillEflagsIfOccupied();10015 try self.spillEflagsIfOccupied();
10015 try self.spillRegisters(abi.getCallerPreservedRegs(10016 try self.spillRegisters(abi.getCallerPreservedRegs(resolved_cc));
10016 abi.resolveCallingConvention(fn_info.cc, self.target.*),
10017 ));
1001810017
10019 // set stack arguments first because this can clobber registers10018 // set stack arguments first because this can clobber registers
10020 // also clobber spill arguments as we go10019 // also clobber spill arguments as we go
...@@ -10109,8 +10108,24 @@ fn genCall(self: *Self, info: union(enum) {...@@ -10109,8 +10108,24 @@ fn genCall(self: *Self, info: union(enum) {
10109 const sym = elf_file.symbol(sym_index);10108 const sym = elf_file.symbol(sym_index);
10110 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);10109 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
10111 if (self.bin_file.options.pic) {10110 if (self.bin_file.options.pic) {
10112 try self.genSetReg(.rax, Type.usize, .{ .load_symbol = sym.esym_index });10111 const callee_reg: Register = switch (resolved_cc) {
10113 try self.asmRegister(.{ ._, .call }, .rax);10112 .SysV => callee: {
10113 if (!fn_info.is_var_args) break :callee .rax;
10114 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
10115 break :callee if (call_info.gp_count < param_regs.len)
10116 param_regs[call_info.gp_count]
10117 else
10118 .r10;
10119 },
10120 .Win64 => .rax,
10121 else => unreachable,
10122 };
10123 try self.genSetReg(
10124 callee_reg,
10125 Type.usize,
10126 .{ .load_symbol = sym.esym_index },
10127 );
10128 try self.asmRegister(.{ ._, .call }, callee_reg);
10114 } else {10129 } else {
10115 _ = try self.addInst(.{10130 _ = try self.addInst(.{
10116 .tag = .call,10131 .tag = .call,