| ... | ... | @@ -39,7 +39,6 @@ liveness: Liveness, |
| 39 | 39 | bin_file: *link.File, |
| 40 | 40 | target: *const std.Target, |
| 41 | 41 | mod_fn: *const Module.Fn, |
| 42 | | debug_output: DebugInfoOutput, |
| 43 | 42 | err_msg: ?*ErrorMsg, |
| 44 | 43 | args: []MCValue, |
| 45 | 44 | ret_mcv: MCValue, |
| ... | ... | @@ -53,13 +52,9 @@ mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 53 | 52 | /// MIR extra data |
| 54 | 53 | mir_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 55 | 54 | |
| 56 | | prev_di_line: u32, |
| 57 | | prev_di_column: u32, |
| 58 | 55 | /// Byte offset within the source file of the ending curly. |
| 59 | 56 | end_di_line: u32, |
| 60 | 57 | end_di_column: u32, |
| 61 | | /// Relative to the beginning of `code`. |
| 62 | | prev_di_pc: usize, |
| 63 | 58 | |
| 64 | 59 | /// The value is an offset into the `Function` `code` from the beginning. |
| 65 | 60 | /// To perform the reloc, write 32-bit signed little-endian integer |
| ... | ... | @@ -272,7 +267,6 @@ pub fn generate( |
| 272 | 267 | .target = &bin_file.options.target, |
| 273 | 268 | .bin_file = bin_file, |
| 274 | 269 | .mod_fn = module_fn, |
| 275 | | .debug_output = debug_output, |
| 276 | 270 | .err_msg = null, |
| 277 | 271 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 278 | 272 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| ... | ... | @@ -281,9 +275,6 @@ pub fn generate( |
| 281 | 275 | .branch_stack = &branch_stack, |
| 282 | 276 | .src_loc = src_loc, |
| 283 | 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 | 278 | .end_di_line = module_fn.rbrace_line, |
| 288 | 279 | .end_di_column = module_fn.rbrace_column, |
| 289 | 280 | }; |
| ... | ... | @@ -316,8 +307,12 @@ pub fn generate( |
| 316 | 307 | var emit = Emit{ |
| 317 | 308 | .mir = mir, |
| 318 | 309 | .bin_file = bin_file, |
| 310 | .debug_output = debug_output, |
| 319 | 311 | .target = &bin_file.options.target, |
| 320 | 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 | 317 | try emit.emitMir(); |
| 323 | 318 | |
| ... | ... | @@ -386,7 +381,10 @@ fn gen(self: *Self) !void { |
| 386 | 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 | 389 | try self.genBody(self.air.getMainBody()); |
| 392 | 390 | |
| ... | ... | @@ -402,7 +400,10 @@ fn gen(self: *Self) !void { |
| 402 | 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 | 408 | // exitlude jumps |
| 408 | 409 | if (self.exitlude_jump_relocs.items.len == 1) { |
| ... | ... | @@ -442,13 +443,27 @@ fn gen(self: *Self) !void { |
| 442 | 443 | .data = .{ .reg = .x30 }, |
| 443 | 444 | }); |
| 444 | 445 | } else { |
| 445 | | try self.dbgSetPrologueEnd(); |
| 446 | _ = try self.addInst(.{ |
| 447 | .tag = .dbg_prologue_end, |
| 448 | .data = .{ .nop = {} }, |
| 449 | }); |
| 450 | |
| 446 | 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 | 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 | 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 | 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 | 607 | /// Asserts there is already capacity to insert into top branch inst_table. |
| 666 | 608 | fn processDeath(self: *Self, inst: Air.Inst.Index) void { |
| 667 | 609 | const air_tags = self.air.instructions.items(.tag); |
| ... | ... | @@ -1407,7 +1349,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1407 | 1349 | }, |
| 1408 | 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 | 1355 | if (self.liveness.isUnused(inst)) |
| 1413 | 1356 | return self.finishAirBookkeeping(); |
| ... | ... | @@ -1698,8 +1641,15 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 1698 | 1641 | |
| 1699 | 1642 | fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1700 | 1643 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 1701 | | _ = dbg_stmt; |
| 1702 | | // try self.dbgAdvancePCAndLine(dbg_stmt.line, dbg_stmt.column); |
| 1644 | |
| 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 | 1653 | return self.finishAirBookkeeping(); |
| 1704 | 1654 | } |
| 1705 | 1655 | |