| ... | ... | @@ -795,7 +795,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 795 | 795 | // zig fmt: on |
| 796 | 796 | } |
| 797 | 797 | |
| 798 | | assert(!self.register_manager.frozenRegsExist()); |
| 798 | assert(!self.register_manager.lockedRegsExist()); |
| 799 | 799 | |
| 800 | 800 | if (std.debug.runtime_safety) { |
| 801 | 801 | if (self.air_bookkeeping < old_air_bookkeeping + 1) { |
| ... | ... | @@ -1028,10 +1028,10 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void { |
| 1028 | 1028 | } |
| 1029 | 1029 | |
| 1030 | 1030 | const operand_lock: ?RegisterLock = switch (operand) { |
| 1031 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1031 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1032 | 1032 | else => null, |
| 1033 | 1033 | }; |
| 1034 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1034 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 1035 | 1035 | |
| 1036 | 1036 | const reg = try self.register_manager.allocReg(inst); |
| 1037 | 1037 | try self.genSetReg(dest_ty, reg, .{ .immediate = 0 }); |
| ... | ... | @@ -1059,10 +1059,10 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 1059 | 1059 | } |
| 1060 | 1060 | |
| 1061 | 1061 | const operand_lock: ?RegisterLock = switch (operand) { |
| 1062 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1062 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1063 | 1063 | else => null, |
| 1064 | 1064 | }; |
| 1065 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1065 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 1066 | 1066 | |
| 1067 | 1067 | const reg: Register = blk: { |
| 1068 | 1068 | if (operand.isRegister()) { |
| ... | ... | @@ -1147,21 +1147,21 @@ fn airMin(self: *Self, inst: Air.Inst.Index) !void { |
| 1147 | 1147 | // TODO audit register allocation |
| 1148 | 1148 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1149 | 1149 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 1150 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1150 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1151 | 1151 | else => null, |
| 1152 | 1152 | }; |
| 1153 | | defer if (lhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1153 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1154 | 1154 | |
| 1155 | 1155 | const lhs_reg = try self.copyToTmpRegister(ty, lhs); |
| 1156 | | const lhs_reg_lock = self.register_manager.freezeRegAssumeUnused(lhs_reg); |
| 1157 | | defer self.register_manager.unfreezeReg(lhs_reg_lock); |
| 1156 | const lhs_reg_lock = self.register_manager.lockRegAssumeUnused(lhs_reg); |
| 1157 | defer self.register_manager.unlockReg(lhs_reg_lock); |
| 1158 | 1158 | |
| 1159 | 1159 | const rhs_mcv = try self.limitImmediateType(bin_op.rhs, i32); |
| 1160 | 1160 | const rhs_lock: ?RegisterLock = switch (rhs_mcv) { |
| 1161 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1161 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1162 | 1162 | else => null, |
| 1163 | 1163 | }; |
| 1164 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1164 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1165 | 1165 | |
| 1166 | 1166 | try self.genBinMathOpMir(.cmp, ty, .{ .register = lhs_reg }, rhs_mcv); |
| 1167 | 1167 | |
| ... | ... | @@ -1197,10 +1197,10 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1197 | 1197 | const offset_ty = self.air.typeOf(op_rhs); |
| 1198 | 1198 | |
| 1199 | 1199 | const offset_lock: ?RegisterLock = switch (offset) { |
| 1200 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1200 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1201 | 1201 | else => null, |
| 1202 | 1202 | }; |
| 1203 | | defer if (offset_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1203 | defer if (offset_lock) |reg| self.register_manager.unlockReg(reg); |
| 1204 | 1204 | |
| 1205 | 1205 | const dst_mcv = blk: { |
| 1206 | 1206 | if (self.reuseOperand(inst, op_lhs, 0, ptr)) { |
| ... | ... | @@ -1210,10 +1210,10 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1210 | 1210 | }; |
| 1211 | 1211 | |
| 1212 | 1212 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| 1213 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1213 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1214 | 1214 | else => null, |
| 1215 | 1215 | }; |
| 1216 | | defer if (dst_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1216 | defer if (dst_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 1217 | 1217 | |
| 1218 | 1218 | const offset_mcv = blk: { |
| 1219 | 1219 | if (self.reuseOperand(inst, op_rhs, 1, offset)) { |
| ... | ... | @@ -1223,10 +1223,10 @@ fn genPtrBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_r |
| 1223 | 1223 | }; |
| 1224 | 1224 | |
| 1225 | 1225 | const offset_mcv_lock: ?RegisterLock = switch (offset_mcv) { |
| 1226 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 1226 | .register => |reg| self.register_manager.lockReg(reg), |
| 1227 | 1227 | else => null, |
| 1228 | 1228 | }; |
| 1229 | | defer if (offset_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1229 | defer if (offset_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 1230 | 1230 | |
| 1231 | 1231 | try self.genIntMulComplexOpMir(offset_ty, offset_mcv, .{ .immediate = elem_size }); |
| 1232 | 1232 | |
| ... | ... | @@ -1312,17 +1312,17 @@ fn genSubOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air |
| 1312 | 1312 | |
| 1313 | 1313 | const lhs = try self.resolveInst(op_lhs); |
| 1314 | 1314 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 1315 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1315 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1316 | 1316 | else => null, |
| 1317 | 1317 | }; |
| 1318 | | defer if (lhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1318 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1319 | 1319 | |
| 1320 | 1320 | const rhs = try self.resolveInst(op_rhs); |
| 1321 | 1321 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 1322 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1322 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1323 | 1323 | else => null, |
| 1324 | 1324 | }; |
| 1325 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1325 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1326 | 1326 | |
| 1327 | 1327 | const dst_mcv = blk: { |
| 1328 | 1328 | if (self.reuseOperand(inst, op_lhs, 0, lhs) and lhs.isRegister()) { |
| ... | ... | @@ -1331,20 +1331,20 @@ fn genSubOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: Air |
| 1331 | 1331 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); |
| 1332 | 1332 | }; |
| 1333 | 1333 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| 1334 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 1334 | .register => |reg| self.register_manager.lockReg(reg), |
| 1335 | 1335 | else => null, |
| 1336 | 1336 | }; |
| 1337 | | defer if (dst_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1337 | defer if (dst_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 1338 | 1338 | |
| 1339 | 1339 | const rhs_mcv = blk: { |
| 1340 | 1340 | if (rhs.isMemory() or rhs.isRegister()) break :blk rhs; |
| 1341 | 1341 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, rhs) }; |
| 1342 | 1342 | }; |
| 1343 | 1343 | const rhs_mcv_lock: ?RegisterLock = switch (rhs_mcv) { |
| 1344 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 1344 | .register => |reg| self.register_manager.lockReg(reg), |
| 1345 | 1345 | else => null, |
| 1346 | 1346 | }; |
| 1347 | | defer if (rhs_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1347 | defer if (rhs_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 1348 | 1348 | |
| 1349 | 1349 | try self.genBinMathOpMir(.sub, dst_ty, dst_mcv, rhs_mcv); |
| 1350 | 1350 | |
| ... | ... | @@ -1382,9 +1382,9 @@ fn airMul(self: *Self, inst: Air.Inst.Index) !void { |
| 1382 | 1382 | try self.register_manager.getReg(.rax, inst); |
| 1383 | 1383 | try self.register_manager.getReg(.rdx, null); |
| 1384 | 1384 | var reg_locks: [2]RegisterLock = undefined; |
| 1385 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1385 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1386 | 1386 | defer for (reg_locks) |reg| { |
| 1387 | | self.register_manager.unfreezeReg(reg); |
| 1387 | self.register_manager.unlockReg(reg); |
| 1388 | 1388 | }; |
| 1389 | 1389 | |
| 1390 | 1390 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -1496,9 +1496,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1496 | 1496 | try self.register_manager.getReg(.rax, inst); |
| 1497 | 1497 | try self.register_manager.getReg(.rdx, null); |
| 1498 | 1498 | var reg_locks: [2]RegisterLock = undefined; |
| 1499 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1499 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1500 | 1500 | defer for (reg_locks) |reg| { |
| 1501 | | self.register_manager.unfreezeReg(reg); |
| 1501 | self.register_manager.unlockReg(reg); |
| 1502 | 1502 | }; |
| 1503 | 1503 | |
| 1504 | 1504 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -1526,27 +1526,27 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1526 | 1526 | const rhs = try self.resolveInst(bin_op.rhs); |
| 1527 | 1527 | |
| 1528 | 1528 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 1529 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1529 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1530 | 1530 | else => null, |
| 1531 | 1531 | }; |
| 1532 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1532 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1533 | 1533 | |
| 1534 | 1534 | const dst_reg: Register = blk: { |
| 1535 | 1535 | if (lhs.isRegister()) break :blk lhs.register; |
| 1536 | 1536 | break :blk try self.copyToTmpRegister(ty, lhs); |
| 1537 | 1537 | }; |
| 1538 | | const dst_reg_lock = self.register_manager.freezeRegAssumeUnused(dst_reg); |
| 1539 | | defer self.register_manager.unfreezeReg(dst_reg_lock); |
| 1538 | const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 1539 | defer self.register_manager.unlockReg(dst_reg_lock); |
| 1540 | 1540 | |
| 1541 | 1541 | const rhs_mcv = blk: { |
| 1542 | 1542 | if (rhs.isRegister() or rhs.isMemory()) break :blk rhs; |
| 1543 | 1543 | break :blk MCValue{ .register = try self.copyToTmpRegister(ty, rhs) }; |
| 1544 | 1544 | }; |
| 1545 | 1545 | const rhs_mcv_lock: ?RegisterLock = switch (rhs_mcv) { |
| 1546 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 1546 | .register => |reg| self.register_manager.lockReg(reg), |
| 1547 | 1547 | else => null, |
| 1548 | 1548 | }; |
| 1549 | | defer if (rhs_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1549 | defer if (rhs_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 1550 | 1550 | |
| 1551 | 1551 | try self.genIntMulComplexOpMir(Type.isize, .{ .register = dst_reg }, rhs_mcv); |
| 1552 | 1552 | |
| ... | ... | @@ -1557,9 +1557,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1557 | 1557 | try self.register_manager.getReg(.rax, null); |
| 1558 | 1558 | try self.register_manager.getReg(.rdx, null); |
| 1559 | 1559 | var reg_locks: [2]RegisterLock = undefined; |
| 1560 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1560 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1561 | 1561 | defer for (reg_locks) |reg| { |
| 1562 | | self.register_manager.unfreezeReg(reg); |
| 1562 | self.register_manager.unlockReg(reg); |
| 1563 | 1563 | }; |
| 1564 | 1564 | |
| 1565 | 1565 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -1571,8 +1571,8 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1571 | 1571 | }, |
| 1572 | 1572 | } |
| 1573 | 1573 | }; |
| 1574 | | const dst_reg_lock = self.register_manager.freezeRegAssumeUnused(dst_reg); |
| 1575 | | defer self.register_manager.unfreezeReg(dst_reg_lock); |
| 1574 | const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 1575 | defer self.register_manager.unlockReg(dst_reg_lock); |
| 1576 | 1576 | |
| 1577 | 1577 | const tuple_ty = self.air.typeOfIndex(inst); |
| 1578 | 1578 | const tuple_size = @intCast(u32, tuple_ty.abiSize(self.target.*)); |
| ... | ... | @@ -1587,9 +1587,9 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1587 | 1587 | |
| 1588 | 1588 | const temp_regs = try self.register_manager.allocRegs(3, .{ null, null, null }); |
| 1589 | 1589 | var temp_regs_locks: [3]RegisterLock = undefined; |
| 1590 | | self.register_manager.freezeRegsAssumeUnused(3, temp_regs, &temp_regs_locks); |
| 1590 | self.register_manager.lockRegsAssumeUnused(3, temp_regs, &temp_regs_locks); |
| 1591 | 1591 | defer for (temp_regs_locks) |reg| { |
| 1592 | | self.register_manager.unfreezeReg(reg); |
| 1592 | self.register_manager.unlockReg(reg); |
| 1593 | 1593 | }; |
| 1594 | 1594 | |
| 1595 | 1595 | const overflow_reg = temp_regs[0]; |
| ... | ... | @@ -1738,15 +1738,15 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa |
| 1738 | 1738 | .register => |reg| reg, |
| 1739 | 1739 | else => try self.copyToTmpRegister(ty, lhs), |
| 1740 | 1740 | }; |
| 1741 | | const dividend_lock = self.register_manager.freezeReg(dividend); |
| 1742 | | defer if (dividend_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1741 | const dividend_lock = self.register_manager.lockReg(dividend); |
| 1742 | defer if (dividend_lock) |reg| self.register_manager.unlockReg(reg); |
| 1743 | 1743 | |
| 1744 | 1744 | const divisor = switch (rhs) { |
| 1745 | 1745 | .register => |reg| reg, |
| 1746 | 1746 | else => try self.copyToTmpRegister(ty, rhs), |
| 1747 | 1747 | }; |
| 1748 | | const divisor_lock = self.register_manager.freezeReg(divisor); |
| 1749 | | defer if (divisor_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1748 | const divisor_lock = self.register_manager.lockReg(divisor); |
| 1749 | defer if (divisor_lock) |reg| self.register_manager.unlockReg(reg); |
| 1750 | 1750 | |
| 1751 | 1751 | try self.genIntMulDivOpMir(switch (signedness) { |
| 1752 | 1752 | .signed => .idiv, |
| ... | ... | @@ -1816,17 +1816,17 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void { |
| 1816 | 1816 | try self.register_manager.getReg(.rax, track_rax); |
| 1817 | 1817 | try self.register_manager.getReg(.rdx, null); |
| 1818 | 1818 | var reg_locks: [2]RegisterLock = undefined; |
| 1819 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1819 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1820 | 1820 | defer for (reg_locks) |reg| { |
| 1821 | | self.register_manager.unfreezeReg(reg); |
| 1821 | self.register_manager.unlockReg(reg); |
| 1822 | 1822 | }; |
| 1823 | 1823 | |
| 1824 | 1824 | const lhs = try self.resolveInst(bin_op.lhs); |
| 1825 | 1825 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 1826 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1826 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1827 | 1827 | else => null, |
| 1828 | 1828 | }; |
| 1829 | | defer if (lhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1829 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1830 | 1830 | |
| 1831 | 1831 | const rhs = blk: { |
| 1832 | 1832 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | ... | @@ -1834,10 +1834,10 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void { |
| 1834 | 1834 | switch (tag) { |
| 1835 | 1835 | .div_floor => { |
| 1836 | 1836 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 1837 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 1837 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 1838 | 1838 | else => null, |
| 1839 | 1839 | }; |
| 1840 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1840 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1841 | 1841 | |
| 1842 | 1842 | break :blk try self.copyToRegisterWithInstTracking(inst, ty, rhs); |
| 1843 | 1843 | }, |
| ... | ... | @@ -1847,10 +1847,10 @@ fn airDiv(self: *Self, inst: Air.Inst.Index) !void { |
| 1847 | 1847 | break :blk rhs; |
| 1848 | 1848 | }; |
| 1849 | 1849 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 1850 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 1850 | .register => |reg| self.register_manager.lockReg(reg), |
| 1851 | 1851 | else => null, |
| 1852 | 1852 | }; |
| 1853 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 1853 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 1854 | 1854 | |
| 1855 | 1855 | if (signedness == .unsigned) { |
| 1856 | 1856 | try self.genIntMulDivOpMir(.div, ty, signedness, lhs, rhs); |
| ... | ... | @@ -1885,9 +1885,9 @@ fn airRem(self: *Self, inst: Air.Inst.Index) !void { |
| 1885 | 1885 | try self.register_manager.getReg(.rax, null); |
| 1886 | 1886 | try self.register_manager.getReg(.rdx, inst); |
| 1887 | 1887 | var reg_locks: [2]RegisterLock = undefined; |
| 1888 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1888 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1889 | 1889 | defer for (reg_locks) |reg| { |
| 1890 | | self.register_manager.unfreezeReg(reg); |
| 1890 | self.register_manager.unlockReg(reg); |
| 1891 | 1891 | }; |
| 1892 | 1892 | |
| 1893 | 1893 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -1916,9 +1916,9 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 1916 | 1916 | try self.register_manager.getReg(.rax, null); |
| 1917 | 1917 | try self.register_manager.getReg(.rdx, if (signedness == .unsigned) inst else null); |
| 1918 | 1918 | var reg_locks: [2]RegisterLock = undefined; |
| 1919 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1919 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }, &reg_locks); |
| 1920 | 1920 | defer for (reg_locks) |reg| { |
| 1921 | | self.register_manager.unfreezeReg(reg); |
| 1921 | self.register_manager.unlockReg(reg); |
| 1922 | 1922 | }; |
| 1923 | 1923 | |
| 1924 | 1924 | const lhs = try self.resolveInst(bin_op.lhs); |
| ... | ... | @@ -2009,15 +2009,15 @@ fn airShl(self: *Self, inst: Air.Inst.Index) !void { |
| 2009 | 2009 | try self.register_manager.getReg(.rcx, null); |
| 2010 | 2010 | try self.genSetReg(shift_ty, .rcx, shift); |
| 2011 | 2011 | } |
| 2012 | | const rcx_lock = self.register_manager.freezeRegAssumeUnused(.rcx); |
| 2013 | | defer self.register_manager.unfreezeReg(rcx_lock); |
| 2012 | const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx); |
| 2013 | defer self.register_manager.unlockReg(rcx_lock); |
| 2014 | 2014 | |
| 2015 | 2015 | const value = try self.resolveInst(bin_op.lhs); |
| 2016 | 2016 | const value_lock: ?RegisterLock = switch (value) { |
| 2017 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2017 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2018 | 2018 | else => null, |
| 2019 | 2019 | }; |
| 2020 | | defer if (value_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2020 | defer if (value_lock) |reg| self.register_manager.unlockReg(reg); |
| 2021 | 2021 | |
| 2022 | 2022 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, value); |
| 2023 | 2023 | _ = try self.addInst(.{ |
| ... | ... | @@ -2114,10 +2114,10 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void { |
| 2114 | 2114 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 2115 | 2115 | const operand = try self.resolveInst(ty_op.operand); |
| 2116 | 2116 | const operand_lock: ?RegisterLock = switch (operand) { |
| 2117 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2117 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2118 | 2118 | else => null, |
| 2119 | 2119 | }; |
| 2120 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2120 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 2121 | 2121 | |
| 2122 | 2122 | const result: MCValue = result: { |
| 2123 | 2123 | if (!payload_ty.hasRuntimeBits()) break :result operand; |
| ... | ... | @@ -2147,10 +2147,10 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 2147 | 2147 | |
| 2148 | 2148 | const operand = try self.resolveInst(ty_op.operand); |
| 2149 | 2149 | const operand_lock: ?RegisterLock = switch (operand) { |
| 2150 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2150 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2151 | 2151 | else => null, |
| 2152 | 2152 | }; |
| 2153 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2153 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 2154 | 2154 | |
| 2155 | 2155 | const abi_align = err_union_ty.abiAlignment(self.target.*); |
| 2156 | 2156 | const err_ty = err_union_ty.errorUnionSet(); |
| ... | ... | @@ -2219,10 +2219,10 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 2219 | 2219 | const optional_ty = self.air.typeOfIndex(inst); |
| 2220 | 2220 | const operand = try self.resolveInst(ty_op.operand); |
| 2221 | 2221 | const operand_lock: ?RegisterLock = switch (operand) { |
| 2222 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2222 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2223 | 2223 | else => null, |
| 2224 | 2224 | }; |
| 2225 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2225 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 2226 | 2226 | |
| 2227 | 2227 | if (optional_ty.isPtrLikeOptional()) { |
| 2228 | 2228 | // TODO should we check if we can reuse the operand? |
| ... | ... | @@ -2356,10 +2356,10 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 2356 | 2356 | const slice_ty = self.air.typeOf(lhs); |
| 2357 | 2357 | const slice_mcv = try self.resolveInst(lhs); |
| 2358 | 2358 | const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) { |
| 2359 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2359 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2360 | 2360 | else => null, |
| 2361 | 2361 | }; |
| 2362 | | defer if (slice_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2362 | defer if (slice_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 2363 | 2363 | |
| 2364 | 2364 | const elem_ty = slice_ty.childType(); |
| 2365 | 2365 | const elem_size = elem_ty.abiSize(self.target.*); |
| ... | ... | @@ -2369,14 +2369,14 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 2369 | 2369 | const index_ty = self.air.typeOf(rhs); |
| 2370 | 2370 | const index_mcv = try self.resolveInst(rhs); |
| 2371 | 2371 | const index_mcv_lock: ?RegisterLock = switch (index_mcv) { |
| 2372 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2372 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2373 | 2373 | else => null, |
| 2374 | 2374 | }; |
| 2375 | | defer if (index_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2375 | defer if (index_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 2376 | 2376 | |
| 2377 | 2377 | const offset_reg = try self.elemOffset(index_ty, index_mcv, elem_size); |
| 2378 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 2379 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 2378 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 2379 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 2380 | 2380 | |
| 2381 | 2381 | const addr_reg = try self.register_manager.allocReg(null); |
| 2382 | 2382 | switch (slice_mcv) { |
| ... | ... | @@ -2433,10 +2433,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2433 | 2433 | const array_ty = self.air.typeOf(bin_op.lhs); |
| 2434 | 2434 | const array = try self.resolveInst(bin_op.lhs); |
| 2435 | 2435 | const array_lock: ?RegisterLock = switch (array) { |
| 2436 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2436 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2437 | 2437 | else => null, |
| 2438 | 2438 | }; |
| 2439 | | defer if (array_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2439 | defer if (array_lock) |reg| self.register_manager.unlockReg(reg); |
| 2440 | 2440 | |
| 2441 | 2441 | const elem_ty = array_ty.childType(); |
| 2442 | 2442 | const elem_abi_size = elem_ty.abiSize(self.target.*); |
| ... | ... | @@ -2444,14 +2444,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2444 | 2444 | const index_ty = self.air.typeOf(bin_op.rhs); |
| 2445 | 2445 | const index = try self.resolveInst(bin_op.rhs); |
| 2446 | 2446 | const index_lock: ?RegisterLock = switch (index) { |
| 2447 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2447 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2448 | 2448 | else => null, |
| 2449 | 2449 | }; |
| 2450 | | defer if (index_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2450 | defer if (index_lock) |reg| self.register_manager.unlockReg(reg); |
| 2451 | 2451 | |
| 2452 | 2452 | const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); |
| 2453 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 2454 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 2453 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 2454 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 2455 | 2455 | |
| 2456 | 2456 | const addr_reg = try self.register_manager.allocReg(null); |
| 2457 | 2457 | switch (array) { |
| ... | ... | @@ -2512,24 +2512,24 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2512 | 2512 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 2513 | 2513 | const ptr = try self.resolveInst(bin_op.lhs); |
| 2514 | 2514 | const ptr_lock: ?RegisterLock = switch (ptr) { |
| 2515 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2515 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2516 | 2516 | else => null, |
| 2517 | 2517 | }; |
| 2518 | | defer if (ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2518 | defer if (ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 2519 | 2519 | |
| 2520 | 2520 | const elem_ty = ptr_ty.elemType2(); |
| 2521 | 2521 | const elem_abi_size = elem_ty.abiSize(self.target.*); |
| 2522 | 2522 | const index_ty = self.air.typeOf(bin_op.rhs); |
| 2523 | 2523 | const index = try self.resolveInst(bin_op.rhs); |
| 2524 | 2524 | const index_lock: ?RegisterLock = switch (index) { |
| 2525 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2525 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2526 | 2526 | else => null, |
| 2527 | 2527 | }; |
| 2528 | | defer if (index_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2528 | defer if (index_lock) |reg| self.register_manager.unlockReg(reg); |
| 2529 | 2529 | |
| 2530 | 2530 | const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); |
| 2531 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 2532 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 2531 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 2532 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 2533 | 2533 | |
| 2534 | 2534 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); |
| 2535 | 2535 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| ... | ... | @@ -2559,24 +2559,24 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2559 | 2559 | const ptr_ty = self.air.typeOf(extra.lhs); |
| 2560 | 2560 | const ptr = try self.resolveInst(extra.lhs); |
| 2561 | 2561 | const ptr_lock: ?RegisterLock = switch (ptr) { |
| 2562 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2562 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2563 | 2563 | else => null, |
| 2564 | 2564 | }; |
| 2565 | | defer if (ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2565 | defer if (ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 2566 | 2566 | |
| 2567 | 2567 | const elem_ty = ptr_ty.elemType2(); |
| 2568 | 2568 | const elem_abi_size = elem_ty.abiSize(self.target.*); |
| 2569 | 2569 | const index_ty = self.air.typeOf(extra.rhs); |
| 2570 | 2570 | const index = try self.resolveInst(extra.rhs); |
| 2571 | 2571 | const index_lock: ?RegisterLock = switch (index) { |
| 2572 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2572 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2573 | 2573 | else => null, |
| 2574 | 2574 | }; |
| 2575 | | defer if (index_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2575 | defer if (index_lock) |reg| self.register_manager.unlockReg(reg); |
| 2576 | 2576 | |
| 2577 | 2577 | const offset_reg = try self.elemOffset(index_ty, index, elem_abi_size); |
| 2578 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 2579 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 2578 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 2579 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 2580 | 2580 | |
| 2581 | 2581 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, ptr); |
| 2582 | 2582 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| ... | ... | @@ -2598,17 +2598,17 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 2598 | 2598 | |
| 2599 | 2599 | const ptr = try self.resolveInst(bin_op.lhs); |
| 2600 | 2600 | const ptr_lock: ?RegisterLock = switch (ptr) { |
| 2601 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2601 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2602 | 2602 | else => null, |
| 2603 | 2603 | }; |
| 2604 | | defer if (ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2604 | defer if (ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 2605 | 2605 | |
| 2606 | 2606 | const tag = try self.resolveInst(bin_op.rhs); |
| 2607 | 2607 | const tag_lock: ?RegisterLock = switch (tag) { |
| 2608 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2608 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2609 | 2609 | else => null, |
| 2610 | 2610 | }; |
| 2611 | | defer if (tag_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2611 | defer if (tag_lock) |reg| self.register_manager.unlockReg(reg); |
| 2612 | 2612 | |
| 2613 | 2613 | const adjusted_ptr: MCValue = if (layout.payload_size > 0 and layout.tag_align < layout.payload_align) blk: { |
| 2614 | 2614 | // TODO reusing the operand |
| ... | ... | @@ -2639,10 +2639,10 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 2639 | 2639 | // TODO reusing the operand |
| 2640 | 2640 | const operand = try self.resolveInst(ty_op.operand); |
| 2641 | 2641 | const operand_lock: ?RegisterLock = switch (operand) { |
| 2642 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 2642 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 2643 | 2643 | else => null, |
| 2644 | 2644 | }; |
| 2645 | | defer if (operand_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 2645 | defer if (operand_lock) |reg| self.register_manager.unlockReg(reg); |
| 2646 | 2646 | |
| 2647 | 2647 | const tag_abi_size = tag_ty.abiSize(self.target.*); |
| 2648 | 2648 | const dst_mcv: MCValue = blk: { |
| ... | ... | @@ -2789,8 +2789,8 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2789 | 2789 | try self.setRegOrMem(elem_ty, dst_mcv, .{ .stack_offset = off }); |
| 2790 | 2790 | }, |
| 2791 | 2791 | .register => |reg| { |
| 2792 | | const reg_lock = self.register_manager.freezeReg(reg); |
| 2793 | | defer if (reg_lock) |locked_reg| self.register_manager.unfreezeReg(locked_reg); |
| 2792 | const reg_lock = self.register_manager.lockReg(reg); |
| 2793 | defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg); |
| 2794 | 2794 | |
| 2795 | 2795 | switch (dst_mcv) { |
| 2796 | 2796 | .dead => unreachable, |
| ... | ... | @@ -2915,8 +2915,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 2915 | 2915 | try self.genSetStack(value_ty, off, value, .{}); |
| 2916 | 2916 | }, |
| 2917 | 2917 | .register => |reg| { |
| 2918 | | const reg_lock = self.register_manager.freezeReg(reg); |
| 2919 | | defer if (reg_lock) |locked_reg| self.register_manager.unfreezeReg(locked_reg); |
| 2918 | const reg_lock = self.register_manager.lockReg(reg); |
| 2919 | defer if (reg_lock) |locked_reg| self.register_manager.unlockReg(locked_reg); |
| 2920 | 2920 | |
| 2921 | 2921 | switch (value) { |
| 2922 | 2922 | .none => unreachable, |
| ... | ... | @@ -3007,14 +3007,14 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3007 | 3007 | .memory, |
| 3008 | 3008 | => { |
| 3009 | 3009 | const value_lock: ?RegisterLock = switch (value) { |
| 3010 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 3010 | .register => |reg| self.register_manager.lockReg(reg), |
| 3011 | 3011 | else => null, |
| 3012 | 3012 | }; |
| 3013 | | defer if (value_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3013 | defer if (value_lock) |reg| self.register_manager.unlockReg(reg); |
| 3014 | 3014 | |
| 3015 | 3015 | const addr_reg = try self.register_manager.allocReg(null); |
| 3016 | | const addr_reg_lock = self.register_manager.freezeRegAssumeUnused(addr_reg); |
| 3017 | | defer self.register_manager.unfreezeReg(addr_reg_lock); |
| 3016 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 3017 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 3018 | 3018 | |
| 3019 | 3019 | try self.loadMemPtrIntoRegister(addr_reg, ptr_ty, ptr); |
| 3020 | 3020 | |
| ... | ... | @@ -3085,8 +3085,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3085 | 3085 | => { |
| 3086 | 3086 | if (abi_size <= 8) { |
| 3087 | 3087 | const tmp_reg = try self.register_manager.allocReg(null); |
| 3088 | | const tmp_reg_lock = self.register_manager.freezeRegAssumeUnused(tmp_reg); |
| 3089 | | defer self.register_manager.unfreezeReg(tmp_reg_lock); |
| 3088 | const tmp_reg_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 3089 | defer self.register_manager.unlockReg(tmp_reg_lock); |
| 3090 | 3090 | |
| 3091 | 3091 | try self.loadMemPtrIntoRegister(tmp_reg, value_ty, value); |
| 3092 | 3092 | |
| ... | ... | @@ -3176,8 +3176,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 3176 | 3176 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 3177 | 3177 | .immediate = struct_field_offset, |
| 3178 | 3178 | }); |
| 3179 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 3180 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 3179 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 3180 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 3181 | 3181 | |
| 3182 | 3182 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ptr_ty, mcv); |
| 3183 | 3183 | try self.genBinMathOpMir(.add, ptr_ty, dst_mcv, .{ .register = offset_reg }); |
| ... | ... | @@ -3188,14 +3188,14 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 3188 | 3188 | break :result MCValue{ .ptr_stack_offset = ptr_stack_offset }; |
| 3189 | 3189 | }, |
| 3190 | 3190 | .register => |reg| { |
| 3191 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 3192 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 3191 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 3192 | defer self.register_manager.unlockReg(reg_lock); |
| 3193 | 3193 | |
| 3194 | 3194 | const offset_reg = try self.copyToTmpRegister(ptr_ty, .{ |
| 3195 | 3195 | .immediate = struct_field_offset, |
| 3196 | 3196 | }); |
| 3197 | | const offset_reg_lock = self.register_manager.freezeRegAssumeUnused(offset_reg); |
| 3198 | | defer self.register_manager.unfreezeReg(offset_reg_lock); |
| 3197 | const offset_reg_lock = self.register_manager.lockRegAssumeUnused(offset_reg); |
| 3198 | defer self.register_manager.unlockReg(offset_reg_lock); |
| 3199 | 3199 | |
| 3200 | 3200 | const can_reuse_operand = self.reuseOperand(inst, operand, 0, mcv); |
| 3201 | 3201 | const result_reg = blk: { |
| ... | ... | @@ -3207,8 +3207,8 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde |
| 3207 | 3207 | break :blk result_reg; |
| 3208 | 3208 | } |
| 3209 | 3209 | }; |
| 3210 | | const result_reg_lock = self.register_manager.freezeReg(result_reg); |
| 3211 | | defer if (result_reg_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 3210 | const result_reg_lock = self.register_manager.lockReg(result_reg); |
| 3211 | defer if (result_reg_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 3212 | 3212 | |
| 3213 | 3213 | try self.genBinMathOpMir(.add, ptr_ty, .{ .register = result_reg }, .{ .register = offset_reg }); |
| 3214 | 3214 | break :result MCValue{ .register = result_reg }; |
| ... | ... | @@ -3236,8 +3236,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3236 | 3236 | break :result MCValue{ .stack_offset = stack_offset }; |
| 3237 | 3237 | }, |
| 3238 | 3238 | .register => |reg| { |
| 3239 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 3240 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 3239 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 3240 | defer self.register_manager.unlockReg(reg_lock); |
| 3241 | 3241 | |
| 3242 | 3242 | const dst_mcv = blk: { |
| 3243 | 3243 | if (self.reuseOperand(inst, operand, 0, mcv)) { |
| ... | ... | @@ -3250,10 +3250,10 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3250 | 3250 | } |
| 3251 | 3251 | }; |
| 3252 | 3252 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| 3253 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 3253 | .register => |reg| self.register_manager.lockReg(reg), |
| 3254 | 3254 | else => null, |
| 3255 | 3255 | }; |
| 3256 | | defer if (dst_mcv_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 3256 | defer if (dst_mcv_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 3257 | 3257 | |
| 3258 | 3258 | // Shift by struct_field_offset. |
| 3259 | 3259 | const shift = @intCast(u8, struct_field_offset * @sizeOf(usize)); |
| ... | ... | @@ -3295,8 +3295,8 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3295 | 3295 | }, |
| 3296 | 3296 | 1 => { |
| 3297 | 3297 | // Get overflow bit. |
| 3298 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 3299 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 3298 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 3299 | defer self.register_manager.unlockReg(reg_lock); |
| 3300 | 3300 | |
| 3301 | 3301 | const dst_reg = try self.register_manager.allocReg(inst); |
| 3302 | 3302 | const flags: u2 = switch (mcv) { |
| ... | ... | @@ -3339,17 +3339,17 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 3339 | 3339 | |
| 3340 | 3340 | const lhs = try self.resolveInst(op_lhs); |
| 3341 | 3341 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 3342 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 3342 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 3343 | 3343 | else => null, |
| 3344 | 3344 | }; |
| 3345 | | defer if (lhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3345 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 3346 | 3346 | |
| 3347 | 3347 | const rhs = try self.resolveInst(op_rhs); |
| 3348 | 3348 | const rhs_lock: ?RegisterLock = switch (rhs) { |
| 3349 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 3349 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 3350 | 3350 | else => null, |
| 3351 | 3351 | }; |
| 3352 | | defer if (rhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3352 | defer if (rhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 3353 | 3353 | |
| 3354 | 3354 | var flipped: bool = false; |
| 3355 | 3355 | const dst_mcv = blk: { |
| ... | ... | @@ -3363,10 +3363,10 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 3363 | 3363 | break :blk try self.copyToRegisterWithInstTracking(inst, dst_ty, lhs); |
| 3364 | 3364 | }; |
| 3365 | 3365 | const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) { |
| 3366 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 3366 | .register => |reg| self.register_manager.lockReg(reg), |
| 3367 | 3367 | else => null, |
| 3368 | 3368 | }; |
| 3369 | | defer if (dst_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3369 | defer if (dst_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 3370 | 3370 | |
| 3371 | 3371 | const src_mcv = blk: { |
| 3372 | 3372 | const mcv = if (flipped) lhs else rhs; |
| ... | ... | @@ -3374,10 +3374,10 @@ fn genBinMathOp(self: *Self, inst: Air.Inst.Index, op_lhs: Air.Inst.Ref, op_rhs: |
| 3374 | 3374 | break :blk MCValue{ .register = try self.copyToTmpRegister(dst_ty, mcv) }; |
| 3375 | 3375 | }; |
| 3376 | 3376 | const src_mcv_lock: ?RegisterLock = switch (src_mcv) { |
| 3377 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 3377 | .register => |reg| self.register_manager.lockReg(reg), |
| 3378 | 3378 | else => null, |
| 3379 | 3379 | }; |
| 3380 | | defer if (src_mcv_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3380 | defer if (src_mcv_lock) |reg| self.register_manager.unlockReg(reg); |
| 3381 | 3381 | |
| 3382 | 3382 | const tag = self.air.instructions.items(.tag)[inst]; |
| 3383 | 3383 | switch (tag) { |
| ... | ... | @@ -3408,8 +3408,8 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3408 | 3408 | .register_overflow_unsigned => unreachable, |
| 3409 | 3409 | .register_overflow_signed => unreachable, |
| 3410 | 3410 | .ptr_stack_offset => { |
| 3411 | | const dst_reg_lock = self.register_manager.freezeReg(dst_reg); |
| 3412 | | defer if (dst_reg_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 3411 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 3412 | defer if (dst_reg_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 3413 | 3413 | |
| 3414 | 3414 | const reg = try self.copyToTmpRegister(dst_ty, src_mcv); |
| 3415 | 3415 | return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); |
| ... | ... | @@ -3440,8 +3440,8 @@ fn genBinMathOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MC |
| 3440 | 3440 | .compare_flags_unsigned, |
| 3441 | 3441 | => { |
| 3442 | 3442 | assert(abi_size <= 8); |
| 3443 | | const dst_reg_lock = self.register_manager.freezeReg(dst_reg); |
| 3444 | | defer if (dst_reg_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 3443 | const dst_reg_lock = self.register_manager.lockReg(dst_reg); |
| 3444 | defer if (dst_reg_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 3445 | 3445 | |
| 3446 | 3446 | const reg = try self.copyToTmpRegister(dst_ty, src_mcv); |
| 3447 | 3447 | return self.genBinMathOpMir(mir_tag, dst_ty, dst_mcv, .{ .register = reg }); |
| ... | ... | @@ -3791,13 +3791,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3791 | 3791 | |
| 3792 | 3792 | try self.register_manager.getReg(.rdi, null); |
| 3793 | 3793 | try self.genSetReg(Type.usize, .rdi, .{ .ptr_stack_offset = stack_offset }); |
| 3794 | | const rdi_lock = self.register_manager.freezeRegAssumeUnused(.rdi); |
| 3794 | const rdi_lock = self.register_manager.lockRegAssumeUnused(.rdi); |
| 3795 | 3795 | |
| 3796 | 3796 | info.return_value.stack_offset = stack_offset; |
| 3797 | 3797 | |
| 3798 | 3798 | break :blk rdi_lock; |
| 3799 | 3799 | } else null; |
| 3800 | | defer if (rdi_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 3800 | defer if (rdi_lock) |reg| self.register_manager.unlockReg(reg); |
| 3801 | 3801 | |
| 3802 | 3802 | for (args) |arg, arg_i| { |
| 3803 | 3803 | const mc_arg = info.args[arg_i]; |
| ... | ... | @@ -4017,8 +4017,8 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4017 | 4017 | switch (self.ret_mcv) { |
| 4018 | 4018 | .stack_offset => { |
| 4019 | 4019 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4020 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4021 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 4020 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 4021 | defer self.register_manager.unlockReg(reg_lock); |
| 4022 | 4022 | |
| 4023 | 4023 | try self.genSetStack(ret_ty, 0, operand, .{ |
| 4024 | 4024 | .source_stack_base = .rbp, |
| ... | ... | @@ -4051,8 +4051,8 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4051 | 4051 | switch (self.ret_mcv) { |
| 4052 | 4052 | .stack_offset => { |
| 4053 | 4053 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4054 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4055 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 4054 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 4055 | defer self.register_manager.unlockReg(reg_lock); |
| 4056 | 4056 | |
| 4057 | 4057 | try self.genInlineMemcpy(.{ .stack_offset = 0 }, ptr, .{ .immediate = elem_ty.abiSize(self.target.*) }, .{ |
| 4058 | 4058 | .source_stack_base = .rbp, |
| ... | ... | @@ -4104,14 +4104,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 4104 | 4104 | // TODO look into reusing the operand |
| 4105 | 4105 | const lhs = try self.resolveInst(bin_op.lhs); |
| 4106 | 4106 | const lhs_lock: ?RegisterLock = switch (lhs) { |
| 4107 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 4107 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 4108 | 4108 | else => null, |
| 4109 | 4109 | }; |
| 4110 | | defer if (lhs_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4110 | defer if (lhs_lock) |reg| self.register_manager.unlockReg(reg); |
| 4111 | 4111 | |
| 4112 | 4112 | const dst_reg = try self.copyToTmpRegister(ty, lhs); |
| 4113 | | const dst_reg_lock = self.register_manager.freezeRegAssumeUnused(dst_reg); |
| 4114 | | defer self.register_manager.unfreezeReg(dst_reg_lock); |
| 4113 | const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg); |
| 4114 | defer self.register_manager.unlockReg(dst_reg_lock); |
| 4115 | 4115 | |
| 4116 | 4116 | const dst_mcv = MCValue{ .register = dst_reg }; |
| 4117 | 4117 | |
| ... | ... | @@ -4576,10 +4576,10 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4576 | 4576 | const operand_ptr = try self.resolveInst(un_op); |
| 4577 | 4577 | |
| 4578 | 4578 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { |
| 4579 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 4579 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 4580 | 4580 | else => null, |
| 4581 | 4581 | }; |
| 4582 | | defer if (operand_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4582 | defer if (operand_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 4583 | 4583 | |
| 4584 | 4584 | const operand: MCValue = blk: { |
| 4585 | 4585 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { |
| ... | ... | @@ -4612,10 +4612,10 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4612 | 4612 | const operand_ptr = try self.resolveInst(un_op); |
| 4613 | 4613 | |
| 4614 | 4614 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { |
| 4615 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 4615 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 4616 | 4616 | else => null, |
| 4617 | 4617 | }; |
| 4618 | | defer if (operand_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4618 | defer if (operand_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 4619 | 4619 | |
| 4620 | 4620 | const operand: MCValue = blk: { |
| 4621 | 4621 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { |
| ... | ... | @@ -4648,10 +4648,10 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4648 | 4648 | const operand_ptr = try self.resolveInst(un_op); |
| 4649 | 4649 | |
| 4650 | 4650 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { |
| 4651 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 4651 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 4652 | 4652 | else => null, |
| 4653 | 4653 | }; |
| 4654 | | defer if (operand_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4654 | defer if (operand_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 4655 | 4655 | |
| 4656 | 4656 | const operand: MCValue = blk: { |
| 4657 | 4657 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { |
| ... | ... | @@ -4684,10 +4684,10 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 4684 | 4684 | const operand_ptr = try self.resolveInst(un_op); |
| 4685 | 4685 | |
| 4686 | 4686 | const operand_ptr_lock: ?RegisterLock = switch (operand_ptr) { |
| 4687 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 4687 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 4688 | 4688 | else => null, |
| 4689 | 4689 | }; |
| 4690 | | defer if (operand_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4690 | defer if (operand_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 4691 | 4691 | |
| 4692 | 4692 | const operand: MCValue = blk: { |
| 4693 | 4693 | if (self.reuseOperand(inst, un_op, 0, operand_ptr)) { |
| ... | ... | @@ -4756,8 +4756,8 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4756 | 4756 | .register => |cond_reg| { |
| 4757 | 4757 | try self.spillCompareFlagsIfOccupied(); |
| 4758 | 4758 | |
| 4759 | | const cond_reg_lock = self.register_manager.freezeReg(cond_reg); |
| 4760 | | defer if (cond_reg_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 4759 | const cond_reg_lock = self.register_manager.lockReg(cond_reg); |
| 4760 | defer if (cond_reg_lock) |reg| self.register_manager.unlockReg(reg); |
| 4761 | 4761 | |
| 4762 | 4762 | switch (case) { |
| 4763 | 4763 | .none => unreachable, |
| ... | ... | @@ -4816,8 +4816,8 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u |
| 4816 | 4816 | |
| 4817 | 4817 | if (abi_size <= 8) { |
| 4818 | 4818 | const reg = try self.copyToTmpRegister(ty, condition); |
| 4819 | | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4820 | | defer self.register_manager.unfreezeReg(reg_lock); |
| 4819 | const reg_lock = self.register_manager.lockRegAssumeUnused(reg); |
| 4820 | defer self.register_manager.unlockReg(reg_lock); |
| 4821 | 4821 | return self.genCondSwitchMir(ty, .{ .register = reg }, case); |
| 4822 | 4822 | } |
| 4823 | 4823 | |
| ... | ... | @@ -5304,8 +5304,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5304 | 5304 | .register_overflow_unsigned, |
| 5305 | 5305 | .register_overflow_signed, |
| 5306 | 5306 | => |reg| { |
| 5307 | | const reg_lock = self.register_manager.freezeReg(reg); |
| 5308 | | defer if (reg_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 5307 | const reg_lock = self.register_manager.lockReg(reg); |
| 5308 | defer if (reg_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 5309 | 5309 | |
| 5310 | 5310 | const wrapped_ty = ty.structFieldType(0); |
| 5311 | 5311 | try self.genSetStack(wrapped_ty, stack_offset, .{ .register = reg }, .{}); |
| ... | ... | @@ -5406,8 +5406,8 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl |
| 5406 | 5406 | |
| 5407 | 5407 | const base_reg = opts.dest_stack_base orelse .rbp; |
| 5408 | 5408 | if (!math.isPowerOfTwo(abi_size)) { |
| 5409 | | const reg_lock = self.register_manager.freezeReg(reg); |
| 5410 | | defer if (reg_lock) |reg_locked| self.register_manager.unfreezeReg(reg_locked); |
| 5409 | const reg_lock = self.register_manager.lockReg(reg); |
| 5410 | defer if (reg_lock) |reg_locked| self.register_manager.unlockReg(reg_locked); |
| 5411 | 5411 | |
| 5412 | 5412 | const tmp_reg = try self.copyToTmpRegister(ty, mcv); |
| 5413 | 5413 | |
| ... | ... | @@ -5500,22 +5500,22 @@ fn genInlineMemcpy( |
| 5500 | 5500 | try self.register_manager.getReg(.rcx, null); |
| 5501 | 5501 | |
| 5502 | 5502 | var reg_locks: [2]RegisterLock = undefined; |
| 5503 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks); |
| 5503 | self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks); |
| 5504 | 5504 | defer for (reg_locks) |reg| { |
| 5505 | | self.register_manager.unfreezeReg(reg); |
| 5505 | self.register_manager.unlockReg(reg); |
| 5506 | 5506 | }; |
| 5507 | 5507 | |
| 5508 | 5508 | const ssbase_lock: ?RegisterLock = if (opts.source_stack_base) |reg| |
| 5509 | | self.register_manager.freezeReg(reg) |
| 5509 | self.register_manager.lockReg(reg) |
| 5510 | 5510 | else |
| 5511 | 5511 | null; |
| 5512 | | defer if (ssbase_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 5512 | defer if (ssbase_lock) |reg| self.register_manager.unlockReg(reg); |
| 5513 | 5513 | |
| 5514 | 5514 | const dsbase_lock: ?RegisterLock = if (opts.dest_stack_base) |reg| |
| 5515 | | self.register_manager.freezeReg(reg) |
| 5515 | self.register_manager.lockReg(reg) |
| 5516 | 5516 | else |
| 5517 | 5517 | null; |
| 5518 | | defer if (dsbase_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 5518 | defer if (dsbase_lock) |reg| self.register_manager.unlockReg(reg); |
| 5519 | 5519 | |
| 5520 | 5520 | const dst_addr_reg = try self.register_manager.allocReg(null); |
| 5521 | 5521 | switch (dst_ptr) { |
| ... | ... | @@ -5549,8 +5549,8 @@ fn genInlineMemcpy( |
| 5549 | 5549 | return self.fail("TODO implement memcpy for setting stack when dest is {}", .{dst_ptr}); |
| 5550 | 5550 | }, |
| 5551 | 5551 | } |
| 5552 | | const dst_addr_reg_lock = self.register_manager.freezeRegAssumeUnused(dst_addr_reg); |
| 5553 | | defer self.register_manager.unfreezeReg(dst_addr_reg_lock); |
| 5552 | const dst_addr_reg_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg); |
| 5553 | defer self.register_manager.unlockReg(dst_addr_reg_lock); |
| 5554 | 5554 | |
| 5555 | 5555 | const src_addr_reg = try self.register_manager.allocReg(null); |
| 5556 | 5556 | switch (src_ptr) { |
| ... | ... | @@ -5584,8 +5584,8 @@ fn genInlineMemcpy( |
| 5584 | 5584 | return self.fail("TODO implement memcpy for setting stack when src is {}", .{src_ptr}); |
| 5585 | 5585 | }, |
| 5586 | 5586 | } |
| 5587 | | const src_addr_reg_lock = self.register_manager.freezeRegAssumeUnused(src_addr_reg); |
| 5588 | | defer self.register_manager.unfreezeReg(src_addr_reg_lock); |
| 5587 | const src_addr_reg_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg); |
| 5588 | defer self.register_manager.unlockReg(src_addr_reg_lock); |
| 5589 | 5589 | |
| 5590 | 5590 | const regs = try self.register_manager.allocRegs(2, .{ null, null }); |
| 5591 | 5591 | const count_reg = regs[0].to64(); |
| ... | ... | @@ -5695,8 +5695,8 @@ fn genInlineMemset( |
| 5695 | 5695 | opts: InlineMemcpyOpts, |
| 5696 | 5696 | ) InnerError!void { |
| 5697 | 5697 | try self.register_manager.getReg(.rax, null); |
| 5698 | | const rax_lock = self.register_manager.freezeRegAssumeUnused(.rax); |
| 5699 | | defer self.register_manager.unfreezeReg(rax_lock); |
| 5698 | const rax_lock = self.register_manager.lockRegAssumeUnused(.rax); |
| 5699 | defer self.register_manager.unlockReg(rax_lock); |
| 5700 | 5700 | |
| 5701 | 5701 | const addr_reg = try self.register_manager.allocReg(null); |
| 5702 | 5702 | switch (dst_ptr) { |
| ... | ... | @@ -5730,8 +5730,8 @@ fn genInlineMemset( |
| 5730 | 5730 | return self.fail("TODO implement memcpy for setting stack when dest is {}", .{dst_ptr}); |
| 5731 | 5731 | }, |
| 5732 | 5732 | } |
| 5733 | | const addr_reg_lock = self.register_manager.freezeRegAssumeUnused(addr_reg); |
| 5734 | | defer self.register_manager.unfreezeReg(addr_reg_lock); |
| 5733 | const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 5734 | defer self.register_manager.unlockReg(addr_reg_lock); |
| 5735 | 5735 | |
| 5736 | 5736 | try self.genSetReg(Type.usize, .rax, len); |
| 5737 | 5737 | try self.genBinMathOpMir(.sub, Type.usize, .{ .register = .rax }, .{ .immediate = 1 }); |
| ... | ... | @@ -6171,24 +6171,24 @@ fn airMemset(self: *Self, inst: Air.Inst.Index) !void { |
| 6171 | 6171 | |
| 6172 | 6172 | const dst_ptr = try self.resolveInst(pl_op.operand); |
| 6173 | 6173 | const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) { |
| 6174 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6174 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6175 | 6175 | else => null, |
| 6176 | 6176 | }; |
| 6177 | | defer if (dst_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6177 | defer if (dst_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 6178 | 6178 | |
| 6179 | 6179 | const src_val = try self.resolveInst(extra.lhs); |
| 6180 | 6180 | const src_val_lock: ?RegisterLock = switch (src_val) { |
| 6181 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6181 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6182 | 6182 | else => null, |
| 6183 | 6183 | }; |
| 6184 | | defer if (src_val_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6184 | defer if (src_val_lock) |reg| self.register_manager.unlockReg(reg); |
| 6185 | 6185 | |
| 6186 | 6186 | const len = try self.resolveInst(extra.rhs); |
| 6187 | 6187 | const len_lock: ?RegisterLock = switch (len) { |
| 6188 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6188 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6189 | 6189 | else => null, |
| 6190 | 6190 | }; |
| 6191 | | defer if (len_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6191 | defer if (len_lock) |reg| self.register_manager.unlockReg(reg); |
| 6192 | 6192 | |
| 6193 | 6193 | try self.genInlineMemset(dst_ptr, src_val, len, .{}); |
| 6194 | 6194 | |
| ... | ... | @@ -6201,25 +6201,25 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 6201 | 6201 | |
| 6202 | 6202 | const dst_ptr = try self.resolveInst(pl_op.operand); |
| 6203 | 6203 | const dst_ptr_lock: ?RegisterLock = switch (dst_ptr) { |
| 6204 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6204 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6205 | 6205 | else => null, |
| 6206 | 6206 | }; |
| 6207 | | defer if (dst_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6207 | defer if (dst_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 6208 | 6208 | |
| 6209 | 6209 | const src_ty = self.air.typeOf(extra.lhs); |
| 6210 | 6210 | const src_ptr = try self.resolveInst(extra.lhs); |
| 6211 | 6211 | const src_ptr_lock: ?RegisterLock = switch (src_ptr) { |
| 6212 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6212 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6213 | 6213 | else => null, |
| 6214 | 6214 | }; |
| 6215 | | defer if (src_ptr_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6215 | defer if (src_ptr_lock) |reg| self.register_manager.unlockReg(reg); |
| 6216 | 6216 | |
| 6217 | 6217 | const len = try self.resolveInst(extra.rhs); |
| 6218 | 6218 | const len_lock: ?RegisterLock = switch (len) { |
| 6219 | | .register => |reg| self.register_manager.freezeRegAssumeUnused(reg), |
| 6219 | .register => |reg| self.register_manager.lockRegAssumeUnused(reg), |
| 6220 | 6220 | else => null, |
| 6221 | 6221 | }; |
| 6222 | | defer if (len_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6222 | defer if (len_lock) |reg| self.register_manager.unlockReg(reg); |
| 6223 | 6223 | |
| 6224 | 6224 | // TODO Is this the only condition for pointer dereference for memcpy? |
| 6225 | 6225 | const src: MCValue = blk: { |
| ... | ... | @@ -6242,10 +6242,10 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 6242 | 6242 | } |
| 6243 | 6243 | }; |
| 6244 | 6244 | const src_lock: ?RegisterLock = switch (src) { |
| 6245 | | .register => |reg| self.register_manager.freezeReg(reg), |
| 6245 | .register => |reg| self.register_manager.lockReg(reg), |
| 6246 | 6246 | else => null, |
| 6247 | 6247 | }; |
| 6248 | | defer if (src_lock) |reg| self.register_manager.unfreezeReg(reg); |
| 6248 | defer if (src_lock) |reg| self.register_manager.unlockReg(reg); |
| 6249 | 6249 | |
| 6250 | 6250 | try self.genInlineMemcpy(dst_ptr, src, len, .{}); |
| 6251 | 6251 | |