From 66e7693204f5b2b64cc3259183a14f64c6c6a298 Mon Sep 17 00:00:00 2001 From: SachinVin Date: Tue, 7 Apr 2020 22:11:16 +0530 Subject: [PATCH] backend/A64: Add Step --- src/backend/A64/a32_interface.cpp | 37 ++++++++++++++++++++++++------- src/backend/A64/block_of_code.cpp | 15 +++++++++++++ src/backend/A64/block_of_code.h | 5 ++++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/backend/A64/a32_interface.cpp b/src/backend/A64/a32_interface.cpp index 2fe93de1..531bd7b8 100644 --- a/src/backend/A64/a32_interface.cpp +++ b/src/backend/A64/a32_interface.cpp @@ -42,7 +42,7 @@ static RunCodeCallbacks GenRunCodeCallbacks(const A32::UserConfig& config, CodeP struct Jit::Impl { Impl(Jit* jit, A32::UserConfig config) - : block_of_code(GenRunCodeCallbacks(config, &GetCurrentBlock, this), JitStateInfo{jit_state}) + : block_of_code(GenRunCodeCallbacks(config, &GetCurrentBlockThunk, this), JitStateInfo{jit_state}) , emitter(block_of_code, config, jit) , config(std::move(config)) , jit_interface(jit) @@ -74,6 +74,10 @@ struct Jit::Impl { block_of_code.RunCode(&jit_state, current_codeptr); } + void Step() { + block_of_code.StepCode(&jit_state, GetCurrentSingleStep()); + } + std::string Disassemble(const IR::LocationDescriptor& descriptor) { auto block = GetBasicBlock(descriptor); std::string result = fmt::format("address: {}\nsize: {} bytes\n", block.entrypoint, block.size); @@ -122,16 +126,21 @@ struct Jit::Impl { private: Jit* jit_interface; - static CodePtr GetCurrentBlock(void* this_voidptr) { + static CodePtr GetCurrentBlockThunk(void* this_voidptr) { Jit::Impl& this_ = *static_cast(this_voidptr); - A32JitState& jit_state = this_.jit_state; + return this_.GetCurrentBlock(); + } - u32 pc = jit_state.Reg[15]; - A32::PSR cpsr{jit_state.Cpsr()}; - A32::FPSCR fpscr{jit_state.upper_location_descriptor}; - A32::LocationDescriptor descriptor{pc, cpsr, fpscr}; + IR::LocationDescriptor GetCurrentLocation() const { + return IR::LocationDescriptor{jit_state.GetUniqueHash()}; + } - return this_.GetBasicBlock(descriptor).entrypoint; + CodePtr GetCurrentBlock() { + return GetBasicBlock(GetCurrentLocation()).entrypoint; + } + + CodePtr GetCurrentSingleStep() { + return GetBasicBlock(A32::LocationDescriptor{GetCurrentLocation()}.SetSingleStepping(true)).entrypoint; } A32EmitA64::BlockDescriptor GetBasicBlock(IR::LocationDescriptor descriptor) { @@ -173,6 +182,18 @@ void Jit::Run() { impl->PerformCacheInvalidation(); } +void Jit::Step() { + ASSERT(!is_executing); + is_executing = true; + SCOPE_EXIT { this->is_executing = false; }; + + impl->jit_state.halt_requested = true; + + impl->Step(); + + impl->PerformCacheInvalidation(); +} + void Jit::ClearCache() { impl->invalidate_entire_cache = true; impl->RequestCacheInvalidation(); diff --git a/src/backend/A64/block_of_code.cpp b/src/backend/A64/block_of_code.cpp index 15f54923..e0bb92e0 100644 --- a/src/backend/A64/block_of_code.cpp +++ b/src/backend/A64/block_of_code.cpp @@ -127,6 +127,8 @@ void BlockOfCode::RunCode(void* jit_state, CodePtr code_ptr) const { run_code(jit_state, code_ptr); } +void BlockOfCode::StepCode(void* jit_state, CodePtr code_ptr) const { + step_code(jit_state, code_ptr); } void BlockOfCode::ReturnFromRunCode(bool fpscr_already_exited) { @@ -166,6 +168,19 @@ void BlockOfCode::GenRunCode() { SwitchFpscrOnEntry(); BR(Arm64Gen::X25); + AlignCode16(); + step_code = (RunCodeFuncType) GetWritableCodePtr(); + + ABI_PushCalleeSaveRegistersAndAdjustStack(*this); + + MOV(Arm64Gen::X28, ABI_PARAM1); + + MOVI2R(Arm64Gen::X26, 1); + STR(Arm64Gen::INDEX_UNSIGNED, Arm64Gen::X26, Arm64Gen::X28, jsi.offsetof_cycles_to_run); + + SwitchFpscrOnEntry(); + BR(ABI_PARAM2); + enter_fpscr_then_loop = GetCodePtr(); SwitchFpscrOnEntry(); loop = GetCodePtr(); diff --git a/src/backend/A64/block_of_code.h b/src/backend/A64/block_of_code.h index 171973f8..44f5c9a0 100644 --- a/src/backend/A64/block_of_code.h +++ b/src/backend/A64/block_of_code.h @@ -48,6 +48,8 @@ public: /// Runs emulated code from code_ptr. void RunCode(void* jit_state, CodePtr code_ptr) const; + /// Runs emulated code from code_ptr for a single cycle. + void StepCode(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,6 +135,7 @@ private: using RunCodeFuncType = void(*)(void*, CodePtr); RunCodeFuncType run_code = nullptr; + RunCodeFuncType step_code = nullptr; static constexpr size_t FPSCR_ALREADY_EXITED = 1 << 0; static constexpr size_t FORCE_RETURN = 1 << 1; std::array return_from_run_code; @@ -141,4 +144,4 @@ private: //Xbyak::util::Cpu cpu_info; }; -} // namespace Dynarmic::BackendX64 +} // namespace Dynarmic::BackendA64