diff --git a/src/backend/A64/a32_interface.cpp b/src/backend/A64/a32_interface.cpp index db8fd2b9..2fe93de1 100644 --- a/src/backend/A64/a32_interface.cpp +++ b/src/backend/A64/a32_interface.cpp @@ -60,13 +60,18 @@ struct Jit::Impl { bool invalidate_entire_cache = false; void Execute() { - const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A32JitState::RSBPtrMask; - if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) { - jit_state.rsb_ptr = new_rsb_ptr; - block_of_code.RunCodeFrom(&jit_state, reinterpret_cast(jit_state.rsb_codeptrs[new_rsb_ptr])); - } else { - block_of_code.RunCode(&jit_state); - } + const CodePtr current_codeptr = [this]{ + // RSB optimization + const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A32JitState::RSBPtrMask; + if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) { + jit_state.rsb_ptr = new_rsb_ptr; + return reinterpret_cast(jit_state.rsb_codeptrs[new_rsb_ptr]); + } + + return GetCurrentBlock(); + }(); + + block_of_code.RunCode(&jit_state, current_codeptr); } std::string Disassemble(const IR::LocationDescriptor& descriptor) { @@ -255,7 +260,6 @@ const std::array& Context::ExtRegs() const { return impl->jit_state.ExtReg; } -/// View and modify CPSR. std::uint32_t Context::Cpsr() const { return impl->jit_state.Cpsr(); } @@ -263,7 +267,6 @@ void Context::SetCpsr(std::uint32_t value) { impl->jit_state.SetCpsr(value); } -/// View and modify FPSCR. std::uint32_t Context::Fpscr() const { return impl->jit_state.Fpscr(); } diff --git a/src/backend/A64/block_of_code.cpp b/src/backend/A64/block_of_code.cpp index d6670beb..15f54923 100644 --- a/src/backend/A64/block_of_code.cpp +++ b/src/backend/A64/block_of_code.cpp @@ -123,12 +123,10 @@ size_t BlockOfCode::SpaceRemaining() const { return std::min(TOTAL_CODE_SIZE - far_code_offset, FAR_CODE_OFFSET - near_code_offset); } -void BlockOfCode::RunCode(void* jit_state) const { - run_code(jit_state); +void BlockOfCode::RunCode(void* jit_state, CodePtr code_ptr) const { + run_code(jit_state, code_ptr); } -void BlockOfCode::RunCodeFrom(void* jit_state, CodePtr code_ptr) const { - run_code_from(jit_state, code_ptr); } void BlockOfCode::ReturnFromRunCode(bool fpscr_already_exited) { @@ -148,23 +146,6 @@ void BlockOfCode::ForceReturnFromRunCode(bool fpscr_already_exited) { void BlockOfCode::GenRunCode() { const u8* loop, *enter_fpscr_then_loop; - AlignCode16(); - run_code_from = (RunCodeFromFuncType) GetWritableCodePtr(); - - ABI_PushCalleeSaveRegistersAndAdjustStack(*this); - - MOV(Arm64Gen::X28, ABI_PARAM1); - MOVI2R(Arm64Gen::X27, cb.value_in_X27); - MOV(Arm64Gen::X25, ABI_PARAM2); // save temporarily in non-volatile register - - cb.GetTicksRemaining->EmitCall(*this); - - STR(Arm64Gen::INDEX_UNSIGNED, ABI_RETURN, Arm64Gen::X28, jsi.offsetof_cycles_to_run); - MOV(Arm64Gen::X26, ABI_RETURN); - - SwitchFpscrOnEntry(); - BR(Arm64Gen::X25); - AlignCode16(); run_code = (RunCodeFuncType) GetWritableCodePtr(); @@ -176,15 +157,18 @@ void BlockOfCode::GenRunCode() { MOV(Arm64Gen::X28, ABI_PARAM1); MOVI2R(Arm64Gen::X27, cb.value_in_X27); + MOV(Arm64Gen::X25, ABI_PARAM2); // save temporarily in non-volatile register cb.GetTicksRemaining->EmitCall(*this); STR(Arm64Gen::INDEX_UNSIGNED, ABI_RETURN, Arm64Gen::X28, jsi.offsetof_cycles_to_run); MOV(Arm64Gen::X26, ABI_RETURN); + SwitchFpscrOnEntry(); + BR(Arm64Gen::X25); + enter_fpscr_then_loop = GetCodePtr(); SwitchFpscrOnEntry(); loop = GetCodePtr(); - cb.LookupBlock->EmitCall(*this); BR(ABI_RETURN); @@ -220,7 +204,7 @@ void BlockOfCode::GenRunCode() { return_from_run_code[FPSCR_ALREADY_EXITED | FORCE_RETURN] = AlignCode16(); emit_return_from_run_code(true, true); - PerfMapRegister(run_code_from, GetCodePtr(), "dynarmic_dispatcher"); + PerfMapRegister(run_code, GetCodePtr(), "dynarmic_dispatcher"); } void BlockOfCode::SwitchFpscrOnEntry() { diff --git a/src/backend/A64/block_of_code.h b/src/backend/A64/block_of_code.h index 23c35b24..171973f8 100644 --- a/src/backend/A64/block_of_code.h +++ b/src/backend/A64/block_of_code.h @@ -46,10 +46,8 @@ public: /// Calculates how much space is remaining to use. This is the minimum of near code and far code. size_t SpaceRemaining() const; - /// Runs emulated code. - void RunCode(void* jit_state) const; /// Runs emulated code from code_ptr. - void RunCodeFrom(void* jit_state, CodePtr code_ptr) const; + void RunCode(void* jit_state, CodePtr code_ptr) const; /// Code emitter: Returns to dispatcher void ReturnFromRunCode(bool fpscr_already_exited = false); /// Code emitter: Returns to dispatcher, forces return to host @@ -133,10 +131,8 @@ private: CodePtr near_code_ptr; CodePtr far_code_ptr; - using RunCodeFuncType = void(*)(void*); - using RunCodeFromFuncType = void(*)(void*, CodePtr); + using RunCodeFuncType = void(*)(void*, CodePtr); RunCodeFuncType run_code = nullptr; - RunCodeFromFuncType run_code_from = nullptr; static constexpr size_t FPSCR_ALREADY_EXITED = 1 << 0; static constexpr size_t FORCE_RETURN = 1 << 1; std::array return_from_run_code;