diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 16f71881d0..fccf608db1 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -31,6 +31,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" +#include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/Reporting.h" #include "Common/ChunkFile.h" @@ -1460,6 +1461,10 @@ void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled) } memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); + if (MIPSComp::jit) { + // When thread switching, we must update the rounding mode if cached in the jit. + MIPSComp::jit->UpdateFCR31(); + } // Reset the llBit, the other thread may have touched memory. currentMIPS->llBit = 0; diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 5ded4af630..7e9d6aa3f6 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -106,6 +106,9 @@ void ArmJit::DoState(PointerWrap &p) } } +void ArmJit::UpdateFCR31() { +} + void ArmJit::FlushAll() { gpr.FlushAll(); diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 903f43e094..941b7372fb 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -175,6 +175,7 @@ public: void ClearCache() override; void InvalidateCacheAt(u32 em_address, int length = 4) override; + void UpdateFCR31() override; void EatPrefix() override { js.EatPrefix(); } diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index e1aaea334f..378d38a3e5 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -79,7 +79,7 @@ Arm64Jit::Arm64Jit(MIPSState *mips) : blocks(mips, this), gpr(mips, &js, &jo), f AllocCodeSpace(1024 * 1024 * 16); // 32MB is the absolute max because that's what an ARM branch instruction can reach, backwards and forwards. GenerateFixedCode(jo); js.startDefaultPrefix = mips_->HasDefaultPrefix(); - js.currentRoundingFunc = convertS0ToSCRATCH1[0]; + js.currentRoundingFunc = convertS0ToSCRATCH1[mips_->fcr31 & 3]; } Arm64Jit::~Arm64Jit() { @@ -98,13 +98,14 @@ void Arm64Jit::DoState(PointerWrap &p) { js.hasSetRounding = 1; } - if (p.GetMode() == PointerWrap::MODE_READ) { - js.currentRoundingFunc = convertS0ToSCRATCH1[(mips_->fcr31) & 3]; - } + // Note: we can't update the currentRoundingFunc here because fcr31 wasn't loaded yet. } -void Arm64Jit::FlushAll() -{ +void Arm64Jit::UpdateFCR31() { + js.currentRoundingFunc = convertS0ToSCRATCH1[mips_->fcr31 & 3]; +} + +void Arm64Jit::FlushAll() { gpr.FlushAll(); fpr.FlushAll(); FlushPrefixV(); diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 28fdb16501..5d815eef83 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -176,6 +176,7 @@ public: void ClearCache() override; void InvalidateCacheAt(u32 em_address, int length = 4) override; + void UpdateFCR31() override; void EatPrefix() override { js.EatPrefix(); } diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 9a86a4356f..63114371e4 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -55,6 +55,9 @@ void IRJit::DoState(PointerWrap &p) { frontend_.DoState(p); } +void IRJit::UpdateFCR31() { +} + void IRJit::ClearCache() { ILOG("IRJit: Clearing the cache!"); blocks_.Clear(); diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index beefcf9bcb..d378dcfc87 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -158,6 +158,7 @@ public: void ClearCache() override; void InvalidateCacheAt(u32 em_address, int length = 4) override; + void UpdateFCR31() override; const u8 *GetDispatcher() const override { return nullptr; } diff --git a/Core/MIPS/JitCommon/JitCommon.h b/Core/MIPS/JitCommon/JitCommon.h index 33e07b1955..bf3023e21d 100644 --- a/Core/MIPS/JitCommon/JitCommon.h +++ b/Core/MIPS/JitCommon/JitCommon.h @@ -131,6 +131,7 @@ namespace MIPSComp { virtual void Compile(u32 em_address) = 0; virtual void CompileFunction(u32 start_address, u32 length) { } virtual void ClearCache() = 0; + virtual void UpdateFCR31() = 0; virtual MIPSOpcode GetOriginalOp(MIPSOpcode op) = 0; // No jit operations may be run between these calls. diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 2302928968..37f16025ad 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -293,6 +293,11 @@ void MIPSState::DoState(PointerWrap &p) { p.Do(inDelaySlot); p.Do(llBit); p.Do(debugCount); + + if (p.mode == p.MODE_READ && MIPSComp::jit) { + // Now that we've loaded fcr31, update any jit state associated. + MIPSComp::jit->UpdateFCR31(); + } } void MIPSState::SingleStep() { diff --git a/Core/MIPS/MIPS/MipsJit.cpp b/Core/MIPS/MIPS/MipsJit.cpp index 48637e8f23..bf3b88ee20 100644 --- a/Core/MIPS/MIPS/MipsJit.cpp +++ b/Core/MIPS/MIPS/MipsJit.cpp @@ -66,6 +66,9 @@ void MipsJit::DoState(PointerWrap &p) } } +void MipsJit::UpdateFCR31() { +} + void MipsJit::FlushAll() { //gpr.FlushAll(); diff --git a/Core/MIPS/MIPS/MipsJit.h b/Core/MIPS/MIPS/MipsJit.h index bc6a526f01..88c1c2dc6d 100644 --- a/Core/MIPS/MIPS/MipsJit.h +++ b/Core/MIPS/MIPS/MipsJit.h @@ -136,6 +136,7 @@ public: void ClearCache() override; void InvalidateCacheAt(u32 em_address, int length = 4) override; + void UpdateFCR31() override; void EatPrefix() override { js.EatPrefix(); } diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index fe9373e9f5..a1273526e6 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -528,6 +528,10 @@ namespace MIPSInt if (fs == 31) { currentMIPS->fcr31 = value & 0x0181FFFF; currentMIPS->fpcond = (value >> 23) & 1; + if (MIPSComp::jit) { + // In case of DISABLE, we need to tell jit we updated FCR31. + MIPSComp::jit->UpdateFCR31(); + } } else { WARN_LOG_REPORT(CPU, "WriteFCR: Unexpected reg %d (value %08x)", fs, value); } diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 48e098cc3c..d92f33a1ca 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -142,6 +142,9 @@ void Jit::DoState(PointerWrap &p) { CBreakPoints::SetSkipFirst(0); } +void Jit::UpdateFCR31() { +} + void Jit::GetStateAndFlushAll(RegCacheState &state) { gpr.GetState(state.gpr); fpr.GetState(state.fpr); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index d6ff79b003..973c5ce496 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -171,6 +171,7 @@ public: blocks.InvalidateICache(em_address, length); } } + void UpdateFCR31() override; const u8 *GetDispatcher() const override { return dispatcher;