| ... | @@ -23,6 +23,7 @@ const FnResult = @import("../../codegen.zig").FnResult; | ... | @@ -23,6 +23,7 @@ const FnResult = @import("../../codegen.zig").FnResult; |
| 23 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; | 23 | const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; |
| 24 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; | 24 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 25 | const RegisterManager = RegisterManagerFn(Self, Register, &abi.allocatable_regs); | 25 | const RegisterManager = RegisterManagerFn(Self, Register, &abi.allocatable_regs); |
| | 26 | const RegisterLock = RegisterManager.RegisterLock; |
| 26 | | 27 | |
| 27 | const build_options = @import("build_options"); | 28 | const build_options = @import("build_options"); |
| 28 | | 29 | |
| ... | @@ -1584,8 +1585,17 @@ fn binOpRegister( | ... | @@ -1584,8 +1585,17 @@ fn binOpRegister( |
| 1584 | const lhs_is_register = lhs == .register; | 1585 | const lhs_is_register = lhs == .register; |
| 1585 | const rhs_is_register = rhs == .register; | 1586 | const rhs_is_register = rhs == .register; |
| 1586 | | 1587 | |
| 1587 | if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register}); | 1588 | const lhs_lock: ?RegisterLock = if (lhs_is_register) |
| 1588 | if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register}); | 1589 | self.register_manager.lockReg(lhs.register) |
| | 1590 | else |
| | 1591 | null; |
| | 1592 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| | 1593 | |
| | 1594 | const rhs_lock: ?RegisterLock = if (rhs_is_register) |
| | 1595 | self.register_manager.lockReg(rhs.register) |
| | 1596 | else |
| | 1597 | null; |
| | 1598 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1589 | | 1599 | |
| 1590 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; | 1600 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 1591 | | 1601 | |
| ... | @@ -1596,13 +1606,12 @@ fn binOpRegister( | ... | @@ -1596,13 +1606,12 @@ fn binOpRegister( |
| 1596 | } else null; | 1606 | } else null; |
| 1597 | | 1607 | |
| 1598 | const reg = try self.register_manager.allocReg(track_inst); | 1608 | const reg = try self.register_manager.allocReg(track_inst); |
| 1599 | self.register_manager.freezeRegs(&.{reg}); | | |
| 1600 | | | |
| 1601 | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); | 1609 | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); |
| 1602 | | 1610 | |
| 1603 | break :blk reg; | 1611 | break :blk reg; |
| 1604 | }; | 1612 | }; |
| 1605 | defer self.register_manager.unfreezeRegs(&.{lhs_reg}); | 1613 | const new_lhs_lock = self.register_manager.lockReg(lhs_reg); |
| | 1614 | defer if (new_lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1606 | | 1615 | |
| 1607 | const rhs_reg = if (rhs_is_register) rhs.register else blk: { | 1616 | const rhs_reg = if (rhs_is_register) rhs.register else blk: { |
| 1608 | const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: { | 1617 | const track_inst: ?Air.Inst.Index = if (maybe_inst) |inst| inst: { |
| ... | @@ -1611,13 +1620,12 @@ fn binOpRegister( | ... | @@ -1611,13 +1620,12 @@ fn binOpRegister( |
| 1611 | } else null; | 1620 | } else null; |
| 1612 | | 1621 | |
| 1613 | const reg = try self.register_manager.allocReg(track_inst); | 1622 | const reg = try self.register_manager.allocReg(track_inst); |
| 1614 | self.register_manager.freezeRegs(&.{reg}); | | |
| 1615 | | | |
| 1616 | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); | 1623 | if (track_inst) |inst| branch.inst_table.putAssumeCapacity(inst, .{ .register = reg }); |
| 1617 | | 1624 | |
| 1618 | break :blk reg; | 1625 | break :blk reg; |
| 1619 | }; | 1626 | }; |
| 1620 | defer self.register_manager.unfreezeRegs(&.{rhs_reg}); | 1627 | const new_rhs_lock = self.register_manager.lockReg(rhs_reg); |
| | 1628 | defer if (new_rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1621 | | 1629 | |
| 1622 | const dest_reg = switch (mir_tag) { | 1630 | const dest_reg = switch (mir_tag) { |
| 1623 | else => if (maybe_inst) |inst| blk: { | 1631 | else => if (maybe_inst) |inst| blk: { |
| ... | @@ -2298,8 +2306,8 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2298,8 +2306,8 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2298 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), | 2306 | .immediate => |imm| try self.setRegOrMem(elem_ty, dst_mcv, .{ .memory = imm }), |
| 2299 | .ptr_stack_offset => |off| try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }), | 2307 | .ptr_stack_offset => |off| try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }), |
| 2300 | .register => |addr_reg| { | 2308 | .register => |addr_reg| { |
| 2301 | self.register_manager.freezeRegs(&.{addr_reg}); | 2309 | const addr_reg_lock = self.register_manager.lockReg(addr_reg); |
| 2302 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); | 2310 | defer if (addr_reg_lock) |reg| self.register_manager.unlockReg(reg); |
| 2303 | | 2311 | |
| 2304 | switch (dst_mcv) { | 2312 | switch (dst_mcv) { |
| 2305 | .dead => unreachable, | 2313 | .dead => unreachable, |
| ... | @@ -2311,15 +2319,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo | ... | @@ -2311,15 +2319,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2311 | .stack_offset => |off| { | 2319 | .stack_offset => |off| { |
| 2312 | if (elem_size <= 8) { | 2320 | if (elem_size <= 8) { |
| 2313 | const tmp_reg = try self.register_manager.allocReg(null); | 2321 | const tmp_reg = try self.register_manager.allocReg(null); |
| 2314 | self.register_manager.freezeRegs(&.{tmp_reg}); | 2322 | const tmp_reg_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 2315 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); | 2323 | defer self.register_manager.unlockReg(tmp_reg_lock); |
| 2316 | | 2324 | |
| 2317 | try self.load(.{ .register = tmp_reg }, ptr, ptr_ty); | 2325 | try self.load(.{ .register = tmp_reg }, ptr, ptr_ty); |
| 2318 | try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); | 2326 | try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); |
| 2319 | } else { | 2327 | } else { |
| 2320 | const regs = try self.register_manager.allocRegs(3, .{ null, null, null }); | 2328 | const regs = try self.register_manager.allocRegs(3, .{ null, null, null }); |
| 2321 | self.register_manager.freezeRegs(&regs); | 2329 | const regs_locks = self.register_manager.lockRegsAssumeUnused(3, regs); |
| 2322 | defer self.register_manager.unfreezeRegs(&regs); | 2330 | defer for (regs_locks) |reg| { |
| | 2331 | self.register_manager.unlockReg(reg); |
| | 2332 | }; |
| 2323 | | 2333 | |
| 2324 | const src_reg = addr_reg; | 2334 | const src_reg = addr_reg; |
| 2325 | const dst_reg = regs[0]; | 2335 | const dst_reg = regs[0]; |
| ... | @@ -2641,8 +2651,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type | ... | @@ -2641,8 +2651,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2641 | try self.genSetStack(value_ty, off, value); | 2651 | try self.genSetStack(value_ty, off, value); |
| 2642 | }, | 2652 | }, |
| 2643 | .register => |addr_reg| { | 2653 | .register => |addr_reg| { |
| 2644 | self.register_manager.freezeRegs(&.{addr_reg}); | 2654 | const addr_reg_lock = self.register_manager.lockReg(addr_reg); |
| 2645 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); | 2655 | defer if (addr_reg_lock) |reg| self.register_manager.unlockReg(reg); |
| 2646 | | 2656 | |
| 2647 | switch (value) { | 2657 | switch (value) { |
| 2648 | .register => |value_reg| { | 2658 | .register => |value_reg| { |