diff --git a/src/backend_x64/block_of_code.cpp b/src/backend_x64/block_of_code.cpp index 27a34f51..a1a7cdd6 100644 --- a/src/backend_x64/block_of_code.cpp +++ b/src/backend_x64/block_of_code.cpp @@ -82,7 +82,14 @@ void BlockOfCode::RunCode(JitState* jit_state, size_t cycles_to_run) const { jit_state->cycles_to_run = cycles_to_run; jit_state->cycles_remaining = cycles_to_run; - run_code(jit_state); + + u32 new_rsb_ptr = (jit_state->rsb_ptr - 1) & JitState::RSBPtrMask; + if (jit_state->GetUniqueHash() == jit_state->rsb_location_descriptors[new_rsb_ptr]) { + jit_state->rsb_ptr = new_rsb_ptr; + run_code_from(jit_state, jit_state->rsb_codeptrs[new_rsb_ptr]); + } else { + run_code(jit_state); + } } void BlockOfCode::ReturnFromRunCode(bool mxcsr_already_exited) { @@ -102,6 +109,14 @@ void BlockOfCode::ForceReturnFromRunCode(bool mxcsr_already_exited) { void BlockOfCode::GenRunCode() { Xbyak::Label loop, enter_mxcsr_then_loop; + align(); + run_code_from = getCurr(); + + ABI_PushCalleeSaveRegistersAndAdjustStack(this); + mov(r15, ABI_PARAM1); + SwitchMxcsrOnEntry(); + jmp(ABI_PARAM2); + align(); run_code = getCurr(); diff --git a/src/backend_x64/block_of_code.h b/src/backend_x64/block_of_code.h index d8cbe7ef..9df949ef 100644 --- a/src/backend_x64/block_of_code.h +++ b/src/backend_x64/block_of_code.h @@ -138,7 +138,9 @@ private: CodePtr far_code_ptr; using RunCodeFuncType = void(*)(JitState*); + using RunCodeFromFuncType = void(*)(JitState*, u64); RunCodeFuncType run_code = nullptr; + RunCodeFromFuncType run_code_from = nullptr; static constexpr size_t MXCSR_ALREADY_EXITED = 1 << 0; static constexpr size_t FORCE_RETURN = 1 << 1; std::array return_from_run_code; diff --git a/src/backend_x64/jitstate.cpp b/src/backend_x64/jitstate.cpp index 7101c5ce..b4b76223 100644 --- a/src/backend_x64/jitstate.cpp +++ b/src/backend_x64/jitstate.cpp @@ -199,5 +199,9 @@ void JitState::SetFpscr(u32 FPSCR) { } } +u64 JitState::GetUniqueHash() const { + return CPSR_et | FPSCR_mode | (static_cast(Reg[15]) << 32); +} + } // namespace BackendX64 } // namespace Dynarmic diff --git a/src/backend_x64/jitstate.h b/src/backend_x64/jitstate.h index 2916c26d..ea968432 100644 --- a/src/backend_x64/jitstate.h +++ b/src/backend_x64/jitstate.h @@ -67,6 +67,8 @@ struct JitState { u32 old_FPSCR = 0; u32 Fpscr() const; void SetFpscr(u32 FPSCR); + + u64 GetUniqueHash() const; }; #ifdef _MSC_VER