authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-01-29 13:15:44+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-30 19:41:51-05:00
log66cf011aa91a66fd8b1489d186152522ccd27550
tree64659dd08ae747a56d181b5641d886651bd4f9ab
parent227968d78c4d0c6eaa92ecae4649bfc757af2c28

stage2 ARM: Move to new regalloc freeze API


1 files changed, 87 insertions(+), 32 deletions(-)

src/arch/arm/CodeGen.zig+87-32
...@@ -629,6 +629,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -629,6 +629,9 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
629 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),629 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
630 // zig fmt: on630 // zig fmt: on
631 }631 }
632
633 assert(!self.register_manager.frozenRegsExist());
634
632 if (std.debug.runtime_safety) {635 if (std.debug.runtime_safety) {
633 if (self.air_bookkeeping < old_air_bookkeeping + 1) {636 if (self.air_bookkeeping < old_air_bookkeeping + 1) {
634 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] });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,18 +1236,21 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
1233 // of two (includes elem_size == 1)1236 // of two (includes elem_size == 1)
1234 const offset_mcv = try self.genArmMulConstant(inst, bin_op.rhs, 1, @intCast(u32, elem_size));1237 const offset_mcv = try self.genArmMulConstant(inst, bin_op.rhs, 1, @intCast(u32, elem_size));
1235 assert(offset_mcv == .register); // result of multiplication should always be register1238 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});
12361241
1237 const base_mcv: MCValue = switch (slice_mcv) {1242 const base_mcv: MCValue = switch (slice_mcv) {
1238 .stack_offset => |off| blk: {1243 .stack_offset => .{ .register = try self.copyToTmpRegister(slice_ptr_field_type, slice_mcv) },
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 else => return self.fail("TODO slice_elem_val when slice is {}", .{slice_mcv}),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});
12451248
1246 if (elem_size <= 4) {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 switch (elem_size) {1254 switch (elem_size) {
1249 1, 4 => {1255 1, 4 => {
1250 const tag: Mir.Inst.Tag = switch (elem_size) {1256 const tag: Mir.Inst.Tag = switch (elem_size) {
...@@ -1278,9 +1284,20 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -1278,9 +1284,20 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
1278 break :result MCValue{ .register = dst_reg };1284 break :result MCValue{ .register = dst_reg };
1279 } else {1285 } else {
1280 const dst_mcv = try self.allocRegOrMem(inst, false);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});
12821291
1283 try self.genArmBinOpCode(addr_reg, base_mcv, offset_mcv, false, .add, .unsigned);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 try self.load(dst_mcv, .{ .register = addr_reg }, slice_ptr_field_type);1301 try self.load(dst_mcv, .{ .register = addr_reg }, slice_ptr_field_type);
12851302
1286 break :result dst_mcv;1303 break :result dst_mcv;
...@@ -1400,6 +1417,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -1400,6 +1417,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1400 return self.fail("TODO implement loading from MCValue.embedded_in_code", .{});1417 return self.fail("TODO implement loading from MCValue.embedded_in_code", .{});
1401 },1418 },
1402 .register => |reg| {1419 .register => |reg| {
1420 self.register_manager.freezeRegs(&.{reg});
1421 defer self.register_manager.unfreezeRegs(&.{reg});
1422
1403 switch (dst_mcv) {1423 switch (dst_mcv) {
1404 .dead => unreachable,1424 .dead => unreachable,
1405 .undef => unreachable,1425 .undef => unreachable,
...@@ -1417,7 +1437,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -1417,7 +1437,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1417 },1437 },
1418 .stack_offset => |off| {1438 .stack_offset => |off| {
1419 if (elem_ty.abiSize(self.target.*) <= 4) {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 try self.load(.{ .register = tmp_reg }, ptr, ptr_ty);1444 try self.load(.{ .register = tmp_reg }, ptr, ptr_ty);
1422 try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg });1445 try self.genSetStack(elem_ty, off, MCValue{ .register = tmp_reg });
1423 } else if (elem_ty.abiSize(self.target.*) == 8) {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,7 +1451,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1428 // larger1451 // larger
14291452
1430 const usize_ty = Type.initTag(.usize);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 _ = try self.addInst(.{1458 _ = try self.addInst(.{
1433 .tag = .ldr,1459 .tag = .ldr,
1434 .data = .{ .rr_offset = .{1460 .data = .{ .rr_offset = .{
...@@ -1449,7 +1475,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -1449,7 +1475,10 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1449 try self.genSetStack(usize_ty, off + 4, MCValue{ .register = tmp_regs[1] });1475 try self.genSetStack(usize_ty, off + 4, MCValue{ .register = tmp_regs[1] });
1450 } else {1476 } else {
1451 // TODO optimize the register allocation1477 // 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 const src_reg = reg;1482 const src_reg = reg;
1454 const dst_reg = regs[0];1483 const dst_reg = regs[0];
1455 const len_reg = regs[1];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,6 +1525,9 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1496 .stack_argument_offset,1525 .stack_argument_offset,
1497 => {1526 => {
1498 const reg = try self.register_manager.allocReg(null, &.{});1527 const reg = try self.register_manager.allocReg(null, &.{});
1528 self.register_manager.freezeRegs(&.{reg});
1529 defer self.register_manager.unfreezeRegs(&.{reg});
1530
1499 try self.genSetReg(ptr_ty, reg, ptr);1531 try self.genSetReg(ptr_ty, reg, ptr);
1500 try self.load(dst_mcv, .{ .register = reg }, ptr_ty);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,6 +1582,9 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
1550 return self.fail("TODO implement storing to MCValue.embedded_in_code", .{});1582 return self.fail("TODO implement storing to MCValue.embedded_in_code", .{});
1551 },1583 },
1552 .register => |addr_reg| {1584 .register => |addr_reg| {
1585 self.register_manager.freezeRegs(&.{addr_reg});
1586 defer self.register_manager.unfreezeRegs(&.{addr_reg});
1587
1553 switch (value) {1588 switch (value) {
1554 .register => |value_reg| {1589 .register => |value_reg| {
1555 _ = try self.addInst(.{1590 _ = try self.addInst(.{
...@@ -1563,9 +1598,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -1563,9 +1598,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
1563 },1598 },
1564 else => {1599 else => {
1565 if (value_ty.abiSize(self.target.*) <= 4) {1600 if (value_ty.abiSize(self.target.*) <= 4) {
1566 const tmp_reg = try self.register_manager.allocReg(null, &.{addr_reg});1601 const tmp_reg = try self.register_manager.allocReg(null, &.{});
1567 try self.genSetReg(value_ty, tmp_reg, value);1602 self.register_manager.freezeRegs(&.{tmp_reg});
1603 defer self.register_manager.unfreezeRegs(&.{tmp_reg});
15681604
1605 try self.genSetReg(value_ty, tmp_reg, value);
1569 try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);1606 try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);
1570 } else {1607 } else {
1571 return self.fail("TODO implement memcpy", .{});1608 return self.fail("TODO implement memcpy", .{});
...@@ -1723,6 +1760,11 @@ fn genArmBinIntOp(...@@ -1723,6 +1760,11 @@ fn genArmBinIntOp(
1723 else => true,1760 else => true,
1724 };1761 };
17251762
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 // Destination must be a register1768 // Destination must be a register
1727 var dst_mcv: MCValue = undefined;1769 var dst_mcv: MCValue = undefined;
1728 var lhs_mcv = lhs;1770 var lhs_mcv = lhs;
...@@ -1734,14 +1776,14 @@ fn genArmBinIntOp(...@@ -1734,14 +1776,14 @@ fn genArmBinIntOp(
1734 if (reuse_lhs) {1776 if (reuse_lhs) {
1735 // Allocate 0 or 1 registers1777 // Allocate 0 or 1 registers
1736 if (!rhs_is_register and rhs_should_be_register) {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 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv);1780 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv);
1739 }1781 }
1740 dst_mcv = lhs;1782 dst_mcv = lhs;
1741 } else if (reuse_rhs and can_swap_lhs_and_rhs) {1783 } else if (reuse_rhs and can_swap_lhs_and_rhs) {
1742 // Allocate 0 or 1 registers1784 // Allocate 0 or 1 registers
1743 if (!lhs_is_register and lhs_should_be_register) {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 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv);1787 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv);
1746 }1788 }
1747 dst_mcv = rhs;1789 dst_mcv = rhs;
...@@ -1751,14 +1793,14 @@ fn genArmBinIntOp(...@@ -1751,14 +1793,14 @@ fn genArmBinIntOp(
1751 // Allocate 1 or 2 registers1793 // Allocate 1 or 2 registers
1752 if (lhs_should_be_register and rhs_should_be_register) {1794 if (lhs_should_be_register and rhs_should_be_register) {
1753 if (lhs_is_register and rhs_is_register) {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 } else if (lhs_is_register) {1797 } else if (lhs_is_register) {
1756 // Move RHS to register1798 // 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 rhs_mcv = dst_mcv;1800 rhs_mcv = dst_mcv;
1759 } else if (rhs_is_register) {1801 } else if (rhs_is_register) {
1760 // Move LHS to register1802 // 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 lhs_mcv = dst_mcv;1804 lhs_mcv = dst_mcv;
1763 } else {1805 } else {
1764 // Move LHS and RHS to register1806 // Move LHS and RHS to register
...@@ -1772,7 +1814,7 @@ fn genArmBinIntOp(...@@ -1772,7 +1814,7 @@ fn genArmBinIntOp(
1772 } else if (lhs_should_be_register) {1814 } else if (lhs_should_be_register) {
1773 // RHS is immediate1815 // RHS is immediate
1774 if (lhs_is_register) {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 } else {1818 } else {
1777 dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) };1819 dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) };
1778 lhs_mcv = dst_mcv;1820 lhs_mcv = dst_mcv;
...@@ -1780,7 +1822,7 @@ fn genArmBinIntOp(...@@ -1780,7 +1822,7 @@ fn genArmBinIntOp(
1780 } else if (rhs_should_be_register and can_swap_lhs_and_rhs) {1822 } else if (rhs_should_be_register and can_swap_lhs_and_rhs) {
1781 // LHS is immediate1823 // LHS is immediate
1782 if (rhs_is_register) {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 } else {1826 } else {
1785 dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) };1827 dst_mcv = MCValue{ .register = try self.register_manager.allocReg(inst, &.{}) };
1786 rhs_mcv = dst_mcv;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,6 +1968,11 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai
1926 const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op_lhs, 0, lhs);1968 const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op_lhs, 0, lhs);
1927 const reuse_rhs = !reuse_lhs and rhs_is_register and self.reuseOperand(inst, op_rhs, 1, rhs);1969 const reuse_rhs = !reuse_lhs and rhs_is_register and self.reuseOperand(inst, op_rhs, 1, rhs);
19281970
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 // Destination must be a register1976 // Destination must be a register
1930 // LHS must be a register1977 // LHS must be a register
1931 // RHS must be a register1978 // 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,28 +1985,28 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai
1938 if (reuse_lhs) {1985 if (reuse_lhs) {
1939 // Allocate 0 or 1 registers1986 // Allocate 0 or 1 registers
1940 if (!rhs_is_register) {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 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv);1989 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_rhs).?, rhs_mcv);
1943 }1990 }
1944 dst_mcv = lhs;1991 dst_mcv = lhs;
1945 } else if (reuse_rhs) {1992 } else if (reuse_rhs) {
1946 // Allocate 0 or 1 registers1993 // Allocate 0 or 1 registers
1947 if (!lhs_is_register) {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 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv);1996 branch.inst_table.putAssumeCapacity(Air.refToIndex(op_lhs).?, lhs_mcv);
1950 }1997 }
1951 dst_mcv = rhs;1998 dst_mcv = rhs;
1952 } else {1999 } else {
1953 // Allocate 1 or 2 registers2000 // Allocate 1 or 2 registers
1954 if (lhs_is_register and rhs_is_register) {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 } else if (lhs_is_register) {2003 } else if (lhs_is_register) {
1957 // Move RHS to register2004 // 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 rhs_mcv = dst_mcv;2006 rhs_mcv = dst_mcv;
1960 } else if (rhs_is_register) {2007 } else if (rhs_is_register) {
1961 // Move LHS to register2008 // 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 lhs_mcv = dst_mcv;2010 lhs_mcv = dst_mcv;
1964 } else {2011 } else {
1965 // Move LHS and RHS to register2012 // 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,29 +2039,32 @@ fn genArmMul(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Ai
1992}2039}
19932040
1994fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_index: Liveness.OperandInt, imm: u32) !MCValue {2041fn 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 const rhs = MCValue{ .immediate = imm };2043 const rhs = MCValue{ .immediate = imm };
19972044
1998 const lhs_is_register = mcv == .register;2045 const lhs_is_register = lhs == .register;
1999 const reuse_lhs = lhs_is_register and self.reuseOperand(inst, op, op_index, mcv);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});
20002050
2001 // Destination must be a register2051 // Destination must be a register
2002 // LHS must be a register2052 // LHS must be a register
2003 // RHS must be a register2053 // RHS must be a register
2004 var dst_mcv: MCValue = undefined;2054 var dst_mcv: MCValue = undefined;
2005 var lhs_mcv: MCValue = mcv;2055 var lhs_mcv: MCValue = lhs;
2006 var rhs_mcv: MCValue = rhs;2056 var rhs_mcv: MCValue = rhs;
20072057
2008 // Allocate registers for operands and/or destination2058 // Allocate registers for operands and/or destination
2009 if (reuse_lhs) {2059 if (reuse_lhs) {
2010 // Allocate 1 register2060 // Allocate 1 register
2011 rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{mcv.register}) };2061 rhs_mcv = MCValue{ .register = try self.register_manager.allocReg(null, &.{}) };
2012 dst_mcv = mcv;2062 dst_mcv = lhs;
2013 } else {2063 } else {
2014 // Allocate 1 or 2 registers2064 // Allocate 1 or 2 registers
2015 if (lhs_is_register) {2065 if (lhs_is_register) {
2016 // Move RHS to register2066 // 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 rhs_mcv = dst_mcv;2068 rhs_mcv = dst_mcv;
2019 } else {2069 } else {
2020 // Move LHS and RHS to register2070 // 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,7 +2077,7 @@ fn genArmMulConstant(self: *Self, inst: Air.Inst.Index, op: Air.Inst.Ref, op_ind
20272077
2028 // Move the operands to the newly allocated registers2078 // Move the operands to the newly allocated registers
2029 if (!lhs_is_register) {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 try self.genSetReg(Type.initTag(.usize), rhs_mcv.register, rhs);2082 try self.genSetReg(Type.initTag(.usize), rhs_mcv.register, rhs);
20332083
...@@ -2375,6 +2425,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -2375,6 +2425,11 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
2375 // lhs should always be a register2425 // lhs should always be a register
2376 const rhs_should_be_register = try self.armOperandShouldBeRegister(rhs);2426 const rhs_should_be_register = try self.armOperandShouldBeRegister(rhs);
23772427
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 var lhs_mcv = lhs;2433 var lhs_mcv = lhs;
2379 var rhs_mcv = rhs;2434 var rhs_mcv = rhs;
23802435