| ... | @@ -181,6 +181,7 @@ const DbgInfoReloc = struct { | ... | @@ -181,6 +181,7 @@ const DbgInfoReloc = struct { |
| 181 | else => unreachable, | 181 | else => unreachable, |
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| | 184 | |
| 184 | fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { | 185 | fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { |
| 185 | switch (function.debug_output) { | 186 | switch (function.debug_output) { |
| 186 | .dwarf => |dw| { | 187 | .dwarf => |dw| { |
| ... | @@ -527,6 +528,28 @@ fn gen(self: *Self) !void { | ... | @@ -527,6 +528,28 @@ fn gen(self: *Self) !void { |
| 527 | self.ret_mcv = MCValue{ .stack_offset = stack_offset }; | 528 | self.ret_mcv = MCValue{ .stack_offset = stack_offset }; |
| 528 | } | 529 | } |
| 529 | | 530 | |
| | 531 | for (self.args) |*arg, arg_index| { |
| | 532 | // Copy register arguments to the stack |
| | 533 | switch (arg.*) { |
| | 534 | .register => |reg| { |
| | 535 | // The first AIR instructions of the main body are guaranteed |
| | 536 | // to be the functions arguments |
| | 537 | const inst = self.air.getMainBody()[arg_index]; |
| | 538 | assert(self.air.instructions.items(.tag)[inst] == .arg); |
| | 539 | |
| | 540 | const ty = self.air.typeOfIndex(inst); |
| | 541 | |
| | 542 | const abi_size = @intCast(u32, ty.abiSize(self.target.*)); |
| | 543 | const abi_align = ty.abiAlignment(self.target.*); |
| | 544 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| | 545 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
| | 546 | |
| | 547 | arg.* = MCValue{ .stack_offset = stack_offset }; |
| | 548 | }, |
| | 549 | else => {}, |
| | 550 | } |
| | 551 | } |
| | 552 | |
| 530 | _ = try self.addInst(.{ | 553 | _ = try self.addInst(.{ |
| 531 | .tag = .dbg_prologue_end, | 554 | .tag = .dbg_prologue_end, |
| 532 | .data = .{ .nop = {} }, | 555 | .data = .{ .nop = {} }, |
| ... | @@ -4163,45 +4186,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4163,45 +4186,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 4163 | self.arg_index += 1; | 4186 | self.arg_index += 1; |
| 4164 | | 4187 | |
| 4165 | const ty = self.air.typeOfIndex(inst); | 4188 | const ty = self.air.typeOfIndex(inst); |
| 4166 | const result = self.args[arg_index]; | 4189 | const tag = self.air.instructions.items(.tag)[inst]; |
| 4167 | const src_index = self.air.instructions.items(.data)[inst].arg.src_index; | 4190 | const src_index = self.air.instructions.items(.data)[inst].arg.src_index; |
| 4168 | const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index); | 4191 | const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index); |
| 4169 | | 4192 | |
| 4170 | const mcv = switch (result) { | | |
| 4171 | // Copy registers to the stack | | |
| 4172 | .register => |reg| blk: { | | |
| 4173 | const mod = self.bin_file.options.module.?; | | |
| 4174 | const abi_size = math.cast(u32, ty.abiSize(self.target.*)) orelse { | | |
| 4175 | return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)}); | | |
| 4176 | }; | | |
| 4177 | const abi_align = ty.abiAlignment(self.target.*); | | |
| 4178 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); | | |
| 4179 | try self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | | |
| 4180 | | | |
| 4181 | break :blk MCValue{ .stack_offset = stack_offset }; | | |
| 4182 | }, | | |
| 4183 | else => result, | | |
| 4184 | }; | | |
| 4185 | | | |
| 4186 | const tag = self.air.instructions.items(.tag)[inst]; | | |
| 4187 | try self.dbg_info_relocs.append(self.gpa, .{ | 4193 | try self.dbg_info_relocs.append(self.gpa, .{ |
| 4188 | .tag = tag, | 4194 | .tag = tag, |
| 4189 | .ty = ty, | 4195 | .ty = ty, |
| 4190 | .name = name, | 4196 | .name = name, |
| 4191 | .mcv = result, | 4197 | .mcv = self.args[arg_index], |
| 4192 | }); | 4198 | }); |
| 4193 | | 4199 | |
| 4194 | if (self.liveness.isUnused(inst)) | 4200 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4195 | return self.finishAirBookkeeping(); | 4201 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| 4196 | | | |
| 4197 | switch (mcv) { | | |
| 4198 | .register => |reg| { | | |
| 4199 | self.register_manager.getRegAssumeFree(reg, inst); | | |
| 4200 | }, | | |
| 4201 | else => {}, | | |
| 4202 | } | | |
| 4203 | | | |
| 4204 | return self.finishAir(inst, mcv, .{ .none, .none, .none }); | | |
| 4205 | } | 4202 | } |
| 4206 | | 4203 | |
| 4207 | fn airBreakpoint(self: *Self) !void { | 4204 | fn airBreakpoint(self: *Self) !void { |