| ... | @@ -39,7 +39,6 @@ liveness: Liveness, | ... | @@ -39,7 +39,6 @@ liveness: Liveness, |
| 39 | bin_file: *link.File, | 39 | bin_file: *link.File, |
| 40 | target: *const std.Target, | 40 | target: *const std.Target, |
| 41 | mod_fn: *const Module.Fn, | 41 | mod_fn: *const Module.Fn, |
| 42 | debug_output: DebugInfoOutput, | | |
| 43 | err_msg: ?*ErrorMsg, | 42 | err_msg: ?*ErrorMsg, |
| 44 | args: []MCValue, | 43 | args: []MCValue, |
| 45 | ret_mcv: MCValue, | 44 | ret_mcv: MCValue, |
| ... | @@ -53,13 +52,9 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, | ... | @@ -53,13 +52,9 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 53 | /// MIR extra data | 52 | /// MIR extra data |
| 54 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, | 53 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 55 | | 54 | |
| 56 | prev_di_line: u32, | | |
| 57 | prev_di_column: u32, | | |
| 58 | /// Byte offset within the source file of the ending curly. | 55 | /// Byte offset within the source file of the ending curly. |
| 59 | end_di_line: u32, | 56 | end_di_line: u32, |
| 60 | end_di_column: u32, | 57 | end_di_column: u32, |
| 61 | /// Relative to the beginning of `code`. | | |
| 62 | prev_di_pc: usize, | | |
| 63 | | 58 | |
| 64 | /// The value is an offset into the `Function` `code` from the beginning. | 59 | /// The value is an offset into the `Function` `code` from the beginning. |
| 65 | /// To perform the reloc, write 32-bit signed little-endian integer | 60 | /// To perform the reloc, write 32-bit signed little-endian integer |
| ... | @@ -272,7 +267,6 @@ pub fn generate( | ... | @@ -272,7 +267,6 @@ pub fn generate( |
| 272 | .target = &bin_file.options.target, | 267 | .target = &bin_file.options.target, |
| 273 | .bin_file = bin_file, | 268 | .bin_file = bin_file, |
| 274 | .mod_fn = module_fn, | 269 | .mod_fn = module_fn, |
| 275 | .debug_output = debug_output, | | |
| 276 | .err_msg = null, | 270 | .err_msg = null, |
| 277 | .args = undefined, // populated after `resolveCallingConventionValues` | 271 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 278 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` | 272 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| ... | @@ -281,9 +275,6 @@ pub fn generate( | ... | @@ -281,9 +275,6 @@ pub fn generate( |
| 281 | .branch_stack = &branch_stack, | 275 | .branch_stack = &branch_stack, |
| 282 | .src_loc = src_loc, | 276 | .src_loc = src_loc, |
| 283 | .stack_align = undefined, | 277 | .stack_align = undefined, |
| 284 | .prev_di_pc = 0, | | |
| 285 | .prev_di_line = module_fn.lbrace_line, | | |
| 286 | .prev_di_column = module_fn.lbrace_column, | | |
| 287 | .end_di_line = module_fn.rbrace_line, | 278 | .end_di_line = module_fn.rbrace_line, |
| 288 | .end_di_column = module_fn.rbrace_column, | 279 | .end_di_column = module_fn.rbrace_column, |
| 289 | }; | 280 | }; |
| ... | @@ -316,8 +307,12 @@ pub fn generate( | ... | @@ -316,8 +307,12 @@ pub fn generate( |
| 316 | var emit = Emit{ | 307 | var emit = Emit{ |
| 317 | .mir = mir, | 308 | .mir = mir, |
| 318 | .bin_file = bin_file, | 309 | .bin_file = bin_file, |
| | 310 | .debug_output = debug_output, |
| 319 | .target = &bin_file.options.target, | 311 | .target = &bin_file.options.target, |
| 320 | .code = code, | 312 | .code = code, |
| | 313 | .prev_di_pc = 0, |
| | 314 | .prev_di_line = module_fn.lbrace_line, |
| | 315 | .prev_di_column = module_fn.lbrace_column, |
| 321 | }; | 316 | }; |
| 322 | try emit.emitMir(); | 317 | try emit.emitMir(); |
| 323 | | 318 | |
| ... | @@ -386,7 +381,10 @@ fn gen(self: *Self) !void { | ... | @@ -386,7 +381,10 @@ fn gen(self: *Self) !void { |
| 386 | .data = .{ .nop = {} }, | 381 | .data = .{ .nop = {} }, |
| 387 | }); | 382 | }); |
| 388 | | 383 | |
| 389 | try self.dbgSetPrologueEnd(); | 384 | _ = try self.addInst(.{ |
| | 385 | .tag = .dbg_prologue_end, |
| | 386 | .data = .{ .nop = {} }, |
| | 387 | }); |
| 390 | | 388 | |
| 391 | try self.genBody(self.air.getMainBody()); | 389 | try self.genBody(self.air.getMainBody()); |
| 392 | | 390 | |
| ... | @@ -402,7 +400,10 @@ fn gen(self: *Self) !void { | ... | @@ -402,7 +400,10 @@ fn gen(self: *Self) !void { |
| 402 | return self.failSymbol("TODO AArch64: allow larger stacks", .{}); | 400 | return self.failSymbol("TODO AArch64: allow larger stacks", .{}); |
| 403 | } | 401 | } |
| 404 | | 402 | |
| 405 | try self.dbgSetEpilogueBegin(); | 403 | _ = try self.addInst(.{ |
| | 404 | .tag = .dbg_epilogue_begin, |
| | 405 | .data = .{ .nop = {} }, |
| | 406 | }); |
| 406 | | 407 | |
| 407 | // exitlude jumps | 408 | // exitlude jumps |
| 408 | if (self.exitlude_jump_relocs.items.len == 1) { | 409 | if (self.exitlude_jump_relocs.items.len == 1) { |
| ... | @@ -442,13 +443,27 @@ fn gen(self: *Self) !void { | ... | @@ -442,13 +443,27 @@ fn gen(self: *Self) !void { |
| 442 | .data = .{ .reg = .x30 }, | 443 | .data = .{ .reg = .x30 }, |
| 443 | }); | 444 | }); |
| 444 | } else { | 445 | } else { |
| 445 | try self.dbgSetPrologueEnd(); | 446 | _ = try self.addInst(.{ |
| | 447 | .tag = .dbg_prologue_end, |
| | 448 | .data = .{ .nop = {} }, |
| | 449 | }); |
| | 450 | |
| 446 | try self.genBody(self.air.getMainBody()); | 451 | try self.genBody(self.air.getMainBody()); |
| 447 | try self.dbgSetEpilogueBegin(); | 452 | |
| | 453 | _ = try self.addInst(.{ |
| | 454 | .tag = .dbg_epilogue_begin, |
| | 455 | .data = .{ .nop = {} }, |
| | 456 | }); |
| 448 | } | 457 | } |
| 449 | | 458 | |
| 450 | // Drop them off at the rbrace. | 459 | // Drop them off at the rbrace. |
| 451 | // try self.dbgAdvancePCAndLine(self.end_di_line, self.end_di_column); | 460 | _ = try self.addInst(.{ |
| | 461 | .tag = .dbg_line, |
| | 462 | .data = .{ .dbg_line_column = .{ |
| | 463 | .line = self.end_di_line, |
| | 464 | .column = self.end_di_column, |
| | 465 | } }, |
| | 466 | }); |
| 452 | } | 467 | } |
| 453 | | 468 | |
| 454 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | 469 | fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| ... | @@ -589,79 +604,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -589,79 +604,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 589 | } | 604 | } |
| 590 | } | 605 | } |
| 591 | | 606 | |
| 592 | fn dbgSetPrologueEnd(self: *Self) InnerError!void { | | |
| 593 | switch (self.debug_output) { | | |
| 594 | .dwarf => |dbg_out| { | | |
| 595 | try dbg_out.dbg_line.append(DW.LNS.set_prologue_end); | | |
| 596 | // try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); | | |
| 597 | }, | | |
| 598 | .plan9 => {}, | | |
| 599 | .none => {}, | | |
| 600 | } | | |
| 601 | } | | |
| 602 | | | |
| 603 | fn dbgSetEpilogueBegin(self: *Self) InnerError!void { | | |
| 604 | switch (self.debug_output) { | | |
| 605 | .dwarf => |dbg_out| { | | |
| 606 | try dbg_out.dbg_line.append(DW.LNS.set_epilogue_begin); | | |
| 607 | // try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); | | |
| 608 | }, | | |
| 609 | .plan9 => {}, | | |
| 610 | .none => {}, | | |
| 611 | } | | |
| 612 | } | | |
| 613 | | | |
| 614 | fn dbgAdvancePCAndLine(self: *Self, line: u32, column: u32) InnerError!void { | | |
| 615 | const delta_line = @intCast(i32, line) - @intCast(i32, self.prev_di_line); | | |
| 616 | const delta_pc: usize = self.code.items.len - self.prev_di_pc; | | |
| 617 | switch (self.debug_output) { | | |
| 618 | .dwarf => |dbg_out| { | | |
| 619 | // TODO Look into using the DWARF special opcodes to compress this data. | | |
| 620 | // It lets you emit single-byte opcodes that add different numbers to | | |
| 621 | // both the PC and the line number at the same time. | | |
| 622 | try dbg_out.dbg_line.ensureUnusedCapacity(11); | | |
| 623 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_pc); | | |
| 624 | leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable; | | |
| 625 | if (delta_line != 0) { | | |
| 626 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_line); | | |
| 627 | leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable; | | |
| 628 | } | | |
| 629 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy); | | |
| 630 | self.prev_di_pc = self.code.items.len; | | |
| 631 | self.prev_di_line = line; | | |
| 632 | self.prev_di_column = column; | | |
| 633 | self.prev_di_pc = self.code.items.len; | | |
| 634 | }, | | |
| 635 | .plan9 => |dbg_out| { | | |
| 636 | if (delta_pc <= 0) return; // only do this when the pc changes | | |
| 637 | // we have already checked the target in the linker to make sure it is compatable | | |
| 638 | const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable; | | |
| 639 | | | |
| 640 | // increasing the line number | | |
| 641 | try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line); | | |
| 642 | // increasing the pc | | |
| 643 | const d_pc_p9 = @intCast(i64, delta_pc) - quant; | | |
| 644 | if (d_pc_p9 > 0) { | | |
| 645 | // minus one because if its the last one, we want to leave space to change the line which is one quanta | | |
| 646 | try dbg_out.dbg_line.append(@intCast(u8, @divExact(d_pc_p9, quant) + 128) - quant); | | |
| 647 | if (dbg_out.pcop_change_index.*) |pci| | | |
| 648 | dbg_out.dbg_line.items[pci] += 1; | | |
| 649 | dbg_out.pcop_change_index.* = @intCast(u32, dbg_out.dbg_line.items.len - 1); | | |
| 650 | } else if (d_pc_p9 == 0) { | | |
| 651 | // we don't need to do anything, because adding the quant does it for us | | |
| 652 | } else unreachable; | | |
| 653 | if (dbg_out.start_line.* == null) | | |
| 654 | dbg_out.start_line.* = self.prev_di_line; | | |
| 655 | dbg_out.end_line.* = line; | | |
| 656 | // only do this if the pc changed | | |
| 657 | self.prev_di_line = line; | | |
| 658 | self.prev_di_column = column; | | |
| 659 | self.prev_di_pc = self.code.items.len; | | |
| 660 | }, | | |
| 661 | .none => {}, | | |
| 662 | } | | |
| 663 | } | | |
| 664 | | | |
| 665 | /// Asserts there is already capacity to insert into top branch inst_table. | 607 | /// Asserts there is already capacity to insert into top branch inst_table. |
| 666 | fn processDeath(self: *Self, inst: Air.Inst.Index) void { | 608 | fn processDeath(self: *Self, inst: Air.Inst.Index) void { |
| 667 | const air_tags = self.air.instructions.items(.tag); | 609 | const air_tags = self.air.instructions.items(.tag); |
| ... | @@ -1407,7 +1349,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1407,7 +1349,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1407 | }, | 1349 | }, |
| 1408 | else => result, | 1350 | else => result, |
| 1409 | }; | 1351 | }; |
| 1410 | try self.genArgDbgInfo(inst, mcv); | 1352 | // TODO generate debug info |
| | 1353 | // try self.genArgDbgInfo(inst, mcv); |
| 1411 | | 1354 | |
| 1412 | if (self.liveness.isUnused(inst)) | 1355 | if (self.liveness.isUnused(inst)) |
| 1413 | return self.finishAirBookkeeping(); | 1356 | return self.finishAirBookkeeping(); |
| ... | @@ -1698,8 +1641,15 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -1698,8 +1641,15 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1698 | | 1641 | |
| 1699 | fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | 1642 | fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1700 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; | 1643 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 1701 | _ = dbg_stmt; | 1644 | |
| 1702 | // try self.dbgAdvancePCAndLine(dbg_stmt.line, dbg_stmt.column); | 1645 | _ = try self.addInst(.{ |
| | 1646 | .tag = .dbg_line, |
| | 1647 | .data = .{ .dbg_line_column = .{ |
| | 1648 | .line = dbg_stmt.line, |
| | 1649 | .column = dbg_stmt.column, |
| | 1650 | } }, |
| | 1651 | }); |
| | 1652 | |
| 1703 | return self.finishAirBookkeeping(); | 1653 | return self.finishAirBookkeeping(); |
| 1704 | } | 1654 | } |
| 1705 | | 1655 | |