| ... | @@ -12,6 +12,11 @@ const ErrorMsg = Module.ErrorMsg; | ... | @@ -12,6 +12,11 @@ const ErrorMsg = Module.ErrorMsg; |
| 12 | const Target = std.Target; | 12 | const Target = std.Target; |
| 13 | const Allocator = mem.Allocator; | 13 | const Allocator = mem.Allocator; |
| 14 | const trace = @import("tracy.zig").trace; | 14 | const trace = @import("tracy.zig").trace; |
| | 15 | const DW = std.dwarf; |
| | 16 | const leb128 = std.debug.leb; |
| | 17 | |
| | 18 | // TODO Turn back on zig fmt when https://github.com/ziglang/zig/issues/5948 is implemented. |
| | 19 | // zig fmt: off |
| 15 | | 20 | |
| 16 | /// The codegen-related data that is stored in `ir.Inst.Block` instructions. | 21 | /// The codegen-related data that is stored in `ir.Inst.Block` instructions. |
| 17 | pub const BlockData = struct { | 22 | pub const BlockData = struct { |
| ... | @@ -52,57 +57,57 @@ pub fn generateSymbol( | ... | @@ -52,57 +57,57 @@ pub fn generateSymbol( |
| 52 | switch (typed_value.ty.zigTypeTag()) { | 57 | switch (typed_value.ty.zigTypeTag()) { |
| 53 | .Fn => { | 58 | .Fn => { |
| 54 | switch (bin_file.base.options.target.cpu.arch) { | 59 | switch (bin_file.base.options.target.cpu.arch) { |
| 55 | //.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code), | 60 | //.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 56 | //.armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code), | 61 | //.armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 57 | //.aarch64 => return Function(.aarch64).generateSymbol(bin_file, src, typed_value, code), | 62 | //.aarch64 => return Function(.aarch64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 58 | //.aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src, typed_value, code), | 63 | //.aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 59 | //.aarch64_32 => return Function(.aarch64_32).generateSymbol(bin_file, src, typed_value, code), | 64 | //.aarch64_32 => return Function(.aarch64_32).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 60 | //.arc => return Function(.arc).generateSymbol(bin_file, src, typed_value, code), | 65 | //.arc => return Function(.arc).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 61 | //.avr => return Function(.avr).generateSymbol(bin_file, src, typed_value, code), | 66 | //.avr => return Function(.avr).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 62 | //.bpfel => return Function(.bpfel).generateSymbol(bin_file, src, typed_value, code), | 67 | //.bpfel => return Function(.bpfel).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 63 | //.bpfeb => return Function(.bpfeb).generateSymbol(bin_file, src, typed_value, code), | 68 | //.bpfeb => return Function(.bpfeb).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 64 | //.hexagon => return Function(.hexagon).generateSymbol(bin_file, src, typed_value, code), | 69 | //.hexagon => return Function(.hexagon).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 65 | //.mips => return Function(.mips).generateSymbol(bin_file, src, typed_value, code), | 70 | //.mips => return Function(.mips).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 66 | //.mipsel => return Function(.mipsel).generateSymbol(bin_file, src, typed_value, code), | 71 | //.mipsel => return Function(.mipsel).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 67 | //.mips64 => return Function(.mips64).generateSymbol(bin_file, src, typed_value, code), | 72 | //.mips64 => return Function(.mips64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 68 | //.mips64el => return Function(.mips64el).generateSymbol(bin_file, src, typed_value, code), | 73 | //.mips64el => return Function(.mips64el).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 69 | //.msp430 => return Function(.msp430).generateSymbol(bin_file, src, typed_value, code), | 74 | //.msp430 => return Function(.msp430).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 70 | //.powerpc => return Function(.powerpc).generateSymbol(bin_file, src, typed_value, code), | 75 | //.powerpc => return Function(.powerpc).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 71 | //.powerpc64 => return Function(.powerpc64).generateSymbol(bin_file, src, typed_value, code), | 76 | //.powerpc64 => return Function(.powerpc64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 72 | //.powerpc64le => return Function(.powerpc64le).generateSymbol(bin_file, src, typed_value, code), | 77 | //.powerpc64le => return Function(.powerpc64le).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 73 | //.r600 => return Function(.r600).generateSymbol(bin_file, src, typed_value, code), | 78 | //.r600 => return Function(.r600).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 74 | //.amdgcn => return Function(.amdgcn).generateSymbol(bin_file, src, typed_value, code), | 79 | //.amdgcn => return Function(.amdgcn).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 75 | //.riscv32 => return Function(.riscv32).generateSymbol(bin_file, src, typed_value, code), | 80 | //.riscv32 => return Function(.riscv32).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 76 | //.riscv64 => return Function(.riscv64).generateSymbol(bin_file, src, typed_value, code), | 81 | //.riscv64 => return Function(.riscv64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 77 | //.sparc => return Function(.sparc).generateSymbol(bin_file, src, typed_value, code), | 82 | //.sparc => return Function(.sparc).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 78 | //.sparcv9 => return Function(.sparcv9).generateSymbol(bin_file, src, typed_value, code), | 83 | //.sparcv9 => return Function(.sparcv9).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 79 | //.sparcel => return Function(.sparcel).generateSymbol(bin_file, src, typed_value, code), | 84 | //.sparcel => return Function(.sparcel).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 80 | //.s390x => return Function(.s390x).generateSymbol(bin_file, src, typed_value, code), | 85 | //.s390x => return Function(.s390x).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 81 | //.tce => return Function(.tce).generateSymbol(bin_file, src, typed_value, code), | 86 | //.tce => return Function(.tce).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 82 | //.tcele => return Function(.tcele).generateSymbol(bin_file, src, typed_value, code), | 87 | //.tcele => return Function(.tcele).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 83 | //.thumb => return Function(.thumb).generateSymbol(bin_file, src, typed_value, code), | 88 | //.thumb => return Function(.thumb).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 84 | //.thumbeb => return Function(.thumbeb).generateSymbol(bin_file, src, typed_value, code), | 89 | //.thumbeb => return Function(.thumbeb).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 85 | //.i386 => return Function(.i386).generateSymbol(bin_file, src, typed_value, code), | 90 | //.i386 => return Function(.i386).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 86 | .x86_64 => return Function(.x86_64).generateSymbol(bin_file, src, typed_value, code), | 91 | .x86_64 => return Function(.x86_64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 87 | //.xcore => return Function(.xcore).generateSymbol(bin_file, src, typed_value, code), | 92 | //.xcore => return Function(.xcore).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 88 | //.nvptx => return Function(.nvptx).generateSymbol(bin_file, src, typed_value, code), | 93 | //.nvptx => return Function(.nvptx).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 89 | //.nvptx64 => return Function(.nvptx64).generateSymbol(bin_file, src, typed_value, code), | 94 | //.nvptx64 => return Function(.nvptx64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 90 | //.le32 => return Function(.le32).generateSymbol(bin_file, src, typed_value, code), | 95 | //.le32 => return Function(.le32).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 91 | //.le64 => return Function(.le64).generateSymbol(bin_file, src, typed_value, code), | 96 | //.le64 => return Function(.le64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 92 | //.amdil => return Function(.amdil).generateSymbol(bin_file, src, typed_value, code), | 97 | //.amdil => return Function(.amdil).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 93 | //.amdil64 => return Function(.amdil64).generateSymbol(bin_file, src, typed_value, code), | 98 | //.amdil64 => return Function(.amdil64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 94 | //.hsail => return Function(.hsail).generateSymbol(bin_file, src, typed_value, code), | 99 | //.hsail => return Function(.hsail).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 95 | //.hsail64 => return Function(.hsail64).generateSymbol(bin_file, src, typed_value, code), | 100 | //.hsail64 => return Function(.hsail64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 96 | //.spir => return Function(.spir).generateSymbol(bin_file, src, typed_value, code), | 101 | //.spir => return Function(.spir).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 97 | //.spir64 => return Function(.spir64).generateSymbol(bin_file, src, typed_value, code), | 102 | //.spir64 => return Function(.spir64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 98 | //.kalimba => return Function(.kalimba).generateSymbol(bin_file, src, typed_value, code), | 103 | //.kalimba => return Function(.kalimba).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 99 | //.shave => return Function(.shave).generateSymbol(bin_file, src, typed_value, code), | 104 | //.shave => return Function(.shave).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 100 | //.lanai => return Function(.lanai).generateSymbol(bin_file, src, typed_value, code), | 105 | //.lanai => return Function(.lanai).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 101 | //.wasm32 => return Function(.wasm32).generateSymbol(bin_file, src, typed_value, code), | 106 | //.wasm32 => return Function(.wasm32).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 102 | //.wasm64 => return Function(.wasm64).generateSymbol(bin_file, src, typed_value, code), | 107 | //.wasm64 => return Function(.wasm64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 103 | //.renderscript32 => return Function(.renderscript32).generateSymbol(bin_file, src, typed_value, code), | 108 | //.renderscript32 => return Function(.renderscript32).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 104 | //.renderscript64 => return Function(.renderscript64).generateSymbol(bin_file, src, typed_value, code), | 109 | //.renderscript64 => return Function(.renderscript64).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 105 | //.ve => return Function(.ve).generateSymbol(bin_file, src, typed_value, code), | 110 | //.ve => return Function(.ve).generateSymbol(bin_file, src, typed_value, code, dbg_line), |
| 106 | else => @panic("Backend architectures that don't have good support yet are commented out, to improve compilation performance. If you are interested in one of these other backends feel free to uncomment them. Eventually these will be completed, but stage1 is slow and a memory hog."), | 111 | else => @panic("Backend architectures that don't have good support yet are commented out, to improve compilation performance. If you are interested in one of these other backends feel free to uncomment them. Eventually these will be completed, but stage1 is slow and a memory hog."), |
| 107 | } | 112 | } |
| 108 | }, | 113 | }, |
| ... | @@ -207,6 +212,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -207,6 +212,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 207 | target: *const std.Target, | 212 | target: *const std.Target, |
| 208 | mod_fn: *const Module.Fn, | 213 | mod_fn: *const Module.Fn, |
| 209 | code: *std.ArrayList(u8), | 214 | code: *std.ArrayList(u8), |
| | 215 | dbg_line: *std.ArrayList(u8), |
| 210 | err_msg: ?*ErrorMsg, | 216 | err_msg: ?*ErrorMsg, |
| 211 | args: []MCValue, | 217 | args: []MCValue, |
| 212 | ret_mcv: MCValue, | 218 | ret_mcv: MCValue, |
| ... | @@ -215,6 +221,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -215,6 +221,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 215 | src: usize, | 221 | src: usize, |
| 216 | stack_align: u32, | 222 | stack_align: u32, |
| 217 | | 223 | |
| | 224 | /// Byte offset within the source file. |
| | 225 | prev_di_src: usize, |
| | 226 | /// Relative to the beginning of `code`. |
| | 227 | prev_di_pc: usize, |
| | 228 | /// Used to find newlines and count line deltas. |
| | 229 | source: []const u8, |
| | 230 | /// Byte offset within the source file of the ending curly. |
| | 231 | rbrace_src: usize, |
| | 232 | |
| 218 | /// The value is an offset into the `Function` `code` from the beginning. | 233 | /// The value is an offset into the `Function` `code` from the beginning. |
| 219 | /// To perform the reloc, write 32-bit signed little-endian integer | 234 | /// To perform the reloc, write 32-bit signed little-endian integer |
| 220 | /// which is a relative jump, based on the address following the reloc. | 235 | /// which is a relative jump, based on the address following the reloc. |
| ... | @@ -366,6 +381,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -366,6 +381,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 366 | src: usize, | 381 | src: usize, |
| 367 | typed_value: TypedValue, | 382 | typed_value: TypedValue, |
| 368 | code: *std.ArrayList(u8), | 383 | code: *std.ArrayList(u8), |
| | 384 | dbg_line: *std.ArrayList(u8), |
| 369 | ) GenerateSymbolError!Result { | 385 | ) GenerateSymbolError!Result { |
| 370 | const module_fn = typed_value.val.cast(Value.Payload.Function).?.func; | 386 | const module_fn = typed_value.val.cast(Value.Payload.Function).?.func; |
| 371 | | 387 | |
| ... | @@ -380,12 +396,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -380,12 +396,20 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 380 | const branch = try branch_stack.addOne(); | 396 | const branch = try branch_stack.addOne(); |
| 381 | branch.* = .{}; | 397 | branch.* = .{}; |
| 382 | | 398 | |
| | 399 | const scope_file = module_fn.owner_decl.scope.cast(Module.Scope.File).?; |
| | 400 | const tree = scope_file.contents.tree; |
| | 401 | const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?; |
| | 402 | const block = fn_proto.body().?.castTag(.Block).?; |
| | 403 | const lbrace_src = tree.token_locs[block.lbrace].start; |
| | 404 | const rbrace_src = tree.token_locs[block.rbrace].start; |
| | 405 | |
| 383 | var function = Self{ | 406 | var function = Self{ |
| 384 | .gpa = bin_file.allocator, | 407 | .gpa = bin_file.allocator, |
| 385 | .target = &bin_file.base.options.target, | 408 | .target = &bin_file.base.options.target, |
| 386 | .bin_file = bin_file, | 409 | .bin_file = bin_file, |
| 387 | .mod_fn = module_fn, | 410 | .mod_fn = module_fn, |
| 388 | .code = code, | 411 | .code = code, |
| | 412 | .dbg_line = dbg_line, |
| 389 | .err_msg = null, | 413 | .err_msg = null, |
| 390 | .args = undefined, // populated after `resolveCallingConventionValues` | 414 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 391 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` | 415 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| ... | @@ -394,6 +418,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -394,6 +418,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 394 | .branch_stack = &branch_stack, | 418 | .branch_stack = &branch_stack, |
| 395 | .src = src, | 419 | .src = src, |
| 396 | .stack_align = undefined, | 420 | .stack_align = undefined, |
| | 421 | .prev_di_pc = 0, |
| | 422 | .prev_di_src = lbrace_src, |
| | 423 | .rbrace_src = rbrace_src, |
| | 424 | .source = tree.source, |
| 397 | }; | 425 | }; |
| 398 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); | 426 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); |
| 399 | | 427 | |
| ... | @@ -432,21 +460,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -432,21 +460,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 432 | // TODO During semantic analysis, check if there are no function calls. If there | 460 | // TODO During semantic analysis, check if there are no function calls. If there |
| 433 | // are none, here we can omit the part where we subtract and then add rsp. | 461 | // are none, here we can omit the part where we subtract and then add rsp. |
| 434 | self.code.appendSliceAssumeCapacity(&[_]u8{ | 462 | self.code.appendSliceAssumeCapacity(&[_]u8{ |
| 435 | // push rbp | 463 | 0x55, // push rbp |
| 436 | 0x55, | 464 | 0x48, 0x89, 0xe5, // mov rbp, rsp |
| 437 | // mov rbp, rsp | 465 | 0x48, 0x81, 0xec, // sub rsp, imm32 (with reloc) |
| 438 | 0x48, | | |
| 439 | 0x89, | | |
| 440 | 0xe5, | | |
| 441 | // sub rsp, imm32 (with reloc) | | |
| 442 | 0x48, | | |
| 443 | 0x81, | | |
| 444 | 0xec, | | |
| 445 | }); | 466 | }); |
| 446 | const reloc_index = self.code.items.len; | 467 | const reloc_index = self.code.items.len; |
| 447 | self.code.items.len += 4; | 468 | self.code.items.len += 4; |
| 448 | | 469 | |
| | 470 | try self.dbgSetPrologueEnd(); |
| 449 | try self.genBody(self.mod_fn.analysis.success); | 471 | try self.genBody(self.mod_fn.analysis.success); |
| | 472 | try self.dbgSetEpilogueBegin(); |
| 450 | | 473 | |
| 451 | const stack_end = self.branch_stack.items[0].max_end_stack; | 474 | const stack_end = self.branch_stack.items[0].max_end_stack; |
| 452 | if (stack_end > math.maxInt(i32)) | 475 | if (stack_end > math.maxInt(i32)) |
| ... | @@ -486,13 +509,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -486,13 +509,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 486 | 0xc3, // ret | 509 | 0xc3, // ret |
| 487 | }); | 510 | }); |
| 488 | } else { | 511 | } else { |
| | 512 | try self.dbgSetPrologueEnd(); |
| 489 | try self.genBody(self.mod_fn.analysis.success); | 513 | try self.genBody(self.mod_fn.analysis.success); |
| | 514 | try self.dbgSetEpilogueBegin(); |
| 490 | } | 515 | } |
| 491 | }, | 516 | }, |
| 492 | else => { | 517 | else => { |
| | 518 | try self.dbgSetPrologueEnd(); |
| 493 | try self.genBody(self.mod_fn.analysis.success); | 519 | try self.genBody(self.mod_fn.analysis.success); |
| | 520 | try self.dbgSetEpilogueBegin(); |
| 494 | }, | 521 | }, |
| 495 | } | 522 | } |
| | 523 | // Drop them off at the rbrace. |
| | 524 | try self.dbgAdvancePCAndLine(self.rbrace_src); |
| 496 | } | 525 | } |
| 497 | | 526 | |
| 498 | fn genBody(self: *Self, body: ir.Body) InnerError!void { | 527 | fn genBody(self: *Self, body: ir.Body) InnerError!void { |
| ... | @@ -509,6 +538,38 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -509,6 +538,38 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 509 | } | 538 | } |
| 510 | } | 539 | } |
| 511 | | 540 | |
| | 541 | fn dbgSetPrologueEnd(self: *Self) InnerError!void { |
| | 542 | try self.dbg_line.append(DW.LNS_set_prologue_end); |
| | 543 | try self.dbgAdvancePCAndLine(self.prev_di_src); |
| | 544 | } |
| | 545 | |
| | 546 | fn dbgSetEpilogueBegin(self: *Self) InnerError!void { |
| | 547 | try self.dbg_line.append(DW.LNS_set_epilogue_begin); |
| | 548 | try self.dbgAdvancePCAndLine(self.prev_di_src); |
| | 549 | } |
| | 550 | |
| | 551 | fn dbgAdvancePCAndLine(self: *Self, src: usize) InnerError!void { |
| | 552 | // TODO Look into improving the performance here by adding a token-index-to-line |
| | 553 | // lookup table, and changing ir.Inst from storing byte offset to token. Currently |
| | 554 | // this involves scanning over the source code for newlines |
| | 555 | // (but only from the previous byte offset to the new one). |
| | 556 | const delta_line = std.zig.lineDelta(self.source, self.prev_di_src, src); |
| | 557 | const delta_pc = self.code.items.len - self.prev_di_pc; |
| | 558 | self.prev_di_src = src; |
| | 559 | self.prev_di_pc = self.code.items.len; |
| | 560 | // TODO Look into using the DWARF special opcodes to compress this data. It lets you emit |
| | 561 | // single-byte opcodes that add different numbers to both the PC and the line number |
| | 562 | // at the same time. |
| | 563 | try self.dbg_line.ensureCapacity(self.dbg_line.items.len + 11); |
| | 564 | self.dbg_line.appendAssumeCapacity(DW.LNS_advance_pc); |
| | 565 | leb128.writeULEB128(self.dbg_line.writer(), delta_pc) catch unreachable; |
| | 566 | if (delta_line != 0) { |
| | 567 | self.dbg_line.appendAssumeCapacity(DW.LNS_advance_line); |
| | 568 | leb128.writeULEB128(self.dbg_line.writer(), delta_line) catch unreachable; |
| | 569 | } |
| | 570 | self.dbg_line.appendAssumeCapacity(DW.LNS_copy); |
| | 571 | } |
| | 572 | |
| 512 | fn processDeath(self: *Self, inst: *ir.Inst) void { | 573 | fn processDeath(self: *Self, inst: *ir.Inst) void { |
| 513 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; | 574 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 514 | const entry = branch.inst_table.getEntry(inst) orelse return; | 575 | const entry = branch.inst_table.getEntry(inst) orelse return; |
| ... | @@ -544,6 +605,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -544,6 +605,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 544 | .cmp_neq => return self.genCmp(inst.castTag(.cmp_neq).?, .neq), | 605 | .cmp_neq => return self.genCmp(inst.castTag(.cmp_neq).?, .neq), |
| 545 | .condbr => return self.genCondBr(inst.castTag(.condbr).?), | 606 | .condbr => return self.genCondBr(inst.castTag(.condbr).?), |
| 546 | .constant => unreachable, // excluded from function bodies | 607 | .constant => unreachable, // excluded from function bodies |
| | 608 | .dbg_stmt => return self.genDbgStmt(inst.castTag(.dbg_stmt).?), |
| 547 | .floatcast => return self.genFloatCast(inst.castTag(.floatcast).?), | 609 | .floatcast => return self.genFloatCast(inst.castTag(.floatcast).?), |
| 548 | .intcast => return self.genIntCast(inst.castTag(.intcast).?), | 610 | .intcast => return self.genIntCast(inst.castTag(.intcast).?), |
| 549 | .isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?), | 611 | .isnonnull => return self.genIsNonNull(inst.castTag(.isnonnull).?), |
| ... | @@ -1107,6 +1169,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -1107,6 +1169,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1107 | } | 1169 | } |
| 1108 | } | 1170 | } |
| 1109 | | 1171 | |
| | 1172 | fn genDbgStmt(self: *Self, inst: *ir.Inst.NoOp) !MCValue { |
| | 1173 | try self.dbgAdvancePCAndLine(inst.base.src); |
| | 1174 | return MCValue.none; |
| | 1175 | } |
| | 1176 | |
| 1110 | fn genCondBr(self: *Self, inst: *ir.Inst.CondBr) !MCValue { | 1177 | fn genCondBr(self: *Self, inst: *ir.Inst.CondBr) !MCValue { |
| 1111 | switch (arch) { | 1178 | switch (arch) { |
| 1112 | .x86_64 => { | 1179 | .x86_64 => { |