| ... | ... | @@ -629,6 +629,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 629 | 629 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 630 | 630 | // zig fmt: on |
| 631 | 631 | } |
| 632 | |
| 633 | assert(!self.register_manager.frozenRegsExist()); |
| 634 | |
| 632 | 635 | if (std.debug.runtime_safety) { |
| 633 | 636 | if (self.air_bookkeeping < old_air_bookkeeping + 1) { |
| 634 | 637 | std.debug.panic("in codegen.zig, handling of AIR instruction %{d} ('{}') did not do proper bookkeeping. Look for a missing call to finishAir.", .{ inst, air_tags[inst] }); |
| ... | ... | @@ -1233,18 +1236,21 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1233 | 1236 | // of two (includes elem_size == 1) |
| 1234 | 1237 | const offset_mcv = try self.genArmMulConstant(inst, bin_op.rhs, 1, @intCast(u32, elem_size)); |
| 1235 | 1238 | assert(offset_mcv == .register); // result of multiplication should always be register |
| 1239 | self.register_manager.freezeRegs(&.{offset_mcv.register}); |
| 1240 | defer self.register_manager.unfreezeRegs(&.{offset_mcv.register}); |
| 1236 | 1241 | |
| 1237 | 1242 | const base_mcv: MCValue = switch (slice_mcv) { |
| 1238 | | .stack_offset => |off| blk: { |
| 1239 | | const reg = try self.register_manager.allocReg(null, &.{offset_mcv.register}); |
| 1240 | | try self.genSetReg(slice_ptr_field_type, reg, MCValue{ .stack_offset = off }); |
| 1241 | | break :blk MCValue{ .register = reg }; |
| 1242 | | }, |
| 1243 | .stack_offset => .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, slice_mcv) }, |
| 1243 | 1244 | else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}), |
| 1244 | 1245 | }; |
| 1246 | self.register_manager.freezeRegs(&.{base_mcv.register}); |
| 1247 | defer self.register_manager.unfreezeRegs(&.{base_mcv.register}); |
| 1245 | 1248 | |
| 1246 | 1249 | if (elem_size <= 4) { |
| 1247 | | const dst_reg = try self.register_manager.allocReg(inst, &.{ base_mcv.register, offset_mcv.register }); |
| 1250 | const dst_reg = try self.register_manager.allocReg(inst, &.{}); |
| 1251 | self.register_manager.freezeRegs(&.{dst_reg}); |
| 1252 | defer self.register_manager.unfreezeRegs(&.{dst_reg}); |
| 1253 | |
| 1248 | 1254 | switch (elem_size) { |
| 1249 | 1255 | 1, 4 => { |
| 1250 | 1256 | const tag: Mir.Inst.Tag = switch (elem_size) { |
| ... | ... | @@ -1278,9 +1284,20 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1278 | 1284 | break :result MCValue{ .register = dst_reg }; |
| 1279 | 1285 | } else { |
| 1280 | 1286 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 1281 | | const addr_reg = try self.register_manager.allocReg(null, &.{ base_mcv.register, offset_mcv.register }); |
| 1287 | |
| 1288 | const addr_reg = try self.register_manager.allocReg(null, &.{}); |
| 1289 | self.register_manager.freezeRegs(&.{addr_reg}); |
| 1290 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| 1282 | 1291 | |
| 1283 | 1292 | try self.genArmBinOpCode(addr_reg, base_mcv, offset_mcv, false, .add, .unsigned); |
| 1293 | |
| 1294 | // I know we will unfreeze these registers at the end of |
| 1295 | // the scope of :result. However, at this point in time, |
| 1296 | // neither the base register nor the offset register |
| 1297 | // contains any valuable data anymore. In order to reduce |
| 1298 | // register pressure, unfreeze them prematurely |
| 1299 | self.register_manager.unfreezeRegs(&.{ base_mcv.register, offset_mcv.register }); |
| 1300 | |
| 1284 | 1301 | try self.load(dst_mcv, .{ .register = addr_reg }, slice_ptr_field_type); |
| 1285 | 1302 | |
| 1286 | 1303 | break :result dst_mcv; |
| ... | ... | @@ -1400,6 +1417,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1400 | 1417 | return self.fail("TODO implement loading from MCValue.embedded_in_code", .{}); |
| 1401 | 1418 | }, |
| 1402 | 1419 | .register => |reg| { |
| 1420 | self.register_manager.freezeRegs(&.{reg}); |
| 1421 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| 1422 | |
| 1403 | 1423 | switch (dst_mcv) { |
| 1404 | 1424 | .dead => unreachable, |
| 1405 | 1425 | .undef => unreachable, |
| ... | ... | @@ -1417,7 +1437,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1417 | 1437 | }, |
| 1418 | 1438 | .stack_offset => |off| { |
| 1419 | 1439 | if (elem_ty.abiSize(self.target.*) <= 4) { |
| 1420 | | const tmp_reg = try self.register_manager.allocReg(null, &.{reg}); |
| 1440 | const tmp_reg = try self.register_manager.allocReg(null, &.{}); |
| 1441 | self.register_manager.freezeRegs(&.{tmp_reg}); |
| 1442 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); |
| 1443 | |
| 1421 | 1444 | try self.load(.{ .register = tmp_reg }, ptr, ptr_ty); |
| 1422 | 1445 | try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg }); |
| 1423 | 1446 | } else if (elem_ty.abiSize(self.target.*) == 8) { |
| ... | ... | @@ -1428,7 +1451,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1428 | 1451 | // larger |
| 1429 | 1452 | |
| 1430 | 1453 | const usize_ty = Type.initTag(.usize); |
| 1431 | | const tmp_regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{reg}); |
| 1454 | const tmp_regs = try self.register_manager.allocRegs(2, .{ null, null }, &.{}); |
| 1455 | self.register_manager.freezeRegs(&tmp_regs); |
| 1456 | defer self.register_manager.unfreezeRegs(&tmp_regs); |
| 1457 | |
| 1432 | 1458 | _ = try self.addInst(.{ |
| 1433 | 1459 | .tag = .ldr, |
| 1434 | 1460 | .data = .{ .rr_offset = .{ |
| ... | ... | @@ -1449,7 +1475,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1449 | 1475 | try self.genSetStack(usize_ty, off + 4, MCValue{ .register = tmp_regs[1] }); |
| 1450 | 1476 | } else { |
| 1451 | 1477 | // TODO optimize the register allocation |
| 1452 | | const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, &.{reg}); |
| 1478 | const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, &.{}); |
| 1479 | self.register_manager.freezeRegs(&regs); |
| 1480 | defer self.register_manager.unfreezeRegs(&regs); |
| 1481 | |
| 1453 | 1482 | const src_reg = reg; |
| 1454 | 1483 | const dst_reg = regs[0]; |
| 1455 | 1484 | const len_reg = regs[1]; |
| ... | ... | @@ -1496,6 +1525,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1496 | 1525 | .stack_argument_offset, |
| 1497 | 1526 | => { |
| 1498 | 1527 | const reg = try self.register_manager.allocReg(null, &.{}); |
| 1528 | self.register_manager.freezeRegs(&.{reg}); |
| 1529 | defer self.register_manager.unfreezeRegs(&.{reg}); |
| 1530 | |
| 1499 | 1531 | try self.genSetReg(ptr_ty, reg, ptr); |
| 1500 | 1532 | try self.load(dst_mcv, .{ .register = reg }, ptr_ty); |
| 1501 | 1533 | }, |
| ... | ... | @@ -1550,6 +1582,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1550 | 1582 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); |
| 1551 | 1583 | }, |
| 1552 | 1584 | .register => |addr_reg| { |
| 1585 | self.register_manager.freezeRegs(&.{addr_reg}); |
| 1586 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| 1587 | |
| 1553 | 1588 | switch (value) { |
| 1554 | 1589 | .register => |value_reg| { |
| 1555 | 1590 | _ = try self.addInst(.{ |
| ... | ... | @@ -1563,9 +1598,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1563 | 1598 | }, |
| 1564 | 1599 | else => { |
| 1565 | 1600 | if (value_ty.abiSize(self.target.*) <= 4) { |
| 1566 | | const tmp_reg = try self.register_manager.allocReg(null, &.{addr_reg}); |
| 1567 | | try self.genSetReg(value_ty, tmp_reg, value); |
| 1601 | const tmp_reg = try self.register_manager.allocReg(null, &.{}); |
| 1602 | self.register_manager.freezeRegs(&.{tmp_reg}); |
| 1603 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); |
| 1568 | 1604 | |
| 1605 | try self.genSetReg(value_ty, tmp_reg, value); |
| 1569 | 1606 | try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty); |
| 1570 | 1607 | } else { |
| 1571 | 1608 | return self.fail("TODO implement memcpy", .{}); |
| ... | ... | @@ -1723,6 +1760,11 @@ fn genArmBinIntOp( |
| 1723 | 1760 | else => true, |
| 1724 | 1761 | }; |
| 1725 | 1762 | |
| 1763 | if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register}); |
| 1764 | defer if (lhs_is_register) self.register_manager.unfreezeRegs(&.{lhs.register}); |
| 1765 | if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register}); |
| 1766 | defer if (rhs_is_register) self.register_manager.unfreezeRegs(&.{rhs.register}); |
| 1767 | |
| 1726 | 1768 | // Destination must be a register |
| 1727 | 1769 | var dst_mcv: MCValue = undefined; |
| 1728 | 1770 | var lhs_mcv = lhs; |
| ... | ... | @@ -1734,14 +1776,14 @@ fn genArmBinIntOp( |
| 1734 | 1776 | if (reuse_lhs) { |
| 1735 | 1777 | // Allocate 0 or 1 registers |
| 1736 | 1778 | if (!rhs_is_register and rhs_should_be_register) { |
| 1737 | | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_rhs).?, &.{lhs.register}) }; |
| 1779 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_rhs).?, &.{}) }; |
| 1738 | 1780 | branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv); |
| 1739 | 1781 | } |
| 1740 | 1782 | dst_mcv = lhs; |
| 1741 | 1783 | } else if (reuse_rhs and can_swap_lhs_and_rhs) { |
| 1742 | 1784 | // Allocate 0 or 1 registers |
| 1743 | 1785 | if (!lhs_is_register and lhs_should_be_register) { |
| 1744 | | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_lhs).?, &.{rhs.register}) }; |
| 1786 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_lhs).?, &.{}) }; |
| 1745 | 1787 | branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv); |
| 1746 | 1788 | } |
| 1747 | 1789 | dst_mcv = rhs; |
| ... | ... | @@ -1751,14 +1793,14 @@ fn genArmBinIntOp( |
| 1751 | 1793 | // Allocate 1 or 2 registers |
| 1752 | 1794 | if (lhs_should_be_register and rhs_should_be_register) { |
| 1753 | 1795 | if (lhs_is_register and rhs_is_register) { |
| 1754 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{ lhs.register, rhs.register }) }; |
| 1796 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1755 | 1797 | } else if (lhs_is_register) { |
| 1756 | 1798 | // Move RHS to register |
| 1757 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{lhs.register}) }; |
| 1799 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1758 | 1800 | rhs_mcv = dst_mcv; |
| 1759 | 1801 | } else if (rhs_is_register) { |
| 1760 | 1802 | // Move LHS to register |
| 1761 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{rhs.register}) }; |
| 1803 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1762 | 1804 | lhs_mcv = dst_mcv; |
| 1763 | 1805 | } else { |
| 1764 | 1806 | // Move LHS and RHS to register |
| ... | ... | @@ -1772,7 +1814,7 @@ fn genArmBinIntOp( |
| 1772 | 1814 | } else if (lhs_should_be_register) { |
| 1773 | 1815 | // RHS is immediate |
| 1774 | 1816 | if (lhs_is_register) { |
| 1775 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{lhs.register}) }; |
| 1817 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1776 | 1818 | } else { |
| 1777 | 1819 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1778 | 1820 | lhs_mcv = dst_mcv; |
| ... | ... | @@ -1780,7 +1822,7 @@ fn genArmBinIntOp( |
| 1780 | 1822 | } else if (rhs_should_be_register and can_swap_lhs_and_rhs) { |
| 1781 | 1823 | // LHS is immediate |
| 1782 | 1824 | if (rhs_is_register) { |
| 1783 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{rhs.register}) }; |
| 1825 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1784 | 1826 | } else { |
| 1785 | 1827 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1786 | 1828 | rhs_mcv = dst_mcv; |
| ... | ... | @@ -1926,6 +1968,11 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai |
| 1926 | 1968 | const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op_lhs, 0, lhs); |
| 1927 | 1969 | const reuse_rhs = !reuse_lhs and rhs_is_register and self.reuseOperand(inst, op_rhs, 1, rhs); |
| 1928 | 1970 | |
| 1971 | if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register}); |
| 1972 | defer if (lhs_is_register) self.register_manager.unfreezeRegs(&.{lhs.register}); |
| 1973 | if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register}); |
| 1974 | defer if (rhs_is_register) self.register_manager.unfreezeRegs(&.{rhs.register}); |
| 1975 | |
| 1929 | 1976 | // Destination must be a register |
| 1930 | 1977 | // LHS must be a register |
| 1931 | 1978 | // RHS must be a register |
| ... | ... | @@ -1938,28 +1985,28 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai |
| 1938 | 1985 | if (reuse_lhs) { |
| 1939 | 1986 | // Allocate 0 or 1 registers |
| 1940 | 1987 | if (!rhs_is_register) { |
| 1941 | | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_rhs).?, &.{lhs.register}) }; |
| 1988 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_rhs).?, &.{}) }; |
| 1942 | 1989 | branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv); |
| 1943 | 1990 | } |
| 1944 | 1991 | dst_mcv = lhs; |
| 1945 | 1992 | } else if (reuse_rhs) { |
| 1946 | 1993 | // Allocate 0 or 1 registers |
| 1947 | 1994 | if (!lhs_is_register) { |
| 1948 | | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_lhs).?, &.{rhs.register}) }; |
| 1995 | lhs_mcv = MCValue{ .register = try self.register_manager.allocReg(Air.refToIndex(op_lhs).?, &.{}) }; |
| 1949 | 1996 | branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv); |
| 1950 | 1997 | } |
| 1951 | 1998 | dst_mcv = rhs; |
| 1952 | 1999 | } else { |
| 1953 | 2000 | // Allocate 1 or 2 registers |
| 1954 | 2001 | if (lhs_is_register and rhs_is_register) { |
| 1955 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{ lhs.register, rhs.register }) }; |
| 2002 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1956 | 2003 | } else if (lhs_is_register) { |
| 1957 | 2004 | // Move RHS to register |
| 1958 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{lhs.register}) }; |
| 2005 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1959 | 2006 | rhs_mcv = dst_mcv; |
| 1960 | 2007 | } else if (rhs_is_register) { |
| 1961 | 2008 | // Move LHS to register |
| 1962 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{rhs.register}) }; |
| 2009 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) }; |
| 1963 | 2010 | lhs_mcv = dst_mcv; |
| 1964 | 2011 | } else { |
| 1965 | 2012 | // Move LHS and RHS to register |
| ... | ... | @@ -1992,29 +2039,32 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai |
| 1992 | 2039 | } |
| 1993 | 2040 | |
| 1994 | 2041 | fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_index: Liveness.OperandInt, imm: u32) !MCValue { |
| 1995 | | const mcv = try self.resolveInst(op); |
| 2042 | const lhs = try self.resolveInst(op); |
| 1996 | 2043 | const rhs = MCValue{ .immediate = imm }; |
| 1997 | 2044 | |
| 1998 | | const lhs_is_register = mcv == .register; |
| 1999 | | const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op, op_index, mcv); |
| 2045 | const lhs_is_register = lhs == .register; |
| 2046 | const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op, op_index, lhs); |
| 2047 | |
| 2048 | if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register}); |
| 2049 | defer if (lhs_is_register) self.register_manager.unfreezeRegs(&.{lhs.register}); |
| 2000 | 2050 | |
| 2001 | 2051 | // Destination must be a register |
| 2002 | 2052 | // LHS must be a register |
| 2003 | 2053 | // RHS must be a register |
| 2004 | 2054 | var dst_mcv: MCValue = undefined; |
| 2005 | | var lhs_mcv: MCValue = mcv; |
| 2055 | var lhs_mcv: MCValue = lhs; |
| 2006 | 2056 | var rhs_mcv: MCValue = rhs; |
| 2007 | 2057 | |
| 2008 | 2058 | // Allocate registers for operands and/or destination |
| 2009 | 2059 | if (reuse_lhs) { |
| 2010 | 2060 | // Allocate 1 register |
| 2011 | | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{mcv.register}) }; |
| 2012 | | dst_mcv = mcv; |
| 2061 | rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{}) }; |
| 2062 | dst_mcv = lhs; |
| 2013 | 2063 | } else { |
| 2014 | 2064 | // Allocate 1 or 2 registers |
| 2015 | 2065 | if (lhs_is_register) { |
| 2016 | 2066 | // Move RHS to register |
| 2017 | | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{mcv.register}) }; |
| 2067 | dst_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{}) }; |
| 2018 | 2068 | rhs_mcv = dst_mcv; |
| 2019 | 2069 | } else { |
| 2020 | 2070 | // Move LHS and RHS to register |
| ... | ... | @@ -2027,7 +2077,7 @@ fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_ind |
| 2027 | 2077 | |
| 2028 | 2078 | // Move the operands to the newly allocated registers |
| 2029 | 2079 | if (!lhs_is_register) { |
| 2030 | | try self.genSetReg(self.air.typeOf(op), lhs_mcv.register, mcv); |
| 2080 | try self.genSetReg(self.air.typeOf(op), lhs_mcv.register, lhs); |
| 2031 | 2081 | } |
| 2032 | 2082 | try self.genSetReg(Type.initTag(.usize), rhs_mcv.register, rhs); |
| 2033 | 2083 | |
| ... | ... | @@ -2375,6 +2425,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 2375 | 2425 | // lhs should always be a register |
| 2376 | 2426 | const rhs_should_be_register = try self.armOperandShouldBeRegister(rhs); |
| 2377 | 2427 | |
| 2428 | if (lhs_is_register) self.register_manager.freezeRegs(&.{lhs.register}); |
| 2429 | defer if (lhs_is_register) self.register_manager.unfreezeRegs(&.{lhs.register}); |
| 2430 | if (rhs_is_register) self.register_manager.freezeRegs(&.{rhs.register}); |
| 2431 | defer if (rhs_is_register) self.register_manager.unfreezeRegs(&.{rhs.register}); |
| 2432 | |
| 2378 | 2433 | var lhs_mcv = lhs; |
| 2379 | 2434 | var rhs_mcv = rhs; |
| 2380 | 2435 | |