| author | |
| committer | |
| log | 2be3033acda53389cac9f3e9a8ca0a3d41348eef |
| tree | af1a41562ca6ed1f7758c55d625d444509834241 |
| parent | 28df64cba45595a201f8c2312656922a8c28a67c |
we use a code offset map in Emit.zig to pre-compute what byte offset each MIR instruction is at. this is important because they can be
of different size4 files changed, 119 insertions(+), 42 deletions(-)
lib/std/builtin.zig+2-6| ... | @@ -759,11 +759,6 @@ else | ... | @@ -759,11 +759,6 @@ else |
| 759 | pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr: ?usize) noreturn { | 759 | pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr: ?usize) noreturn { |
| 760 | @setCold(true); | 760 | @setCold(true); |
| 761 | 761 | ||
| 762 | // stage2_riscv64 backend doesn't support loops yet. | ||
| 763 | if (builtin.zig_backend == .stage2_riscv64) { | ||
| 764 | unreachable; | ||
| 765 | } | ||
| 766 | |||
| 767 | // For backends that cannot handle the language features depended on by the | 762 | // For backends that cannot handle the language features depended on by the |
| 768 | // default panic handler, we have a simpler panic handler: | 763 | // default panic handler, we have a simpler panic handler: |
| 769 | if (builtin.zig_backend == .stage2_wasm or | 764 | if (builtin.zig_backend == .stage2_wasm or |
| ... | @@ -772,7 +767,8 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr | ... | @@ -772,7 +767,8 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr |
| 772 | builtin.zig_backend == .stage2_x86 or | 767 | builtin.zig_backend == .stage2_x86 or |
| 773 | (builtin.zig_backend == .stage2_x86_64 and (builtin.target.ofmt != .elf and builtin.target.ofmt != .macho)) or | 768 | (builtin.zig_backend == .stage2_x86_64 and (builtin.target.ofmt != .elf and builtin.target.ofmt != .macho)) or |
| 774 | builtin.zig_backend == .stage2_sparc64 or | 769 | builtin.zig_backend == .stage2_sparc64 or |
| 775 | builtin.zig_backend == .stage2_spirv64) | 770 | builtin.zig_backend == .stage2_spirv64 or |
| 771 | builtin.zig_backend == .stage2_riscv64) | ||
| 776 | { | 772 | { |
| 777 | while (true) { | 773 | while (true) { |
| 778 | @breakpoint(); | 774 | @breakpoint(); |
src/arch/riscv64/CodeGen.zig+29-22| ... | @@ -301,6 +301,7 @@ pub fn generate( | ... | @@ -301,6 +301,7 @@ pub fn generate( |
| 301 | .prev_di_line = func.lbrace_line, | 301 | .prev_di_line = func.lbrace_line, |
| 302 | .prev_di_column = func.lbrace_column, | 302 | .prev_di_column = func.lbrace_column, |
| 303 | .stack_size = @max(32, function.max_end_stack), | 303 | .stack_size = @max(32, function.max_end_stack), |
| 304 | .code_offset_mapping = .{}, | ||
| 304 | }; | 305 | }; |
| 305 | defer emit.deinit(); | 306 | defer emit.deinit(); |
| 306 | 307 | ||
| ... | @@ -929,21 +930,16 @@ fn binOpRegister( | ... | @@ -929,21 +930,16 @@ fn binOpRegister( |
| 929 | .cmp_gt => .cmp_gt, | 930 | .cmp_gt => .cmp_gt, |
| 930 | else => return self.fail("TODO: binOpRegister {s}", .{@tagName(tag)}), | 931 | else => return self.fail("TODO: binOpRegister {s}", .{@tagName(tag)}), |
| 931 | }; | 932 | }; |
| 932 | const mir_data: Mir.Inst.Data = switch (tag) { | ||
| 933 | .add, | ||
| 934 | .sub, | ||
| 935 | .cmp_eq, | ||
| 936 | => .{ .r_type = .{ | ||
| 937 | .rd = dest_reg, | ||
| 938 | .rs1 = lhs_reg, | ||
| 939 | .rs2 = rhs_reg, | ||
| 940 | } }, | ||
| 941 | else => return self.fail("TODO: binOpRegister {s}", .{@tagName(tag)}), | ||
| 942 | }; | ||
| 943 | 933 | ||
| 944 | _ = try self.addInst(.{ | 934 | _ = try self.addInst(.{ |
| 945 | .tag = mir_tag, | 935 | .tag = mir_tag, |
| 946 | .data = mir_data, | 936 | .data = .{ |
| 937 | .r_type = .{ | ||
| 938 | .rd = dest_reg, | ||
| 939 | .rs1 = lhs_reg, | ||
| 940 | .rs2 = rhs_reg, | ||
| 941 | }, | ||
| 942 | }, | ||
| 947 | }); | 943 | }); |
| 948 | 944 | ||
| 949 | return MCValue{ .register = dest_reg }; | 945 | return MCValue{ .register = dest_reg }; |
| ... | @@ -1636,7 +1632,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1636,7 +1632,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 1636 | 1632 | ||
| 1637 | const dst_mcv = switch (src_mcv) { | 1633 | const dst_mcv = switch (src_mcv) { |
| 1638 | .register => |src_reg| dst: { | 1634 | .register => |src_reg| dst: { |
| 1639 | self.register_manager.getRegAssumeFree(src_reg, inst); | 1635 | try self.register_manager.getReg(src_reg, inst); |
| 1640 | break :dst src_mcv; | 1636 | break :dst src_mcv; |
| 1641 | }, | 1637 | }, |
| 1642 | else => return self.fail("TODO: airArg {s}", .{@tagName(src_mcv)}), | 1638 | else => return self.fail("TODO: airArg {s}", .{@tagName(src_mcv)}), |
| ... | @@ -1914,6 +1910,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1914,6 +1910,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 1914 | self.processDeath(operand); | 1910 | self.processDeath(operand); |
| 1915 | } | 1911 | } |
| 1916 | try self.genBody(then_body); | 1912 | try self.genBody(then_body); |
| 1913 | // point at the to-be-generated else case | ||
| 1914 | try self.performReloc(reloc, @intCast(self.mir_instructions.len)); | ||
| 1917 | 1915 | ||
| 1918 | // Revert to the previous register and stack allocation state. | 1916 | // Revert to the previous register and stack allocation state. |
| 1919 | 1917 | ||
| ... | @@ -1929,7 +1927,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1929,7 +1927,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 1929 | self.next_stack_offset = parent_next_stack_offset; | 1927 | self.next_stack_offset = parent_next_stack_offset; |
| 1930 | self.register_manager.free_registers = parent_free_registers; | 1928 | self.register_manager.free_registers = parent_free_registers; |
| 1931 | 1929 | ||
| 1932 | try self.performReloc(reloc); | ||
| 1933 | const else_branch = self.branch_stack.addOneAssumeCapacity(); | 1930 | const else_branch = self.branch_stack.addOneAssumeCapacity(); |
| 1934 | else_branch.* = .{}; | 1931 | else_branch.* = .{}; |
| 1935 | 1932 | ||
| ... | @@ -2014,8 +2011,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2014,8 +2011,6 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { |
| 2014 | var item = self.branch_stack.pop(); | 2011 | var item = self.branch_stack.pop(); |
| 2015 | item.deinit(self.gpa); | 2012 | item.deinit(self.gpa); |
| 2016 | } | 2013 | } |
| 2017 | |||
| 2018 | return self.finishAir(inst, .unreach, .{ .none, .none, .none }); | ||
| 2019 | } | 2014 | } |
| 2020 | 2015 | ||
| 2021 | fn condBr(self: *Self, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { | 2016 | fn condBr(self: *Self, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { |
| ... | @@ -2027,12 +2022,12 @@ fn condBr(self: *Self, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { | ... | @@ -2027,12 +2022,12 @@ fn condBr(self: *Self, cond_ty: Type, condition: MCValue) !Mir.Inst.Index { |
| 2027 | }; | 2022 | }; |
| 2028 | 2023 | ||
| 2029 | return try self.addInst(.{ | 2024 | return try self.addInst(.{ |
| 2030 | .tag = .beq, | 2025 | .tag = .bne, |
| 2031 | .data = .{ | 2026 | .data = .{ |
| 2032 | .b_type = .{ | 2027 | .b_type = .{ |
| 2033 | .rs1 = reg, | 2028 | .rs1 = reg, |
| 2034 | .rs2 = .zero, | 2029 | .rs2 = .zero, |
| 2035 | .imm12 = 0, // patched later. | 2030 | .inst = undefined, |
| 2036 | }, | 2031 | }, |
| 2037 | }, | 2032 | }, |
| 2038 | }); | 2033 | }); |
| ... | @@ -2218,7 +2213,13 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2218,7 +2213,13 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 2218 | try self.genBody(body); | 2213 | try self.genBody(body); |
| 2219 | 2214 | ||
| 2220 | for (self.blocks.getPtr(inst).?.relocs.items) |reloc| { | 2215 | for (self.blocks.getPtr(inst).?.relocs.items) |reloc| { |
| 2221 | try self.performReloc(reloc); | 2216 | // here we are relocing to point at the instruction after the block. |
| 2217 | // [then case] | ||
| 2218 | // [jump to end] // this is reloced | ||
| 2219 | // [else case] | ||
| 2220 | // [jump to end] // this is reloced | ||
| 2221 | // [this isn't generated yet] // point to here | ||
| 2222 | try self.performReloc(reloc, @intCast(self.mir_instructions.len)); | ||
| 2222 | } | 2223 | } |
| 2223 | 2224 | ||
| 2224 | const result = self.blocks.getPtr(inst).?.mcv; | 2225 | const result = self.blocks.getPtr(inst).?.mcv; |
| ... | @@ -2233,11 +2234,14 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2233,11 +2234,14 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 2233 | // return self.finishAir(inst, .dead, .{ condition, .none, .none }); | 2234 | // return self.finishAir(inst, .dead, .{ condition, .none, .none }); |
| 2234 | } | 2235 | } |
| 2235 | 2236 | ||
| 2236 | fn performReloc(self: *Self, inst: Mir.Inst.Index) !void { | 2237 | fn performReloc(self: *Self, inst: Mir.Inst.Index, target: Mir.Inst.Index) !void { |
| 2237 | const tag = self.mir_instructions.items(.tag)[inst]; | 2238 | const tag = self.mir_instructions.items(.tag)[inst]; |
| 2238 | 2239 | ||
| 2239 | switch (tag) { | 2240 | switch (tag) { |
| 2240 | .beq => self.mir_instructions.items(.data)[inst].b_type.imm12 = @intCast(inst), | 2241 | .bne, |
| 2242 | .beq, | ||
| 2243 | => self.mir_instructions.items(.data)[inst].b_type.inst = target, | ||
| 2244 | .jal => self.mir_instructions.items(.data)[inst].j_type.inst = target, | ||
| 2241 | else => return self.fail("TODO: performReloc {s}", .{@tagName(tag)}), | 2245 | else => return self.fail("TODO: performReloc {s}", .{@tagName(tag)}), |
| 2242 | } | 2246 | } |
| 2243 | } | 2247 | } |
| ... | @@ -2283,7 +2287,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { | ... | @@ -2283,7 +2287,7 @@ fn brVoid(self: *Self, block: Air.Inst.Index) !void { |
| 2283 | .data = .{ | 2287 | .data = .{ |
| 2284 | .j_type = .{ | 2288 | .j_type = .{ |
| 2285 | .rd = .ra, | 2289 | .rd = .ra, |
| 2286 | .imm21 = undefined, // populated later through performReloc | 2290 | .inst = undefined, |
| 2287 | }, | 2291 | }, |
| 2288 | }, | 2292 | }, |
| 2289 | })); | 2293 | })); |
| ... | @@ -2467,6 +2471,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, src_val: MCValue) Inner | ... | @@ -2467,6 +2471,9 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, src_val: MCValue) Inner |
| 2467 | } | 2471 | } |
| 2468 | }, | 2472 | }, |
| 2469 | .stack_offset, .load_symbol => { | 2473 | .stack_offset, .load_symbol => { |
| 2474 | if (true) | ||
| 2475 | return self.fail("TODO: genSetStack {s}", .{@tagName(src_val)}); | ||
| 2476 | |||
| 2470 | if (abi_size <= 8) { | 2477 | if (abi_size <= 8) { |
| 2471 | const reg = try self.copyToTmpRegister(ty, src_val); | 2478 | const reg = try self.copyToTmpRegister(ty, src_val); |
| 2472 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); | 2479 | return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); |
src/arch/riscv64/Emit.zig+86-12| ... | @@ -26,8 +26,14 @@ prev_di_line: u32, | ... | @@ -26,8 +26,14 @@ prev_di_line: u32, |
| 26 | prev_di_column: u32, | 26 | prev_di_column: u32, |
| 27 | /// Relative to the beginning of `code`. | 27 | /// Relative to the beginning of `code`. |
| 28 | prev_di_pc: usize, | 28 | prev_di_pc: usize, |
| 29 | 29 | /// Function's stack size. Used for backpatching. | |
| 30 | stack_size: u32, | 30 | stack_size: u32, |
| 31 | /// For backward branches: stores the code offset of the target | ||
| 32 | /// instruction | ||
| 33 | /// | ||
| 34 | /// For forward branches: stores the code offset of the branch | ||
| 35 | /// instruction | ||
| 36 | code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .{}, | ||
| 31 | 37 | ||
| 32 | const log = std.log.scoped(.emit); | 38 | const log = std.log.scoped(.emit); |
| 33 | 39 | ||
| ... | @@ -100,6 +106,10 @@ pub fn emitMir( | ... | @@ -100,6 +106,10 @@ pub fn emitMir( |
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | pub fn deinit(emit: *Emit) void { | 108 | pub fn deinit(emit: *Emit) void { |
| 109 | const comp = emit.bin_file.comp; | ||
| 110 | const gpa = comp.gpa; | ||
| 111 | |||
| 112 | emit.code_offset_mapping.deinit(gpa); | ||
| 103 | emit.* = undefined; | 113 | emit.* = undefined; |
| 104 | } | 114 | } |
| 105 | 115 | ||
| ... | @@ -118,10 +128,8 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { | ... | @@ -118,10 +128,8 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { |
| 118 | } | 128 | } |
| 119 | 129 | ||
| 120 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void { | 130 | fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void { |
| 121 | log.debug("Line: {} {}\n", .{ line, emit.prev_di_line }); | ||
| 122 | const delta_line = @as(i32, @intCast(line)) - @as(i32, @intCast(emit.prev_di_line)); | 131 | const delta_line = @as(i32, @intCast(line)) - @as(i32, @intCast(emit.prev_di_line)); |
| 123 | const delta_pc: usize = emit.code.items.len - emit.prev_di_pc; | 132 | const delta_pc: usize = emit.code.items.len - emit.prev_di_pc; |
| 124 | log.debug("(advance pc={d} and line={d})", .{ delta_pc, delta_line }); | ||
| 125 | switch (emit.debug_output) { | 133 | switch (emit.debug_output) { |
| 126 | .dwarf => |dw| { | 134 | .dwarf => |dw| { |
| 127 | if (column != emit.prev_di_column) try dw.setColumn(column); | 135 | if (column != emit.prev_di_column) try dw.setColumn(column); |
| ... | @@ -166,7 +174,7 @@ fn mirRType(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -166,7 +174,7 @@ fn mirRType(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 166 | switch (tag) { | 174 | switch (tag) { |
| 167 | .add => try emit.writeInstruction(Instruction.add(r_type.rd, r_type.rs1, r_type.rs2)), | 175 | .add => try emit.writeInstruction(Instruction.add(r_type.rd, r_type.rs1, r_type.rs2)), |
| 168 | .sub => try emit.writeInstruction(Instruction.sub(r_type.rd, r_type.rs1, r_type.rs2)), | 176 | .sub => try emit.writeInstruction(Instruction.sub(r_type.rd, r_type.rs1, r_type.rs2)), |
| 169 | .cmp_eq => try emit.writeInstruction(Instruction.slt(r_type.rd, r_type.rs1, r_type.rs2)), | 177 | .cmp_gt => try emit.writeInstruction(Instruction.slt(r_type.rd, r_type.rs1, r_type.rs2)), |
| 170 | else => unreachable, | 178 | else => unreachable, |
| 171 | } | 179 | } |
| 172 | } | 180 | } |
| ... | @@ -175,8 +183,17 @@ fn mirBType(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -175,8 +183,17 @@ fn mirBType(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 175 | const tag = emit.mir.instructions.items(.tag)[inst]; | 183 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 176 | const b_type = emit.mir.instructions.items(.data)[inst].b_type; | 184 | const b_type = emit.mir.instructions.items(.data)[inst].b_type; |
| 177 | 185 | ||
| 186 | const offset = @as(i64, @intCast(emit.code_offset_mapping.get(b_type.inst).?)) - @as(i64, @intCast(emit.code.items.len)); | ||
| 187 | |||
| 178 | switch (tag) { | 188 | switch (tag) { |
| 179 | .beq => try emit.writeInstruction(Instruction.beq(b_type.rs1, b_type.rs2, b_type.imm12)), | 189 | .beq => { |
| 190 | log.debug("beq: {} offset={}", .{ inst, offset }); | ||
| 191 | try emit.writeInstruction(Instruction.beq(b_type.rs1, b_type.rs2, @intCast(offset))); | ||
| 192 | }, | ||
| 193 | .bne => { | ||
| 194 | log.debug("bne: {} offset={}", .{ inst, offset }); | ||
| 195 | try emit.writeInstruction(Instruction.bne(b_type.rs1, b_type.rs2, @intCast(offset))); | ||
| 196 | }, | ||
| 180 | else => unreachable, | 197 | else => unreachable, |
| 181 | } | 198 | } |
| 182 | } | 199 | } |
| ... | @@ -215,9 +232,12 @@ fn mirJType(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -215,9 +232,12 @@ fn mirJType(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 215 | const tag = emit.mir.instructions.items(.tag)[inst]; | 232 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 216 | const j_type = emit.mir.instructions.items(.data)[inst].j_type; | 233 | const j_type = emit.mir.instructions.items(.data)[inst].j_type; |
| 217 | 234 | ||
| 235 | const offset = @as(i64, @intCast(emit.code_offset_mapping.get(j_type.inst).?)) - @as(i64, @intCast(emit.code.items.len)); | ||
| 236 | |||
| 218 | switch (tag) { | 237 | switch (tag) { |
| 219 | .jal => { | 238 | .jal => { |
| 220 | try emit.writeInstruction(Instruction.jal(j_type.rd, j_type.imm21)); | 239 | log.debug("jal: {} offset={}", .{ inst, offset }); |
| 240 | try emit.writeInstruction(Instruction.jal(j_type.rd, @intCast(offset))); | ||
| 221 | }, | 241 | }, |
| 222 | else => unreachable, | 242 | else => unreachable, |
| 223 | } | 243 | } |
| ... | @@ -304,12 +324,8 @@ fn mirPsuedo(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -304,12 +324,8 @@ fn mirPsuedo(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 304 | }, | 324 | }, |
| 305 | 325 | ||
| 306 | .j => { | 326 | .j => { |
| 307 | const target = data.inst; | 327 | const offset = @as(i64, @intCast(emit.code_offset_mapping.get(data.inst).?)) - @as(i64, @intCast(emit.code.items.len)); |
| 308 | const offset: i12 = @intCast(emit.code.items.len); | 328 | try emit.writeInstruction(Instruction.jal(.s0, @intCast(offset))); |
| 309 | _ = target; | ||
| 310 | |||
| 311 | try emit.writeInstruction(Instruction.jal(.s0, offset)); | ||
| 312 | unreachable; // TODO: mirPsuedo j | ||
| 313 | }, | 329 | }, |
| 314 | 330 | ||
| 315 | else => unreachable, | 331 | else => unreachable, |
| ... | @@ -401,7 +417,51 @@ fn isLoad(tag: Mir.Inst.Tag) bool { | ... | @@ -401,7 +417,51 @@ fn isLoad(tag: Mir.Inst.Tag) bool { |
| 401 | }; | 417 | }; |
| 402 | } | 418 | } |
| 403 | 419 | ||
| 420 | pub fn isBranch(tag: Mir.Inst.Tag) bool { | ||
| 421 | return switch (tag) { | ||
| 422 | .beq => true, | ||
| 423 | .bne => true, | ||
| 424 | .jal => true, | ||
| 425 | .j => true, | ||
| 426 | else => false, | ||
| 427 | }; | ||
| 428 | } | ||
| 429 | |||
| 430 | pub fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index { | ||
| 431 | const tag = emit.mir.instructions.items(.tag)[inst]; | ||
| 432 | const data = emit.mir.instructions.items(.data)[inst]; | ||
| 433 | |||
| 434 | switch (tag) { | ||
| 435 | .bne, | ||
| 436 | .beq, | ||
| 437 | => return data.b_type.inst, | ||
| 438 | .jal => return data.j_type.inst, | ||
| 439 | .j => return data.inst, | ||
| 440 | else => std.debug.panic("branchTarget {s}", .{@tagName(tag)}), | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | fn instructionSize(emit: *Emit, inst: Mir.Inst.Index) usize { | ||
| 445 | const tag = emit.mir.instructions.items(.tag)[inst]; | ||
| 446 | |||
| 447 | return switch (tag) { | ||
| 448 | .dbg_line, | ||
| 449 | .dbg_epilogue_begin, | ||
| 450 | .dbg_prologue_end, | ||
| 451 | => 0, | ||
| 452 | |||
| 453 | .psuedo_epilogue => 12, // 3 * 4 | ||
| 454 | .psuedo_prologue => 16, // 4 * 4 | ||
| 455 | |||
| 456 | .abs => 12, // 3 * 4 | ||
| 457 | |||
| 458 | else => 4, | ||
| 459 | }; | ||
| 460 | } | ||
| 461 | |||
| 404 | fn lowerMir(emit: *Emit) !void { | 462 | fn lowerMir(emit: *Emit) !void { |
| 463 | const comp = emit.bin_file.comp; | ||
| 464 | const gpa = comp.gpa; | ||
| 405 | const mir_tags = emit.mir.instructions.items(.tag); | 465 | const mir_tags = emit.mir.instructions.items(.tag); |
| 406 | const mir_datas = emit.mir.instructions.items(.data); | 466 | const mir_datas = emit.mir.instructions.items(.data); |
| 407 | 467 | ||
| ... | @@ -419,5 +479,19 @@ fn lowerMir(emit: *Emit) !void { | ... | @@ -419,5 +479,19 @@ fn lowerMir(emit: *Emit) !void { |
| 419 | mir_datas[inst].i_type.imm12 = -(casted_size - 12 - offset); | 479 | mir_datas[inst].i_type.imm12 = -(casted_size - 12 - offset); |
| 420 | } | 480 | } |
| 421 | } | 481 | } |
| 482 | |||
| 483 | if (isBranch(tag)) { | ||
| 484 | const target_inst = emit.branchTarget(inst); | ||
| 485 | try emit.code_offset_mapping.put(gpa, target_inst, 0); | ||
| 486 | } | ||
| 487 | } | ||
| 488 | var current_code_offset: usize = 0; | ||
| 489 | |||
| 490 | for (0..mir_tags.len) |index| { | ||
| 491 | const inst = @as(u32, @intCast(index)); | ||
| 492 | if (emit.code_offset_mapping.getPtr(inst)) |offset| { | ||
| 493 | offset.* = current_code_offset; | ||
| 494 | } | ||
| 495 | current_code_offset += emit.instructionSize(inst); | ||
| 422 | } | 496 | } |
| 423 | } | 497 | } |
src/arch/riscv64/Mir.zig+2-2| ... | @@ -158,14 +158,14 @@ pub const Inst = struct { | ... | @@ -158,14 +158,14 @@ pub const Inst = struct { |
| 158 | b_type: struct { | 158 | b_type: struct { |
| 159 | rs1: Register, | 159 | rs1: Register, |
| 160 | rs2: Register, | 160 | rs2: Register, |
| 161 | imm12: i13, | 161 | inst: Inst.Index, |
| 162 | }, | 162 | }, |
| 163 | /// J-Type | 163 | /// J-Type |
| 164 | /// | 164 | /// |
| 165 | /// Used by e.g. jal | 165 | /// Used by e.g. jal |
| 166 | j_type: struct { | 166 | j_type: struct { |
| 167 | rd: Register, | 167 | rd: Register, |
| 168 | imm21: i21, | 168 | inst: Inst.Index, |
| 169 | }, | 169 | }, |
| 170 | /// U-Type | 170 | /// U-Type |
| 171 | /// | 171 | /// |