diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index a2dc1cb6b7..9433e48b49 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -205,6 +205,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) // we must mark them as no longer discarded gpr.ResetRegisters(js.op->regsOut); fpr.ResetRegisters(js.op->GetFregsOut()); + gpr.ResetCRRegisters(js.op->crOut); if (js.op->opinfo->flags & FL_ENDBLOCK) { @@ -1199,9 +1200,11 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) { gpr.DiscardRegisters(op.gprDiscardable); fpr.DiscardRegisters(op.fprDiscardable); + gpr.DiscardCRRegisters(op.crDiscardable); } gpr.StoreRegisters(~op.gprInUse & (op.regsIn | op.regsOut)); fpr.StoreRegisters(~op.fprInUse & (op.fregsIn | op.GetFregsOut())); + gpr.StoreCRRegisters(~op.crInUse & (op.crIn | op.crOut)); if (opinfo->flags & FL_LOADSTORE) ++js.numLoadStoreInst; diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index d4e933aaf3..5da455cb61 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -129,6 +129,8 @@ void Arm64RegCache::DiscardRegister(size_t preg) { OpArg& reg = m_guest_registers[preg]; ARM64Reg host_reg = reg.GetReg(); + if (!IsVector(host_reg)) + host_reg = EncodeRegTo32(host_reg); reg.Discard(); if (host_reg != ARM64Reg::INVALID_REG) @@ -288,6 +290,25 @@ void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, bool maintain_state, ARM64Reg } } +void Arm64GPRCache::DiscardCRRegisters(BitSet8 regs) +{ + for (int i : regs) + DiscardRegister(GUEST_CR_OFFSET + i); +} + +void Arm64GPRCache::ResetCRRegisters(BitSet8 regs) +{ + for (int i : regs) + { + OpArg& reg = m_guest_registers[GUEST_CR_OFFSET + i]; + ARM64Reg host_reg = reg.GetReg(); + + ASSERT_MSG(DYNA_REC, host_reg == ARM64Reg::INVALID_REG, + "Attempted to reset a loaded register (did you mean to flush it?)"); + reg.Flush(); + } +} + void Arm64GPRCache::Flush(FlushMode mode, ARM64Reg tmp_reg) { FlushRegisters(BitSet32(0xFFFFFFFF), mode == FlushMode::MaintainState, tmp_reg); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index fbe1f30134..dad43ce9ef 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -335,6 +335,9 @@ public: FlushCRRegisters(regs, false, tmp_reg); } + void DiscardCRRegisters(BitSet8 regs); + void ResetCRRegisters(BitSet8 regs); + protected: // Get the order of the host registers void GetAllocationOrder() override;