| ... | @@ -3797,64 +3797,68 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3797,64 +3797,68 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 3797 | const ty = self.air.typeOfIndex(inst); | 3797 | const ty = self.air.typeOfIndex(inst); |
| 3798 | const mcv = self.args[arg_index]; | 3798 | const mcv = self.args[arg_index]; |
| 3799 | const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index); | 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 | if (self.liveness.isUnused(inst)) | 3801 | if (self.liveness.isUnused(inst)) |
| 3803 | return self.finishAirBookkeeping(); | 3802 | return self.finishAirBookkeeping(); |
| 3804 | | 3803 | |
| 3805 | const dst_mcv: MCValue = blk: { | 3804 | const dst_mcv: MCValue = switch (mcv) { |
| 3806 | switch (mcv) { | 3805 | .register => |reg| blk: { |
| 3807 | .register => |reg| { | 3806 | self.register_manager.getRegAssumeFree(reg.to64(), inst); |
| 3808 | self.register_manager.getRegAssumeFree(reg.to64(), inst); | 3807 | break :blk MCValue{ .register = reg }; |
| 3809 | switch (self.debug_output) { | 3808 | }, |
| 3810 | .dwarf => |dw| { | 3809 | .stack_offset => |off| blk: { |
| 3811 | const dbg_info = &dw.dbg_info; | 3810 | const offset = @intCast(i32, self.max_end_stack) - off + 16; |
| 3812 | try dbg_info.ensureUnusedCapacity(3); | 3811 | break :blk MCValue{ .stack_offset = -offset }; |
| 3813 | dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); | 3812 | }, |
| 3814 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 3813 | else => return self.fail("TODO implement arg for {}", .{mcv}), |
| 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 | } | | |
| 3853 | }; | 3814 | }; |
| | 3815 | try self.genArgDbgInfo(ty, name, dst_mcv); |
| 3854 | | 3816 | |
| 3855 | return self.finishAir(inst, dst_mcv, .{ .none, .none, .none }); | 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 | fn airBreakpoint(self: *Self) !void { | 3862 | fn airBreakpoint(self: *Self) !void { |
| 3859 | _ = try self.addInst(.{ | 3863 | _ = try self.addInst(.{ |
| 3860 | .tag = .interrupt, | 3864 | .tag = .interrupt, |
| ... | @@ -4424,7 +4428,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4424,7 +4428,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 4424 | } | 4428 | } |
| 4425 | | 4429 | |
| 4426 | fn genVarDbgInfo( | 4430 | fn genVarDbgInfo( |
| 4427 | self: *Self, | 4431 | self: Self, |
| 4428 | tag: Air.Inst.Tag, | 4432 | tag: Air.Inst.Tag, |
| 4429 | ty: Type, | 4433 | ty: Type, |
| 4430 | mcv: MCValue, | 4434 | mcv: MCValue, |
| ... | @@ -4445,17 +4449,23 @@ fn genVarDbgInfo( | ... | @@ -4445,17 +4449,23 @@ fn genVarDbgInfo( |
| 4445 | reg.dwarfLocOp(), | 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 | try dbg_info.ensureUnusedCapacity(7); | 4456 | try dbg_info.ensureUnusedCapacity(7); |
| 4450 | const fixup = dbg_info.items.len; | 4457 | const fixup = dbg_info.items.len; |
| 4451 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 4458 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4452 | 1, // we will backpatch it after we encode the displacement in LEB128 | 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 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; | 4462 | leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; |
| 4456 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | 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 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); | 4469 | const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); |
| 4460 | const is_ptr = switch (tag) { | 4470 | const is_ptr = switch (tag) { |
| 4461 | .dbg_var_ptr => true, | 4471 | .dbg_var_ptr => true, |
| ... | @@ -4494,27 +4504,23 @@ fn genVarDbgInfo( | ... | @@ -4494,27 +4504,23 @@ fn genVarDbgInfo( |
| 4494 | else => {}, | 4504 | else => {}, |
| 4495 | } | 4505 | } |
| 4496 | }, | 4506 | }, |
| | 4507 | |
| 4497 | .immediate => |x| { | 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 | try dbg_info.ensureUnusedCapacity(2); | 4509 | try dbg_info.ensureUnusedCapacity(2); |
| 4503 | const fixup = dbg_info.items.len; | 4510 | const fixup = dbg_info.items.len; |
| 4504 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 4511 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4505 | 1, | 4512 | 1, |
| 4506 | switch (signedness) { | 4513 | if (ty.isSignedInt()) DW.OP.consts else DW.OP.constu, |
| 4507 | .signed => DW.OP.consts, | | |
| 4508 | .unsigned => DW.OP.constu, | | |
| 4509 | }, | | |
| 4510 | }); | 4514 | }); |
| 4511 | switch (signedness) { | 4515 | if (ty.isSignedInt()) { |
| 4512 | .signed => try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)), | 4516 | try leb128.writeILEB128(dbg_info.writer(), @bitCast(i64, x)); |
| 4513 | .unsigned => try leb128.writeULEB128(dbg_info.writer(), x), | 4517 | } else { |
| | 4518 | try leb128.writeULEB128(dbg_info.writer(), x); |
| 4514 | } | 4519 | } |
| 4515 | try dbg_info.append(DW.OP.stack_value); | 4520 | try dbg_info.append(DW.OP.stack_value); |
| 4516 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); | 4521 | dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); |
| 4517 | }, | 4522 | }, |
| | 4523 | |
| 4518 | .undef => { | 4524 | .undef => { |
| 4519 | // DW.AT.location, DW.FORM.exprloc | 4525 | // DW.AT.location, DW.FORM.exprloc |
| 4520 | // uleb128(exprloc_len) | 4526 | // uleb128(exprloc_len) |
| ... | @@ -4530,12 +4536,14 @@ fn genVarDbgInfo( | ... | @@ -4530,12 +4536,14 @@ fn genVarDbgInfo( |
| 4530 | dbg_info.appendSliceAssumeCapacity(implicit_value_len.items); | 4536 | dbg_info.appendSliceAssumeCapacity(implicit_value_len.items); |
| 4531 | dbg_info.appendNTimesAssumeCapacity(0xaa, abi_size); | 4537 | dbg_info.appendNTimesAssumeCapacity(0xaa, abi_size); |
| 4532 | }, | 4538 | }, |
| | 4539 | |
| 4533 | .none => { | 4540 | .none => { |
| 4534 | try dbg_info.ensureUnusedCapacity(3); | 4541 | try dbg_info.ensureUnusedCapacity(3); |
| 4535 | dbg_info.appendSliceAssumeCapacity(&[3]u8{ // DW.AT.location, DW.FORM.exprloc | 4542 | dbg_info.appendSliceAssumeCapacity(&[3]u8{ // DW.AT.location, DW.FORM.exprloc |
| 4536 | 2, DW.OP.lit0, DW.OP.stack_value, | 4543 | 2, DW.OP.lit0, DW.OP.stack_value, |
| 4537 | }); | 4544 | }); |
| 4538 | }, | 4545 | }, |
| | 4546 | |
| 4539 | else => { | 4547 | else => { |
| 4540 | try dbg_info.ensureUnusedCapacity(2); | 4548 | try dbg_info.ensureUnusedCapacity(2); |
| 4541 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc | 4549 | dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| ... | @@ -4556,7 +4564,7 @@ fn genVarDbgInfo( | ... | @@ -4556,7 +4564,7 @@ fn genVarDbgInfo( |
| 4556 | | 4564 | |
| 4557 | /// Adds a Type to the .debug_info at the current position. The bytes will be populated later, | 4565 | /// Adds a Type to the .debug_info at the current position. The bytes will be populated later, |
| 4558 | /// after codegen for this symbol is done. | 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 | switch (self.debug_output) { | 4568 | switch (self.debug_output) { |
| 4561 | .dwarf => |dw| { | 4569 | .dwarf => |dw| { |
| 4562 | const dbg_info = &dw.dbg_info; | 4570 | const dbg_info = &dw.dbg_info; |