| ... | @@ -211,6 +211,16 @@ pub const MCValue = union(enum) { | ... | @@ -211,6 +211,16 @@ pub const MCValue = union(enum) { |
| 211 | else => false, | 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 | const Branch = struct { | 226 | const Branch = struct { |
| ... | @@ -842,20 +852,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live | ... | @@ -842,20 +852,15 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live |
| 842 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; | 852 | const branch = &self.branch_stack.items[self.branch_stack.items.len - 1]; |
| 843 | branch.inst_table.putAssumeCapacityNoClobber(inst, result); | 853 | branch.inst_table.putAssumeCapacityNoClobber(inst, result); |
| 844 | | 854 | |
| 845 | switch (result) { | 855 | if (result.asRegister()) |reg| { |
| 846 | .register, | 856 | // In some cases (such as bitcast), an operand |
| 847 | .register_overflow_signed, | 857 | // may be the same MCValue as the result. If |
| 848 | .register_overflow_unsigned, | 858 | // that operand died and was a register, it |
| 849 | => |reg| { | 859 | // was freed by processDeath. We have to |
| 850 | // In some cases (such as bitcast), an operand | 860 | // "re-allocate" the register. |
| 851 | // may be the same MCValue as the result. If | 861 | if (self.register_manager.isRegFree(reg)) { |
| 852 | // that operand died and was a register, it | 862 | self.register_manager.getRegAssumeFree(reg, inst); |
| 853 | // was freed by processDeath. We have to | 863 | } |
| 854 | // "re-allocate" the register. | | |
| 855 | if (self.register_manager.isRegFree(reg)) { | | |
| 856 | self.register_manager.getRegAssumeFree(reg, inst); | | |
| 857 | } | | |
| 858 | }, | | |
| 859 | } | 864 | } |
| 860 | } | 865 | } |
| 861 | self.finishAirBookkeeping(); | 866 | self.finishAirBookkeeping(); |
| ... | @@ -4011,12 +4016,6 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4011,12 +4016,6 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { |
| 4011 | const ret_ty = self.fn_type.fnReturnType(); | 4016 | const ret_ty = self.fn_type.fnReturnType(); |
| 4012 | switch (self.ret_mcv) { | 4017 | switch (self.ret_mcv) { |
| 4013 | .stack_offset => { | 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 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); | 4019 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4021 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); | 4020 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4022 | defer self.register_manager.unfreezeReg(reg_lock); | 4021 | defer self.register_manager.unfreezeReg(reg_lock); |
| ... | @@ -4051,12 +4050,6 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4051,12 +4050,6 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 4051 | const elem_ty = ptr_ty.elemType(); | 4050 | const elem_ty = ptr_ty.elemType(); |
| 4052 | switch (self.ret_mcv) { | 4051 | switch (self.ret_mcv) { |
| 4053 | .stack_offset => { | 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 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); | 4053 | const reg = try self.copyToTmpRegister(Type.usize, self.ret_mcv); |
| 4061 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); | 4054 | const reg_lock = self.register_manager.freezeRegAssumeUnused(reg); |
| 4062 | defer self.register_manager.unfreezeReg(reg_lock); | 4055 | defer self.register_manager.unfreezeReg(reg_lock); |