authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 19:29:47+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 19:29:47+01:00
log2f0299c3cf3ce52c973eec62c88e87596e2d5260
tree94451bc321d652e0308048ed018fb85b5ece8c24
parent2ca809c32a69c286568814043019e444c1c85ff2

x64: account for multiple returns from functions

This is necessary to correctly adjust for spilling of the %rdi register in the callee.

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

src/arch/x86_64/CodeGen.zig+8-5
......@@ -49,7 +49,7 @@ arg_index: u32,
4949src_loc: Module.SrcLoc,
5050stack_align: u32,
5151
52ret_backpatch: ?Mir.Inst.Index = null,
52ret_backpatches: std.ArrayListUnmanaged(Mir.Inst.Index) = .{},
5353compare_flags_inst: ?Air.Inst.Index = null,
5454
5555/// MIR Instructions
......@@ -310,6 +310,7 @@ pub fn generate(
310310 std.AutoHashMap(Mir.Inst.Index, Air.Inst.Index).init(bin_file.allocator)
311311 else {},
312312 };
313 defer function.ret_backpatches.deinit(bin_file.allocator);
313314 defer function.stack.deinit(bin_file.allocator);
314315 defer function.blocks.deinit(bin_file.allocator);
315316 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
......@@ -473,8 +474,8 @@ fn gen(self: *Self) InnerError!void {
473474 };
474475 inline for (callee_preserved_regs) |reg, i| {
475476 if (self.register_manager.isRegAllocated(reg)) {
476 if (self.ret_backpatch) |inst| {
477 if (reg.to64() == .rdi) {
477 if (reg.to64() == .rdi) {
478 for (self.ret_backpatches.items) |inst| {
478479 const ops = Mir.Ops.decode(self.mir_instructions.items(.ops)[inst]);
479480 self.mir_instructions.set(inst, Mir.Inst{
480481 .tag = .mov,
......@@ -3312,7 +3313,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
33123313 self.register_manager.freezeRegs(&.{ .rax, .rcx, .rdi });
33133314 defer self.register_manager.unfreezeRegs(&.{ .rax, .rcx, .rdi });
33143315 const reg = try self.register_manager.allocReg(null);
3315 self.ret_backpatch = try self.addInst(.{
3316 const backpatch = try self.addInst(.{
33163317 .tag = .mov,
33173318 .ops = (Mir.Ops{
33183319 .reg1 = reg,
......@@ -3320,6 +3321,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
33203321 }).encode(),
33213322 .data = undefined,
33223323 });
3324 try self.ret_backpatches.append(self.gpa, backpatch);
33233325 try self.genSetStack(ret_ty, 0, operand, .{
33243326 .source_stack_base = .rbp,
33253327 .dest_stack_base = reg,
......@@ -3354,7 +3356,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
33543356 self.register_manager.freezeRegs(&.{ .rax, .rcx, .rdi });
33553357 defer self.register_manager.unfreezeRegs(&.{ .rax, .rcx, .rdi });
33563358 const reg = try self.register_manager.allocReg(null);
3357 self.ret_backpatch = try self.addInst(.{
3359 const backpatch = try self.addInst(.{
33583360 .tag = .mov,
33593361 .ops = (Mir.Ops{
33603362 .reg1 = reg,
......@@ -3362,6 +3364,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
33623364 }).encode(),
33633365 .data = undefined,
33643366 });
3367 try self.ret_backpatches.append(self.gpa, backpatch);
33653368 try self.genInlineMemcpy(0, elem_ty, ptr, .{
33663369 .source_stack_base = .rbp,
33673370 .dest_stack_base = reg,