backend/A64: Add Step

This commit is contained in:
SachinVin 2020-04-07 22:11:16 +05:30 committed by xperia64
parent f9c841b66d
commit 36c28648d7
3 changed files with 48 additions and 9 deletions

View File

@ -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<Jit::Impl*>(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();

View File

@ -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();

View File

@ -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<const void*, 4> return_from_run_code;
@ -141,4 +144,4 @@ private:
//Xbyak::util::Cpu cpu_info;
};
} // namespace Dynarmic::BackendX64
} // namespace Dynarmic::BackendA64