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 {...@@ -439,16 +439,17 @@ fn gen(self: *Self) InnerError!void {
439 });439 });
440440
441 if (self.ret_mcv == .stack_offset) {441 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
443 // register which the callee is free to clobber. Therefore, we purposely443 // register which the callee is free to clobber. Therefore, we purposely
444 // spill it to stack immediately.444 // spill it to stack immediately.
445 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset + 8, 8);445 const stack_offset = mem.alignForwardGeneric(u32, self.next_stack_offset + 8, 8);
446 self.next_stack_offset = stack_offset;446 self.next_stack_offset = stack_offset;
447 self.max_end_stack = @maximum(self.max_end_stack, self.next_stack_offset);447 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 }, .{});
450 self.ret_mcv = MCValue{ .stack_offset = @intCast(i32, stack_offset) };451 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 });
452 }453 }
453454
454 _ = try self.addInst(.{455 _ = try self.addInst(.{
...@@ -831,7 +832,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -831,7 +832,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
831fn processDeath(self: *Self, inst: Air.Inst.Index) void {832fn processDeath(self: *Self, inst: Air.Inst.Index) void {
832 const air_tags = self.air.instructions.items(.tag);833 const air_tags = self.air.instructions.items(.tag);
833 if (air_tags[inst] == .constant) return; // Constants are immortal.834 if (air_tags[inst] == .constant) return; // Constants are immortal.
834 log.debug("%{d} => {}", .{ inst, MCValue.dead });835 log.debug("%{d} => {}", .{ inst, MCValue{ .dead = {} } });
835 // When editing this function, note that the logic must synchronize with `reuseOperand`.836 // When editing this function, note that the logic must synchronize with `reuseOperand`.
836 const prev_value = self.getResolvedInstValue(inst);837 const prev_value = self.getResolvedInstValue(inst);
837 const branch = &self.branch_stack.items[self.branch_stack.items.len - 1];838 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....@@ -3960,7 +3961,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3960 try self.register_manager.getReg(reg, null);3961 try self.register_manager.getReg(reg, null);
3961 }3962 }
39623963
3963 const rdi_lock: ?RegisterLock = blk: {3964 const ret_reg_lock: ?RegisterLock = blk: {
3964 if (info.return_value == .stack_offset) {3965 if (info.return_value == .stack_offset) {
3965 const ret_ty = fn_ty.fnReturnType();3966 const ret_ty = fn_ty.fnReturnType();
3966 const ret_abi_size = @intCast(u32, ret_ty.abiSize(self.target.*));3967 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....@@ -3968,17 +3969,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
3968 const stack_offset = @intCast(i32, try self.allocMem(inst, ret_abi_size, ret_abi_align));3969 const stack_offset = @intCast(i32, try self.allocMem(inst, ret_abi_size, ret_abi_align));
3969 log.debug("airCall: return value on stack at offset {}", .{stack_offset});3970 log.debug("airCall: return value on stack at offset {}", .{stack_offset});
39703971
3971 try self.register_manager.getReg(.rdi, null);3972 const ret_reg = abi.getCAbiIntParamRegs(self.target.*)[0];
3972 try self.genSetReg(Type.usize, .rdi, .{ .ptr_stack_offset = stack_offset });3973 try self.register_manager.getReg(ret_reg, null);
3973 const rdi_lock = self.register_manager.lockRegAssumeUnused(.rdi);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
3975 info.return_value.stack_offset = stack_offset;3977 info.return_value.stack_offset = stack_offset;
39763978
3977 break :blk rdi_lock;3979 break :blk ret_reg_lock;
3978 }3980 }
3979 break :blk null;3981 break :blk null;
3980 };3982 };
3981 defer if (rdi_lock) |lock| self.register_manager.unlockReg(lock);3983 defer if (ret_reg_lock) |lock| self.register_manager.unlockReg(lock);
39823984
3983 for (args) |arg, arg_i| {3985 for (args) |arg, arg_i| {
3984 const mc_arg = info.args[arg_i];3986 const mc_arg = info.args[arg_i];
...@@ -7292,11 +7294,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -7292,11 +7294,12 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
7292 assert(ret_ty.isError());7294 assert(ret_ty.isError());
7293 result.return_value = .{ .immediate = 0 };7295 result.return_value = .{ .immediate = 0 };
7294 } else if (ret_ty_size <= 8) {7296 } 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 };
7296 } else {7299 } else {
7297 // We simply make the return MCValue a stack offset. However, the actual value7300 // We simply make the return MCValue a stack offset. However, the actual value
7298 // for the offset will be populated later. We will also push the stack offset7301 // 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.
7300 result.return_value = .{ .stack_offset = 0 };7303 result.return_value = .{ .stack_offset = 0 };
7301 }7304 }
7302 }7305 }