arm64jit: Update rounding mode on thread switch.

Since fcr31 is per-thread, we must update jit state when it changes.
This also fixes the rounding mode on load state and jit/interp switch.
This commit is contained in:
Unknown W. Brackets 2018-04-01 10:09:31 -07:00
parent 7d3fac2b4b
commit 09e307b097
14 changed files with 39 additions and 6 deletions

View file

@ -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;

View file

@ -106,6 +106,9 @@ void ArmJit::DoState(PointerWrap &p)
}
}
void ArmJit::UpdateFCR31() {
}
void ArmJit::FlushAll()
{
gpr.FlushAll();

View file

@ -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(); }

View file

@ -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();

View file

@ -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(); }

View file

@ -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();

View file

@ -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; }

View file

@ -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.

View file

@ -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() {

View file

@ -66,6 +66,9 @@ void MipsJit::DoState(PointerWrap &p)
}
}
void MipsJit::UpdateFCR31() {
}
void MipsJit::FlushAll()
{
//gpr.FlushAll();

View file

@ -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(); }

View file

@ -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);
}

View file

@ -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);

View file

@ -171,6 +171,7 @@ public:
blocks.InvalidateICache(em_address, length);
}
}
void UpdateFCR31() override;
const u8 *GetDispatcher() const override {
return dispatcher;