| ... | ... | @@ -211,6 +211,16 @@ pub const MCValue = union(enum) { |
| 211 | 211 | else => false, |
| 212 | 212 | }; |
| 213 | 213 | } |
| 214 | |
| 215 | fn asRegister(mcv: MCValue) ?Register { |
| 216 | return switch (mcv) { |
| 217 | .register, |
| 218 | .register_overflow_unsigned, |
| 219 | .register_overflow_signed, |
| 220 | => |reg| reg, |
| 221 | else => null, |
| 222 | }; |
| 223 | } |
| 214 | 224 | }; |
| 215 | 225 | |
| 216 | 226 | const Branch = struct { |
| ... | ... | @@ -842,20 +852,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live |
| 842 | 852 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 843 | 853 | branch.inst_table.putAssumeCapacityNoClobber(inst, result); |
| 844 | 854 | |
| 845 | | switch (result) { |
| 846 | | .register, |
| 847 | | .register_overflow_signed, |
| 848 | | .register_overflow_unsigned, |
| 849 | | => |reg| { |
| 850 | | // In some cases (such as bitcast), an operand |
| 851 | | // may be the same MCValue as the result. If |
| 852 | | // that operand died and was a register, it |
| 853 | | // was freed by processDeath. We have to |
| 854 | | // "re-allocate" the register. |
| 855 | | if (self.register_manager.isRegFree(reg)) { |
| 856 | | self.register_manager.getRegAssumeFree(reg, inst); |
| 857 | | } |
| 858 | | }, |
| 855 | if (result.asRegister()) |reg| { |
| 856 | // In some cases (such as bitcast), an operand |
| 857 | // may be the same MCValue as the result. If |
| 858 | // that operand died and was a register, it |
| 859 | // was freed by processDeath. We have to |
| 860 | // "re-allocate" the register. |
| 861 | if (self.register_manager.isRegFree(reg)) { |
| 862 | self.register_manager.getRegAssumeFree(reg, inst); |
| 863 | } |
| 859 | 864 | } |
| 860 | 865 | } |
| 861 | 866 | self.finishAirBookkeeping(); |
| ... | ... | @@ -4011,12 +4016,6 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4011 | 4016 | const ret_ty = self.fn_type.fnReturnType(); |
| 4012 | 4017 | switch (self.ret_mcv) { |
| 4013 | 4018 | .stack_offset => { |
| 4014 | | var reg_locks: [2]RegisterLock = undefined; |
| 4015 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks); |
| 4016 | | defer for (reg_locks) |reg| { |
| 4017 | | self.register_manager.unfreezeReg(reg); |
| 4018 | | }; |
| 4019 | | |
| 4020 | 4019 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4021 | 4020 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4022 | 4021 | defer self.register_manager.unfreezeReg(reg_lock); |
| ... | ... | @@ -4051,12 +4050,6 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4051 | 4050 | const elem_ty = ptr_ty.elemType(); |
| 4052 | 4051 | switch (self.ret_mcv) { |
| 4053 | 4052 | .stack_offset => { |
| 4054 | | var reg_locks: [2]RegisterLock = undefined; |
| 4055 | | self.register_manager.freezeRegsAssumeUnused(2, .{ .rax, .rcx }, &reg_locks); |
| 4056 | | defer for (reg_locks) |reg| { |
| 4057 | | self.register_manager.unfreezeReg(reg); |
| 4058 | | }; |
| 4059 | | |
| 4060 | 4053 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4061 | 4054 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4062 | 4055 | defer self.register_manager.unfreezeReg(reg_lock); |