From 09e307b097f64628c4ffb6807582b398bba1868d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 1 Apr 2018 10:09:31 -0700 Subject: [PATCH 1/2] 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. --- Core/HLE/sceKernelThread.cpp | 5 +++++ Core/MIPS/ARM/ArmJit.cpp | 3 +++ Core/MIPS/ARM/ArmJit.h | 1 + Core/MIPS/ARM64/Arm64Jit.cpp | 13 +++++++------ Core/MIPS/ARM64/Arm64Jit.h | 1 + Core/MIPS/IR/IRJit.cpp | 3 +++ Core/MIPS/IR/IRJit.h | 1 + Core/MIPS/JitCommon/JitCommon.h | 1 + Core/MIPS/MIPS.cpp | 5 +++++ Core/MIPS/MIPS/MipsJit.cpp | 3 +++ Core/MIPS/MIPS/MipsJit.h | 1 + Core/MIPS/MIPSInt.cpp | 4 ++++ Core/MIPS/x86/Jit.cpp | 3 +++ Core/MIPS/x86/Jit.h | 1 + 14 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 16f71881d..fccf608db 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 5ded4af63..7e9d6aa3f 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 903f43e09..941b7372f 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 e1aaea334..378d38a3e 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 28fdb1650..5d815eef8 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 9a86a4356..63114371e 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 beefcf9bc..d378dcfc8 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 33e07b195..bf3023e21 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 230292896..37f16025a 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 48637e8f2..bf3b88ee2 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 bc6a526f0..88c1c2dc6 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 fe9373e9f..a1273526e 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 48e098cc3..d92f33a1c 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 d6ff79b00..973c5ce49 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; From ab809bd19ee15d2ef03a250345f70eb9948ecf01 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 1 Apr 2018 10:36:16 -0700 Subject: [PATCH 2/2] jit: Apply hasSetRounding at compile time. Otherwise, the block will be executed with the wrong rounding mode the first time rounding is set. This could be important if it was set for a single operation. This is only a problem the first time it's set. --- Core/MIPS/ARM/ArmAsm.cpp | 14 -------------- Core/MIPS/ARM/ArmCompFPU.cpp | 8 ++++++-- Core/MIPS/ARM/ArmJit.cpp | 8 ++++++-- Core/MIPS/ARM/ArmJit.h | 3 +-- Core/MIPS/ARM64/Arm64Asm.cpp | 11 ----------- Core/MIPS/ARM64/Arm64CompFPU.cpp | 10 +++++++--- Core/MIPS/ARM64/Arm64Jit.cpp | 7 ++++++- Core/MIPS/ARM64/Arm64Jit.h | 2 +- Core/MIPS/IR/IRFrontend.cpp | 2 ++ Core/MIPS/x86/Asm.cpp | 12 ------------ Core/MIPS/x86/CompFPU.cpp | 2 +- Core/MIPS/x86/Jit.cpp | 10 ++++++---- Core/MIPS/x86/Jit.h | 3 +-- 13 files changed, 37 insertions(+), 55 deletions(-) diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index b32d39ef7..7e037a705 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -123,20 +123,6 @@ void ArmJit::GenerateFixedCode() { POP(2, SCRATCHREG1, R_PC); } - // Must preserve SCRATCHREG1 (R0), destroys SCRATCHREG2 (LR) - updateRoundingMode = AlignCode16(); { - PUSH(2, SCRATCHREG1, R_LR); - LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31)); - MOVI2R(SCRATCHREG1, 0x1000003); - TST(SCRATCHREG2, SCRATCHREG1); - FixupBranch skip = B_CC(CC_EQ); // zero - MOVI2R(SCRATCHREG2, 1); - MOVP2R(SCRATCHREG1, &js.hasSetRounding); - STRB(SCRATCHREG2, SCRATCHREG1, 0); - SetJumpTarget(skip); - POP(2, SCRATCHREG1, R_PC); - } - FlushLitPool(); enterDispatcher = AlignCode16(); diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index 475cf7fdb..971f8cebd 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -416,8 +416,10 @@ void ArmJit::Comp_mxc1(MIPSOpcode op) // Must clear before setting, since ApplyRoundingMode() assumes it was cleared. RestoreRoundingMode(); bool wasImm = gpr.IsImm(rt); + u32 immVal = -1; if (wasImm) { - gpr.SetImm(MIPS_REG_FPCOND, (gpr.GetImm(rt) >> 23) & 1); + immVal = gpr.GetImm(rt); + gpr.SetImm(MIPS_REG_FPCOND, (immVal >> 23) & 1); gpr.MapReg(rt); } else { gpr.MapDirtyIn(MIPS_REG_FPCOND, rt); @@ -433,8 +435,10 @@ void ArmJit::Comp_mxc1(MIPSOpcode op) MOV(SCRATCHREG1, Operand2(gpr.R(rt), ST_LSR, 23)); AND(gpr.R(MIPS_REG_FPCOND), SCRATCHREG1, Operand2(1)); #endif + UpdateRoundingMode(); + } else { + UpdateRoundingMode(immVal); } - UpdateRoundingMode(); ApplyRoundingMode(); } else { Comp_Generic(op); diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index 7e9d6aa3f..ea206a6d2 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -640,8 +640,12 @@ void ArmJit::ApplyRoundingMode(bool force) { } // Does (must!) not destroy R0 (SCRATCHREG1). Destroys R14 (SCRATCHREG2). -void ArmJit::UpdateRoundingMode() { - QuickCallFunction(R1, updateRoundingMode); +void ArmJit::UpdateRoundingMode(u32 fcr31) { + // We must set js.hasSetRounding at compile time, or this block will use the wrong rounding mode. + // The fcr31 parameter is -1 when not known at compile time, so we just assume it was changed. + if (fcr31 & 0x01000003) { + js.hasSetRounding = true; + } } // IDEA - could have a WriteDualExit that takes two destinations and two condition flags, diff --git a/Core/MIPS/ARM/ArmJit.h b/Core/MIPS/ARM/ArmJit.h index 941b7372f..af2b6a128 100644 --- a/Core/MIPS/ARM/ArmJit.h +++ b/Core/MIPS/ARM/ArmJit.h @@ -203,7 +203,7 @@ private: void WriteDownCountR(ArmGen::ARMReg reg); void RestoreRoundingMode(bool force = false); void ApplyRoundingMode(bool force = false); - void UpdateRoundingMode(); + void UpdateRoundingMode(u32 fcr31 = -1); void MovFromPC(ArmGen::ARMReg r); void MovToPC(ArmGen::ARMReg r); @@ -311,7 +311,6 @@ public: const u8 *restoreRoundingMode; const u8 *applyRoundingMode; - const u8 *updateRoundingMode; const u8 *breakpointBailout; }; diff --git a/Core/MIPS/ARM64/Arm64Asm.cpp b/Core/MIPS/ARM64/Arm64Asm.cpp index f0f5ac3e7..2390ed967 100644 --- a/Core/MIPS/ARM64/Arm64Asm.cpp +++ b/Core/MIPS/ARM64/Arm64Asm.cpp @@ -177,17 +177,6 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) { ADDI2R(SCRATCH2, SCRATCH2, 4); SetJumpTarget(skip); - // We need both SCRATCH1 and SCRATCH2 for updating hasSetRounding. - PUSH(SCRATCH2); - // We can only skip if the rounding mode is zero and flush is not set. - CMPI2R(SCRATCH2, 0); - FixupBranch skip2 = B(CC_EQ); - MOVI2R(SCRATCH2, 1); - MOVP2R(SCRATCH1_64, &js.hasSetRounding); - STRB(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0); - SetJumpTarget(skip2); - POP(SCRATCH2); - // Let's update js.currentRoundingFunc with the right convertS0ToSCRATCH1 func. MOVP2R(SCRATCH1_64, convertS0ToSCRATCH1); LSL(SCRATCH2, SCRATCH2, 3); diff --git a/Core/MIPS/ARM64/Arm64CompFPU.cpp b/Core/MIPS/ARM64/Arm64CompFPU.cpp index ea971de24..e608baa6d 100644 --- a/Core/MIPS/ARM64/Arm64CompFPU.cpp +++ b/Core/MIPS/ARM64/Arm64CompFPU.cpp @@ -375,8 +375,10 @@ void Arm64Jit::Comp_mxc1(MIPSOpcode op) // Must clear before setting, since ApplyRoundingMode() assumes it was cleared. RestoreRoundingMode(); bool wasImm = gpr.IsImm(rt); + u32 immVal = -1; if (wasImm) { - gpr.SetImm(MIPS_REG_FPCOND, (gpr.GetImm(rt) >> 23) & 1); + immVal = gpr.GetImm(rt); + gpr.SetImm(MIPS_REG_FPCOND, (immVal >> 23) & 1); gpr.MapReg(rt); } else { gpr.MapDirtyIn(MIPS_REG_FPCOND, rt); @@ -387,9 +389,11 @@ void Arm64Jit::Comp_mxc1(MIPSOpcode op) STR(INDEX_UNSIGNED, gpr.R(rt), CTXREG, offsetof(MIPSState, fcr31)); if (!wasImm) { UBFX(gpr.R(MIPS_REG_FPCOND), gpr.R(rt), 23, 1); + // TODO: We do have the fcr31 value in a register here, could use that in UpdateRoundingMode to avoid reloading it. + UpdateRoundingMode(); + } else { + UpdateRoundingMode(immVal); } - // TODO: We do have the fcr31 value in a register here, could use that in UpdateRoundingMode to avoid reloading it. - UpdateRoundingMode(); ApplyRoundingMode(); } else { Comp_Generic(op); diff --git a/Core/MIPS/ARM64/Arm64Jit.cpp b/Core/MIPS/ARM64/Arm64Jit.cpp index 378d38a3e..46b1a9bf3 100644 --- a/Core/MIPS/ARM64/Arm64Jit.cpp +++ b/Core/MIPS/ARM64/Arm64Jit.cpp @@ -602,7 +602,12 @@ void Arm64Jit::ApplyRoundingMode(bool force) { } // Destroys SCRATCH1 and SCRATCH2 -void Arm64Jit::UpdateRoundingMode() { +void Arm64Jit::UpdateRoundingMode(u32 fcr31) { + // We must set js.hasSetRounding at compile time, or this block will use the wrong rounding mode. + // The fcr31 parameter is -1 when not known at compile time, so we just assume it was changed. + if (fcr31 & 0x01000003) { + js.hasSetRounding = true; + } QuickCallFunction(SCRATCH2_64, updateRoundingMode); } diff --git a/Core/MIPS/ARM64/Arm64Jit.h b/Core/MIPS/ARM64/Arm64Jit.h index 5d815eef8..3d8445138 100644 --- a/Core/MIPS/ARM64/Arm64Jit.h +++ b/Core/MIPS/ARM64/Arm64Jit.h @@ -202,7 +202,7 @@ private: void WriteDownCountR(Arm64Gen::ARM64Reg reg, bool updateFlags = true); void RestoreRoundingMode(bool force = false); void ApplyRoundingMode(bool force = false); - void UpdateRoundingMode(); + void UpdateRoundingMode(u32 fcr31 = -1); void MovFromPC(Arm64Gen::ARM64Reg r); void MovToPC(Arm64Gen::ARM64Reg r); diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index d7ca005e6..b86ff2890 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -200,6 +200,8 @@ void IRFrontend::ApplyRoundingMode(bool force) { // Destroys SCRATCH1 and SCRATCH2 void IRFrontend::UpdateRoundingMode() { + // We must set js.hasSetRounding at compile time, or this block will use the wrong rounding mode. + js.hasSetRounding = true; ir.Write(IROp::UpdateRoundingMode); } diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index 64d0e9af3..a6242801f 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -109,18 +109,6 @@ void Jit::GenerateFixedCode(JitOptions &jo) { RET(); } - updateRoundingMode = AlignCode16(); { - // If it's only ever 0, we don't actually bother applying or restoring it. - // This is the most common situation. - TEST(32, MIPSSTATE_VAR(fcr31), Imm32(0x01000003)); - FixupBranch skip = J_CC(CC_Z); - // TODO: Move the hasSetRounding flag somewhere we can reach it through the context pointer, or something. - MOV(PTRBITS, R(RAX), ImmPtr(&js.hasSetRounding)); - MOV(8, MatR(RAX), Imm8(1)); - SetJumpTarget(skip); - RET(); - } - enterDispatcher = AlignCode16(); ABI_PushAllCalleeSavedRegsAndAdjustStack(); #ifdef _M_X64 diff --git a/Core/MIPS/x86/CompFPU.cpp b/Core/MIPS/x86/CompFPU.cpp index 9ed0c6871..664490966 100644 --- a/Core/MIPS/x86/CompFPU.cpp +++ b/Core/MIPS/x86/CompFPU.cpp @@ -426,7 +426,7 @@ void Jit::Comp_mxc1(MIPSOpcode op) { if ((gpr.GetImm(rt) & 0x1000003) == 0) { // Default nearest / no-flush mode, just leave it cleared. } else { - UpdateRoundingMode(); + UpdateRoundingMode(gpr.GetImm(rt)); ApplyRoundingMode(); } } else { diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index d92f33a1c..45eadbf61 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -198,8 +198,12 @@ void Jit::ApplyRoundingMode(bool force) { } } -void Jit::UpdateRoundingMode() { - CALL(updateRoundingMode); +void Jit::UpdateRoundingMode(u32 fcr31) { + // We must set js.hasSetRounding at compile time, or this block will use the wrong rounding mode. + // The fcr31 parameter is -1 when not known at compile time, so we just assume it was changed. + if (fcr31 & 0x01000003) { + js.hasSetRounding = true; + } } void Jit::ClearCache() @@ -418,8 +422,6 @@ void Jit::AddContinuedBlock(u32 dest) { bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) { if (ptr == applyRoundingMode) name = "applyRoundingMode"; - else if (ptr == updateRoundingMode) - name = "updateRoundingMode"; else if (ptr == dispatcher) name = "dispatcher"; else if (ptr == dispatcherInEAXNoCheck) diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 973c5ce49..1c397005f 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -155,7 +155,7 @@ public: void RestoreRoundingMode(bool force = false); void ApplyRoundingMode(bool force = false); - void UpdateRoundingMode(); + void UpdateRoundingMode(u32 fcr31 = -1); JitBlockCache *GetBlockCache() override { return &blocks; } JitBlockCacheDebugInterface *GetBlockCacheDebugInterface() override { return &blocks; } @@ -324,7 +324,6 @@ private: const u8 *restoreRoundingMode; const u8 *applyRoundingMode; - const u8 *updateRoundingMode; const u8 *endOfPregeneratedCode;