From 090186a0c26447d99417dad9f1ba8bde49579191 Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Mon, 23 Jan 2023 21:08:43 +0100 Subject: [PATCH] stage2 AArch64: move copy-register-arg-to-stack code to fn prologue This enhances the debugging experience as upon encountering a breakpoint in a function, all arguments passed as registers have already been moved to the stack, ready to be inspected by the debugger. --- src/arch/aarch64/CodeGen.zig | 57 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 200bf3b8e0..0efd34937a 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -181,6 +181,7 @@ const DbgInfoReloc = struct { else => unreachable, } } + fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { switch (function.debug_output) { .dwarf => |dw| { @@ -527,6 +528,28 @@ fn gen(self: *Self) !void { self.ret_mcv = MCValue{ .stack_offset = stack_offset }; } + for (self.args) |*arg, arg_index| { + // Copy register arguments to the stack + switch (arg.*) { + .register => |reg| { + // The first AIR instructions of the main body are guaranteed + // to be the functions arguments + const inst = self.air.getMainBody()[arg_index]; + assert(self.air.instructions.items(.tag)[inst] == .arg); + + const ty = self.air.typeOfIndex(inst); + + const abi_size = @intCast(u32, ty.abiSize(self.target.*)); + const abi_align = ty.abiAlignment(self.target.*); + const stack_offset = try self.allocMem(abi_size, abi_align, inst); + try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); + + arg.* = MCValue{ .stack_offset = stack_offset }; + }, + else => {}, + } + } + _ = try self.addInst(.{ .tag = .dbg_prologue_end, .data = .{ .nop = {} }, @@ -4163,45 +4186,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { self.arg_index += 1; const ty = self.air.typeOfIndex(inst); - const result = self.args[arg_index]; + const tag = self.air.instructions.items(.tag)[inst]; const src_index = self.air.instructions.items(.data)[inst].arg.src_index; const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index); - const mcv = switch (result) { - // Copy registers to the stack - .register => |reg| blk: { - const mod = self.bin_file.options.module.?; - const abi_size = math.cast(u32, ty.abiSize(self.target.*)) orelse { - return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)}); - }; - const abi_align = ty.abiAlignment(self.target.*); - const stack_offset = try self.allocMem(abi_size, abi_align, inst); - try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); - - break :blk MCValue{ .stack_offset = stack_offset }; - }, - else => result, - }; - - const tag = self.air.instructions.items(.tag)[inst]; try self.dbg_info_relocs.append(self.gpa, .{ .tag = tag, .ty = ty, .name = name, - .mcv = result, + .mcv = self.args[arg_index], }); - if (self.liveness.isUnused(inst)) - return self.finishAirBookkeeping(); - - switch (mcv) { - .register => |reg| { - self.register_manager.getRegAssumeFree(reg, inst); - }, - else => {}, - } - - return self.finishAir(inst, mcv, .{ .none, .none, .none }); + const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; + return self.finishAir(inst, result, .{ .none, .none, .none }); } fn airBreakpoint(self: *Self) !void {