| author | |
| committer | |
| log | 331f6a07a98206c3b5c096e73860ef1b7a3dfe85 |
| tree | ac5a8794de5467d828e375297e92b52c0ee40614 |
| parent | b7a883b7d1247e9342805a8d06e70fd4d02f11b3 |
3 files changed, 48 insertions(+), 24 deletions(-)
src-self-hosted/codegen.zig+18-9| ... | @@ -396,12 +396,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -396,12 +396,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 396 | const branch = try branch_stack.addOne(); | 396 | const branch = try branch_stack.addOne(); |
| 397 | branch.* = .{}; | 397 | branch.* = .{}; |
| 398 | 398 | ||
| 399 | const scope_file = module_fn.owner_decl.scope.cast(Module.Scope.File).?; | 399 | const src_data: struct {lbrace_src: usize, rbrace_src: usize, source: []const u8} = blk: { |
| 400 | const tree = scope_file.contents.tree; | 400 | if (module_fn.owner_decl.scope.cast(Module.Scope.File)) |scope_file| { |
| 401 | const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?; | 401 | const tree = scope_file.contents.tree; |
| 402 | const block = fn_proto.body().?.castTag(.Block).?; | 402 | const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?; |
| 403 | const lbrace_src = tree.token_locs[block.lbrace].start; | 403 | const block = fn_proto.body().?.castTag(.Block).?; |
| 404 | const rbrace_src = tree.token_locs[block.rbrace].start; | 404 | const lbrace_src = tree.token_locs[block.lbrace].start; |
| 405 | const rbrace_src = tree.token_locs[block.rbrace].start; | ||
| 406 | break :blk .{ .lbrace_src = lbrace_src, .rbrace_src = rbrace_src, .source = tree.source }; | ||
| 407 | } else if (module_fn.owner_decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { | ||
| 408 | const byte_off = zir_module.contents.module.decls[module_fn.owner_decl.src_index].inst.src; | ||
| 409 | break :blk .{ .lbrace_src = byte_off, .rbrace_src = byte_off, .source = zir_module.source.bytes }; | ||
| 410 | } else { | ||
| 411 | unreachable; | ||
| 412 | } | ||
| 413 | }; | ||
| 405 | 414 | ||
| 406 | var function = Self{ | 415 | var function = Self{ |
| 407 | .gpa = bin_file.allocator, | 416 | .gpa = bin_file.allocator, |
| ... | @@ -419,9 +428,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -419,9 +428,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 419 | .src = src, | 428 | .src = src, |
| 420 | .stack_align = undefined, | 429 | .stack_align = undefined, |
| 421 | .prev_di_pc = 0, | 430 | .prev_di_pc = 0, |
| 422 | .prev_di_src = lbrace_src, | 431 | .prev_di_src = src_data.lbrace_src, |
| 423 | .rbrace_src = rbrace_src, | 432 | .rbrace_src = src_data.rbrace_src, |
| 424 | .source = tree.source, | 433 | .source = src_data.source, |
| 425 | }; | 434 | }; |
| 426 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); | 435 | defer function.exitlude_jump_relocs.deinit(bin_file.allocator); |
| 427 | 436 |
src-self-hosted/codegen/c.zig+11-5| ... | @@ -89,17 +89,17 @@ fn genFn(file: *C, decl: *Decl) !void { | ... | @@ -89,17 +89,17 @@ fn genFn(file: *C, decl: *Decl) !void { |
| 89 | const func: *Module.Fn = tv.val.cast(Value.Payload.Function).?.func; | 89 | const func: *Module.Fn = tv.val.cast(Value.Payload.Function).?.func; |
| 90 | const instructions = func.analysis.success.instructions; | 90 | const instructions = func.analysis.success.instructions; |
| 91 | if (instructions.len > 0) { | 91 | if (instructions.len > 0) { |
| 92 | try writer.writeAll("\n"); | ||
| 92 | for (instructions) |inst| { | 93 | for (instructions) |inst| { |
| 93 | try writer.writeAll("\n "); | ||
| 94 | switch (inst.tag) { | 94 | switch (inst.tag) { |
| 95 | .assembly => try genAsm(file, inst.castTag(.assembly).?, decl), | 95 | .assembly => try genAsm(file, inst.castTag(.assembly).?, decl), |
| 96 | .call => try genCall(file, inst.castTag(.call).?, decl), | 96 | .call => try genCall(file, inst.castTag(.call).?, decl), |
| 97 | .ret => try genRet(file, inst.castTag(.ret).?, decl, tv.ty.fnReturnType()), | 97 | .ret => try genRet(file, inst.castTag(.ret).?, decl, tv.ty.fnReturnType()), |
| 98 | .retvoid => try file.main.writer().print("return;", .{}), | 98 | .retvoid => try file.main.writer().print(" return;\n", .{}), |
| 99 | .dbg_stmt => try genDbgStmt(file, inst.castTag(.dbg_stmt).?, decl), | ||
| 99 | else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}), | 100 | else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}), |
| 100 | } | 101 | } |
| 101 | } | 102 | } |
| 102 | try writer.writeAll("\n"); | ||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | try writer.writeAll("}\n\n"); | 105 | try writer.writeAll("}\n\n"); |
| ... | @@ -112,6 +112,7 @@ fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) ! | ... | @@ -112,6 +112,7 @@ fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) ! |
| 112 | fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { | 112 | fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 113 | const writer = file.main.writer(); | 113 | const writer = file.main.writer(); |
| 114 | const header = file.header.writer(); | 114 | const header = file.header.writer(); |
| 115 | try writer.writeAll(" "); | ||
| 115 | if (inst.func.castTag(.constant)) |func_inst| { | 116 | if (inst.func.castTag(.constant)) |func_inst| { |
| 116 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { | 117 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { |
| 117 | const target = func_val.func.owner_decl; | 118 | const target = func_val.func.owner_decl; |
| ... | @@ -126,7 +127,7 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { | ... | @@ -126,7 +127,7 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 126 | try renderFunctionSignature(file, header, target); | 127 | try renderFunctionSignature(file, header, target); |
| 127 | try header.writeAll(";\n"); | 128 | try header.writeAll(";\n"); |
| 128 | } | 129 | } |
| 129 | try writer.print("{}();", .{tname}); | 130 | try writer.print("{}();\n", .{tname}); |
| 130 | } else { | 131 | } else { |
| 131 | return file.fail(decl.src(), "TODO non-function call target?", .{}); | 132 | return file.fail(decl.src(), "TODO non-function call target?", .{}); |
| 132 | } | 133 | } |
| ... | @@ -138,8 +139,13 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { | ... | @@ -138,8 +139,13 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void { |
| 138 | } | 139 | } |
| 139 | } | 140 | } |
| 140 | 141 | ||
| 142 | fn genDbgStmt(file: *C, inst: *Inst.NoOp, decl: *Decl) !void { | ||
| 143 | // TODO emit #line directive here with line number and filename | ||
| 144 | } | ||
| 145 | |||
| 141 | fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { | 146 | fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { |
| 142 | const writer = file.main.writer(); | 147 | const writer = file.main.writer(); |
| 148 | try writer.writeAll(" "); | ||
| 143 | for (as.inputs) |i, index| { | 149 | for (as.inputs) |i, index| { |
| 144 | if (i[0] == '{' and i[i.len - 1] == '}') { | 150 | if (i[0] == '{' and i[i.len - 1] == '}') { |
| 145 | const reg = i[1 .. i.len - 1]; | 151 | const reg = i[1 .. i.len - 1]; |
| ... | @@ -187,5 +193,5 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { | ... | @@ -187,5 +193,5 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void { |
| 187 | } | 193 | } |
| 188 | } | 194 | } |
| 189 | } | 195 | } |
| 190 | try writer.writeAll(");"); | 196 | try writer.writeAll(");\n"); |
| 191 | } | 197 | } |
src-self-hosted/link.zig+19-10| ... | @@ -1825,15 +1825,24 @@ pub const File = struct { | ... | @@ -1825,15 +1825,24 @@ pub const File = struct { |
| 1825 | // For functions we need to add a prologue to the debug line program. | 1825 | // For functions we need to add a prologue to the debug line program. |
| 1826 | try dbg_line_buffer.ensureCapacity(26); | 1826 | try dbg_line_buffer.ensureCapacity(26); |
| 1827 | 1827 | ||
| 1828 | const scope_file = decl.scope.cast(Module.Scope.File).?; | 1828 | const line_off: u28 = blk: { |
| 1829 | const tree = scope_file.contents.tree; | 1829 | if (decl.scope.cast(Module.Scope.File)) |scope_file| { |
| 1830 | const file_ast_decls = tree.root_node.decls(); | 1830 | const tree = scope_file.contents.tree; |
| 1831 | // TODO Look into improving the performance here by adding a token-index-to-line | 1831 | const file_ast_decls = tree.root_node.decls(); |
| 1832 | // lookup table. Currently this involves scanning over the source code for newlines. | 1832 | // TODO Look into improving the performance here by adding a token-index-to-line |
| 1833 | const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; | 1833 | // lookup table. Currently this involves scanning over the source code for newlines. |
| 1834 | const block = fn_proto.body().?.castTag(.Block).?; | 1834 | const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?; |
| 1835 | const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); | 1835 | const block = fn_proto.body().?.castTag(.Block).?; |
| 1836 | const casted_line_off = @intCast(u28, line_delta); | 1836 | const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start); |
| 1837 | break :blk @intCast(u28, line_delta); | ||
| 1838 | } else if (decl.scope.cast(Module.Scope.ZIRModule)) |zir_module| { | ||
| 1839 | const byte_off = zir_module.contents.module.decls[decl.src_index].inst.src; | ||
| 1840 | const line_delta = std.zig.lineDelta(zir_module.source.bytes, 0, byte_off); | ||
| 1841 | break :blk @intCast(u28, line_delta); | ||
| 1842 | } else { | ||
| 1843 | unreachable; | ||
| 1844 | } | ||
| 1845 | }; | ||
| 1837 | 1846 | ||
| 1838 | const ptr_width_bytes = self.ptrWidthBytes(); | 1847 | const ptr_width_bytes = self.ptrWidthBytes(); |
| 1839 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ | 1848 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ |
| ... | @@ -1850,7 +1859,7 @@ pub const File = struct { | ... | @@ -1850,7 +1859,7 @@ pub const File = struct { |
| 1850 | // to this function's begin curly. | 1859 | // to this function's begin curly. |
| 1851 | assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); | 1860 | assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); |
| 1852 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. | 1861 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. |
| 1853 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), casted_line_off); | 1862 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); |
| 1854 | 1863 | ||
| 1855 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); | 1864 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); |
| 1856 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); | 1865 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); |