mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-07 06:58:15 +01:00
A64: Add Step
Allow for stepping instruction-by-instruction
This commit is contained in:
parent
53e23efcef
commit
f69c77391e
11 changed files with 108 additions and 32 deletions
|
|
@ -291,11 +291,11 @@ void A64EmitX64::GenTerminalHandlers() {
|
|||
// This calculation has to match up with A64::LocationDescriptor::UniqueHash
|
||||
// TODO: Optimization is available here based on known state of fpcr.
|
||||
code.mov(rbp, qword[r15 + offsetof(A64JitState, pc)]);
|
||||
code.mov(rcx, A64::LocationDescriptor::PC_MASK);
|
||||
code.mov(rcx, A64::LocationDescriptor::pc_mask);
|
||||
code.and_(rcx, rbp);
|
||||
code.mov(ebx, dword[r15 + offsetof(A64JitState, fpcr)]);
|
||||
code.and_(ebx, A64::LocationDescriptor::FPCR_MASK);
|
||||
code.shl(ebx, 37);
|
||||
code.and_(ebx, A64::LocationDescriptor::fpcr_mask);
|
||||
code.shl(ebx, A64::LocationDescriptor::fpcr_shift);
|
||||
code.or_(rbx, rcx);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,13 +54,28 @@ public:
|
|||
|
||||
// TODO: Check code alignment
|
||||
|
||||
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::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<CodePtr>(jit_state.rsb_codeptrs[new_rsb_ptr]));
|
||||
} else {
|
||||
block_of_code.RunCode(&jit_state);
|
||||
}
|
||||
const CodePtr current_code_ptr = [this]{
|
||||
// RSB optimization
|
||||
const u32 new_rsb_ptr = (jit_state.rsb_ptr - 1) & A64JitState::RSBPtrMask;
|
||||
if (jit_state.GetUniqueHash() == jit_state.rsb_location_descriptors[new_rsb_ptr]) {
|
||||
jit_state.rsb_ptr = new_rsb_ptr;
|
||||
return reinterpret_cast<CodePtr>(jit_state.rsb_codeptrs[new_rsb_ptr]);
|
||||
}
|
||||
|
||||
return GetCurrentBlock();
|
||||
}();
|
||||
block_of_code.RunCodeFrom(&jit_state, current_code_ptr);
|
||||
|
||||
PerformRequestedCacheInvalidation();
|
||||
}
|
||||
|
||||
void Step() {
|
||||
ASSERT(!is_executing);
|
||||
is_executing = true;
|
||||
SCOPE_EXIT { this->is_executing = false; };
|
||||
jit_state.halt_requested = true;
|
||||
|
||||
block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
|
||||
|
||||
PerformRequestedCacheInvalidation();
|
||||
}
|
||||
|
|
@ -185,9 +200,19 @@ private:
|
|||
return this_->GetCurrentBlock();
|
||||
}
|
||||
|
||||
CodePtr GetCurrentBlock() {
|
||||
IR::LocationDescriptor current_location{jit_state.GetUniqueHash()};
|
||||
IR::LocationDescriptor GetCurrentLocation() const {
|
||||
return IR::LocationDescriptor{jit_state.GetUniqueHash()};
|
||||
}
|
||||
|
||||
CodePtr GetCurrentBlock() {
|
||||
return GetBlock(GetCurrentLocation());
|
||||
}
|
||||
|
||||
CodePtr GetCurrentSingleStep() {
|
||||
return GetBlock(A64::LocationDescriptor{GetCurrentLocation()}.SetSingleStepping(true));
|
||||
}
|
||||
|
||||
CodePtr GetBlock(IR::LocationDescriptor current_location) {
|
||||
if (auto block = emitter.GetBasicBlock(current_location))
|
||||
return block->entrypoint;
|
||||
|
||||
|
|
@ -256,6 +281,10 @@ void Jit::Run() {
|
|||
impl->Run();
|
||||
}
|
||||
|
||||
void Jit::Step() {
|
||||
impl->Step();
|
||||
}
|
||||
|
||||
void Jit::ClearCache() {
|
||||
impl->ClearCache();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@
|
|||
|
||||
namespace Dynarmic::BackendX64 {
|
||||
|
||||
u64 A64JitState::GetUniqueHash() const noexcept {
|
||||
const u64 fpcr_u64 = static_cast<u64>(fpcr & A64::LocationDescriptor::FPCR_MASK) << 37;
|
||||
const u64 pc_u64 = pc & A64::LocationDescriptor::PC_MASK;
|
||||
return pc_u64 | fpcr_u64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparing MXCSR and FPCR
|
||||
* ========================
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <xbyak.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/A64/location_descriptor.h"
|
||||
|
||||
namespace Dynarmic::BackendX64 {
|
||||
|
||||
|
|
@ -79,7 +80,11 @@ struct A64JitState {
|
|||
void SetFpcr(u32 value);
|
||||
void SetFpsr(u32 value);
|
||||
|
||||
u64 GetUniqueHash() const noexcept;
|
||||
u64 GetUniqueHash() const noexcept {
|
||||
const u64 fpcr_u64 = static_cast<u64>(fpcr & A64::LocationDescriptor::fpcr_mask) << A64::LocationDescriptor::fpcr_shift;
|
||||
const u64 pc_u64 = pc & A64::LocationDescriptor::pc_mask;
|
||||
return pc_u64 | fpcr_u64;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
|||
|
|
@ -142,6 +142,10 @@ void BlockOfCode::RunCodeFrom(void* jit_state, CodePtr code_ptr) const {
|
|||
run_code_from(jit_state, code_ptr);
|
||||
}
|
||||
|
||||
void BlockOfCode::StepCode(void* jit_state, CodePtr code_ptr) const {
|
||||
step_code(jit_state, code_ptr);
|
||||
}
|
||||
|
||||
void BlockOfCode::ReturnFromRunCode(bool mxcsr_already_exited) {
|
||||
size_t index = 0;
|
||||
if (mxcsr_already_exited)
|
||||
|
|
@ -174,6 +178,19 @@ void BlockOfCode::GenRunCode() {
|
|||
SwitchMxcsrOnEntry();
|
||||
jmp(r14);
|
||||
|
||||
align();
|
||||
step_code = getCurr<RunCodeFromFuncType>();
|
||||
|
||||
ABI_PushCalleeSaveRegistersAndAdjustStack(*this);
|
||||
|
||||
mov(r15, ABI_PARAM1);
|
||||
|
||||
mov(qword[r15 + jsi.offsetof_cycles_to_run], 1);
|
||||
mov(qword[r15 + jsi.offsetof_cycles_remaining], 1);
|
||||
|
||||
SwitchMxcsrOnEntry();
|
||||
jmp(ABI_PARAM2);
|
||||
|
||||
align();
|
||||
run_code = getCurr<RunCodeFuncType>();
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public:
|
|||
void RunCode(void* jit_state) const;
|
||||
/// Runs emulated code from code_ptr.
|
||||
void RunCodeFrom(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 mxcsr_already_exited = false);
|
||||
/// Code emitter: Returns to dispatcher, forces return to host
|
||||
|
|
@ -158,6 +160,7 @@ private:
|
|||
using RunCodeFuncType = void(*)(void*);
|
||||
using RunCodeFromFuncType = void(*)(void*, CodePtr);
|
||||
RunCodeFuncType run_code = nullptr;
|
||||
RunCodeFromFuncType step_code = nullptr;
|
||||
RunCodeFromFuncType run_code_from = nullptr;
|
||||
static constexpr size_t MXCSR_ALREADY_EXITED = 1 << 0;
|
||||
static constexpr size_t FORCE_RETURN = 1 << 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue