authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-03 15:12:30+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:57+02:00
log619d82234ecbb8a130e827e9de6f545288649a58
treee7e63192379fd12cc55e34d868c8041ea2960f0e
parent28f525baa4ff0480043a16dd2467f231c8d6526a

x86_64: clean up return registers for unspecified cc


1 files changed, 15 insertions(+), 12 deletions(-)

src/arch/x86_64/CodeGen.zig+15-12
......@@ -439,16 +439,17 @@ fn gen(self: *Self) InnerError!void {
439439 });
440440
441441 if (self.ret_mcv == .stack_offset) {
442 // The address where to store the return value for the caller is in `.rdi`
442 // The address where to store the return value for the caller is in a
443443 // register which the callee is free to clobber. Therefore, we purposely
444444 // spill it to stack immediately.
445445 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset + 8, 8);
446446 self.next_stack_offset = stack_offset;
447447 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);
448448
449 try self.genSetStack(Type.usize, @intCast(i32, stack_offset), MCValue{ .register = .rdi }, .{});
449 const ret_reg = abi.getCAbiIntParamRegs(self.target.*)[0];
450 try self.genSetStack(Type.usize, @intCast(i32, stack_offset), MCValue{ .register = ret_reg }, .{});
450451 self.ret_mcv = MCValue{ .stack_offset = @intCast(i32, stack_offset) };
451 log.debug("gen: spilling .rdi to stack at offset {}", .{stack_offset});
452 log.debug("gen: spilling {s} to stack at offset {}", .{ @tagName(ret_reg), stack_offset });
452453 }
453454
454455 _ = try self.addInst(.{
......@@ -831,7 +832,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
831832fn processDeath(self: *Self, inst: Air.Inst.Index) void {
832833 const air_tags = self.air.instructions.items(.tag);
833834 if (air_tags[inst] == .constant) return; // Constants are immortal.
834 log.debug("%{d} => {}", .{ inst, MCValue.dead });
835 log.debug("%{d} => {}", .{ inst, MCValue{ .dead = {} } });
835836 // When editing this function, note that the logic must synchronize with `reuseOperand`.
836837 const prev_value = self.getResolvedInstValue(inst);
837838 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];
......@@ -3960,7 +3961,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
39603961 try self.register_manager.getReg(reg, null);
39613962 }
39623963
3963 const rdi_lock: ?RegisterLock = blk: {
3964 const ret_reg_lock: ?RegisterLock = blk: {
39643965 if (info.return_value == .stack_offset) {
39653966 const ret_ty = fn_ty.fnReturnType();
39663967 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));
......@@ -3968,17 +3969,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
39683969 const stack_offset = @intCast(i32, try self.allocMem(inst, ret_abi_size, ret_abi_align));
39693970 log.debug("airCall: return value on stack at offset {}", .{stack_offset});
39703971
3971 try self.register_manager.getReg(.rdi, null);
3972 try self.genSetReg(Type.usize, .rdi, .{ .ptr_stack_offset = stack_offset });
3973 const rdi_lock = self.register_manager.lockRegAssumeUnused(.rdi);
3972 const ret_reg = abi.getCAbiIntParamRegs(self.target.*)[0];
3973 try self.register_manager.getReg(ret_reg, null);
3974 try self.genSetReg(Type.usize, ret_reg, .{ .ptr_stack_offset = stack_offset });
3975 const ret_reg_lock = self.register_manager.lockRegAssumeUnused(ret_reg);
39743976
39753977 info.return_value.stack_offset = stack_offset;
39763978
3977 break :blk rdi_lock;
3979 break :blk ret_reg_lock;
39783980 }
39793981 break :blk null;
39803982 };
3981 defer if (rdi_lock) |lock| self.register_manager.unlockReg(lock);
3983 defer if (ret_reg_lock) |lock| self.register_manager.unlockReg(lock);
39823984
39833985 for (args) |arg, arg_i| {
39843986 const mc_arg = info.args[arg_i];
......@@ -7292,11 +7294,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
72927294 assert(ret_ty.isError());
72937295 result.return_value = .{ .immediate = 0 };
72947296 } else if (ret_ty_size <= 8) {
7295 result.return_value = .{ .register = .rdi };
7297 const aliased_reg = registerAlias(abi.getCAbiIntReturnRegs(self.target.*)[0], ret_ty_size);
7298 result.return_value = .{ .register = aliased_reg };
72967299 } else {
72977300 // We simply make the return MCValue a stack offset. However, the actual value
72987301 // for the offset will be populated later. We will also push the stack offset
7299 // value into .rdi register when we resolve the offset.
7302 // value into an appropriate register when we resolve the offset.
73007303 result.return_value = .{ .stack_offset = 0 };
73017304 }
73027305 }