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