| ... | ... | @@ -3797,64 +3797,68 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 3797 | 3797 | const ty = self.air.typeOfIndex(inst); |
| 3798 | 3798 | const mcv = self.args[arg_index]; |
| 3799 | 3799 | const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index); |
| 3800 | | const name_with_null = name.ptr[0 .. name.len + 1]; |
| 3801 | 3800 | |
| 3802 | 3801 | if (self.liveness.isUnused(inst)) |
| 3803 | 3802 | return self.finishAirBookkeeping(); |
| 3804 | 3803 | |
| 3805 | | const dst_mcv: MCValue = blk: { |
| 3806 | | switch (mcv) { |
| 3807 | | .register => |reg| { |
| 3808 | | self.register_manager.getRegAssumeFree(reg.to64(), inst); |
| 3809 | | switch (self.debug_output) { |
| 3810 | | .dwarf => |dw| { |
| 3811 | | const dbg_info = &dw.dbg_info; |
| 3812 | | try dbg_info.ensureUnusedCapacity(3); |
| 3813 | | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); |
| 3814 | | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 3815 | | 1, // ULEB128 dwarf expression length |
| 3816 | | reg.dwarfLocOp(), |
| 3817 | | }); |
| 3818 | | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 3819 | | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 3820 | | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 3821 | | }, |
| 3822 | | .plan9 => {}, |
| 3823 | | .none => {}, |
| 3824 | | } |
| 3825 | | break :blk mcv; |
| 3826 | | }, |
| 3827 | | .stack_offset => |off| { |
| 3828 | | const offset = @intCast(i32, self.max_end_stack) - off + 16; |
| 3829 | | switch (self.debug_output) { |
| 3830 | | .dwarf => |dw| { |
| 3831 | | const dbg_info = &dw.dbg_info; |
| 3832 | | try dbg_info.ensureUnusedCapacity(8); |
| 3833 | | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); |
| 3834 | | const fixup = dbg_info.items.len; |
| 3835 | | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 3836 | | 1, // we will backpatch it after we encode the displacement in LEB128 |
| 3837 | | DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer |
| 3838 | | }); |
| 3839 | | leb128.writeILEB128(dbg_info.writer(), offset) catch unreachable; |
| 3840 | | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 3841 | | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 3842 | | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 3843 | | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 3844 | | |
| 3845 | | }, |
| 3846 | | .plan9 => {}, |
| 3847 | | .none => {}, |
| 3848 | | } |
| 3849 | | break :blk MCValue{ .stack_offset = -offset }; |
| 3850 | | }, |
| 3851 | | else => return self.fail("TODO implement arg for {}", .{mcv}), |
| 3852 | | } |
| 3804 | const dst_mcv: MCValue = switch (mcv) { |
| 3805 | .register => |reg| blk: { |
| 3806 | self.register_manager.getRegAssumeFree(reg.to64(), inst); |
| 3807 | break :blk MCValue{ .register = reg }; |
| 3808 | }, |
| 3809 | .stack_offset => |off| blk: { |
| 3810 | const offset = @intCast(i32, self.max_end_stack) - off + 16; |
| 3811 | break :blk MCValue{ .stack_offset = -offset }; |
| 3812 | }, |
| 3813 | else => return self.fail("TODO implement arg for {}", .{mcv}), |
| 3853 | 3814 | }; |
| 3815 | try self.genArgDbgInfo(ty, name, dst_mcv); |
| 3854 | 3816 | |
| 3855 | 3817 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); |
| 3856 | 3818 | } |
| 3857 | 3819 | |
| 3820 | fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { |
| 3821 | const name_with_null = name.ptr[0 .. name.len + 1]; |
| 3822 | switch (self.debug_output) { |
| 3823 | .dwarf => |dw| { |
| 3824 | const dbg_info = &dw.dbg_info; |
| 3825 | switch (mcv) { |
| 3826 | .register => |reg| { |
| 3827 | try dbg_info.ensureUnusedCapacity(3); |
| 3828 | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); |
| 3829 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 3830 | 1, // ULEB128 dwarf expression length |
| 3831 | reg.dwarfLocOp(), |
| 3832 | }); |
| 3833 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 3834 | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 3835 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 3836 | }, |
| 3837 | |
| 3838 | .stack_offset => |off| { |
| 3839 | try dbg_info.ensureUnusedCapacity(8); |
| 3840 | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); |
| 3841 | const fixup = dbg_info.items.len; |
| 3842 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 3843 | 1, // we will backpatch it after we encode the displacement in LEB128 |
| 3844 | Register.rbp.dwarfLocOpDeref(), // TODO handle -fomit-frame-pointer |
| 3845 | }); |
| 3846 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; |
| 3847 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 3848 | try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); |
| 3849 | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 3850 | dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 3851 | |
| 3852 | }, |
| 3853 | |
| 3854 | else => unreachable, // not a valid function parameter |
| 3855 | } |
| 3856 | }, |
| 3857 | .plan9 => {}, |
| 3858 | .none => {}, |
| 3859 | } |
| 3860 | } |
| 3861 | |
| 3858 | 3862 | fn airBreakpoint(self: *Self) !void { |
| 3859 | 3863 | _ = try self.addInst(.{ |
| 3860 | 3864 | .tag = .interrupt, |
| ... | ... | @@ -4424,7 +4428,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4424 | 4428 | } |
| 4425 | 4429 | |
| 4426 | 4430 | fn genVarDbgInfo( |
| 4427 | | self: *Self, |
| 4431 | self: Self, |
| 4428 | 4432 | tag: Air.Inst.Tag, |
| 4429 | 4433 | ty: Type, |
| 4430 | 4434 | mcv: MCValue, |
| ... | ... | @@ -4445,17 +4449,23 @@ fn genVarDbgInfo( |
| 4445 | 4449 | reg.dwarfLocOp(), |
| 4446 | 4450 | }); |
| 4447 | 4451 | }, |
| 4448 | | .ptr_stack_offset, .stack_offset => |off| { |
| 4452 | |
| 4453 | .ptr_stack_offset, |
| 4454 | .stack_offset, |
| 4455 | => |off| { |
| 4449 | 4456 | try dbg_info.ensureUnusedCapacity(7); |
| 4450 | 4457 | const fixup = dbg_info.items.len; |
| 4451 | 4458 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4452 | 4459 | 1, // we will backpatch it after we encode the displacement in LEB128 |
| 4453 | | DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer |
| 4460 | Register.rbp.dwarfLocOpDeref(), // TODO handle -fomit-frame-pointer |
| 4454 | 4461 | }); |
| 4455 | 4462 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; |
| 4456 | 4463 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 4457 | 4464 | }, |
| 4458 | | .memory, .linker_load => { |
| 4465 | |
| 4466 | .memory, |
| 4467 | .linker_load, |
| 4468 | => { |
| 4459 | 4469 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); |
| 4460 | 4470 | const is_ptr = switch (tag) { |
| 4461 | 4471 | .dbg_var_ptr => true, |
| ... | ... | @@ -4494,27 +4504,23 @@ fn genVarDbgInfo( |
| 4494 | 4504 | else => {}, |
| 4495 | 4505 | } |
| 4496 | 4506 | }, |
| 4507 | |
| 4497 | 4508 | .immediate => |x| { |
| 4498 | | const signedness: std.builtin.Signedness = blk: { |
| 4499 | | if (ty.zigTypeTag() != .Int) break :blk .unsigned; |
| 4500 | | break :blk ty.intInfo(self.target.*).signedness; |
| 4501 | | }; |
| 4502 | 4509 | try dbg_info.ensureUnusedCapacity(2); |
| 4503 | 4510 | const fixup = dbg_info.items.len; |
| 4504 | 4511 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4505 | 4512 | 1, |
| 4506 | | switch (signedness) { |
| 4507 | | .signed => DW.OP.consts, |
| 4508 | | .unsigned => DW.OP.constu, |
| 4509 | | }, |
| 4513 | if (ty.isSignedInt()) DW.OP.consts else DW.OP.constu, |
| 4510 | 4514 | }); |
| 4511 | | switch (signedness) { |
| 4512 | | .signed => try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)), |
| 4513 | | .unsigned => try leb128.writeULEB128(dbg_info.writer(), x), |
| 4515 | if (ty.isSignedInt()) { |
| 4516 | try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)); |
| 4517 | } else { |
| 4518 | try leb128.writeULEB128(dbg_info.writer(), x); |
| 4514 | 4519 | } |
| 4515 | 4520 | try dbg_info.append(DW.OP.stack_value); |
| 4516 | 4521 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 4517 | 4522 | }, |
| 4523 | |
| 4518 | 4524 | .undef => { |
| 4519 | 4525 | // DW.AT.location, DW.FORM.exprloc |
| 4520 | 4526 | // uleb128(exprloc_len) |
| ... | ... | @@ -4530,12 +4536,14 @@ fn genVarDbgInfo( |
| 4530 | 4536 | dbg_info.appendSliceAssumeCapacity(implicit_value_len.items); |
| 4531 | 4537 | dbg_info.appendNTimesAssumeCapacity(0xaa, abi_size); |
| 4532 | 4538 | }, |
| 4539 | |
| 4533 | 4540 | .none => { |
| 4534 | 4541 | try dbg_info.ensureUnusedCapacity(3); |
| 4535 | 4542 | dbg_info.appendSliceAssumeCapacity(&[3]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4536 | 4543 | 2, DW.OP.lit0, DW.OP.stack_value, |
| 4537 | 4544 | }); |
| 4538 | 4545 | }, |
| 4546 | |
| 4539 | 4547 | else => { |
| 4540 | 4548 | try dbg_info.ensureUnusedCapacity(2); |
| 4541 | 4549 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| ... | ... | @@ -4556,7 +4564,7 @@ fn genVarDbgInfo( |
| 4556 | 4564 | |
| 4557 | 4565 | /// Adds a Type to the .debug_info at the current position. The bytes will be populated later, |
| 4558 | 4566 | /// after codegen for this symbol is done. |
| 4559 | | fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void { |
| 4567 | fn addDbgInfoTypeReloc(self: Self, ty: Type) !void { |
| 4560 | 4568 | switch (self.debug_output) { |
| 4561 | 4569 | .dwarf => |dw| { |
| 4562 | 4570 | const dbg_info = &dw.dbg_info; |