backend/arm64: Implement Step
This commit is contained in:
parent
cf47ab3b42
commit
d90e0db502
4 changed files with 33 additions and 6 deletions
|
@ -166,6 +166,27 @@ void A32AddressSpace::EmitPrelude() {
|
||||||
|
|
||||||
code.BR(X0);
|
code.BR(X0);
|
||||||
|
|
||||||
|
prelude_info.step_code = code.ptr<PreludeInfo::RunCodeFuncType>();
|
||||||
|
ABI_PushRegisters(code, ABI_CALLEE_SAVE | (1 << 30), sizeof(StackLayout));
|
||||||
|
|
||||||
|
code.MOV(Xstate, X1);
|
||||||
|
code.MOV(Xhalt, X2);
|
||||||
|
|
||||||
|
code.LDR(Wscratch0, Xstate, offsetof(A32JitState, upper_location_descriptor));
|
||||||
|
code.AND(Wscratch0, Wscratch0, 0xffff0000);
|
||||||
|
code.MRS(Xscratch1, oaknut::SystemReg::FPCR);
|
||||||
|
code.STR(Wscratch1, SP, offsetof(StackLayout, save_host_fpcr));
|
||||||
|
code.MSR(oaknut::SystemReg::FPCR, Xscratch0);
|
||||||
|
|
||||||
|
oaknut::Label step_hr_loop;
|
||||||
|
code.l(step_hr_loop);
|
||||||
|
code.LDAXR(Wscratch0, Xhalt);
|
||||||
|
code.ORR(Wscratch0, Wscratch0, static_cast<u32>(HaltReason::Step));
|
||||||
|
code.STLXR(Wscratch1, Wscratch0, Xhalt);
|
||||||
|
code.CBNZ(Wscratch1, step_hr_loop);
|
||||||
|
|
||||||
|
code.BR(X0);
|
||||||
|
|
||||||
prelude_info.return_from_run_code = code.ptr<void*>();
|
prelude_info.return_from_run_code = code.ptr<void*>();
|
||||||
|
|
||||||
code.LDR(Wscratch0, SP, offsetof(StackLayout, save_host_fpcr));
|
code.LDR(Wscratch0, SP, offsetof(StackLayout, save_host_fpcr));
|
||||||
|
|
|
@ -19,6 +19,12 @@ public:
|
||||||
const auto entry_point = process.GetOrEmit(location_descriptor);
|
const auto entry_point = process.GetOrEmit(location_descriptor);
|
||||||
return process.prelude_info.run_code(entry_point, &thread_ctx, halt_reason);
|
return process.prelude_info.run_code(entry_point, &thread_ctx, halt_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HaltReason Step(A32AddressSpace& process, A32JitState& thread_ctx, volatile u32* halt_reason) {
|
||||||
|
const auto location_descriptor = A32::LocationDescriptor{thread_ctx.GetLocationDescriptor()}.SetSingleStepping(true);
|
||||||
|
const auto entry_point = process.GetOrEmit(location_descriptor);
|
||||||
|
return process.prelude_info.step_code(entry_point, &thread_ctx, halt_reason);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
|
@ -79,11 +79,11 @@ struct Jit::Impl final {
|
||||||
jit_interface->is_executing = false;
|
jit_interface->is_executing = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_FALSE("Unimplemented");
|
HaltReason hr = core.Step(current_address_space, current_state, &halt_reason);
|
||||||
|
|
||||||
PerformRequestedCacheInvalidation();
|
PerformRequestedCacheInvalidation();
|
||||||
|
|
||||||
return HaltReason{};
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearCache() {
|
void ClearCache() {
|
||||||
|
|
|
@ -61,8 +61,8 @@ void EmitSetUpperLocationDescriptor(oaknut::CodeGenerator& code, EmitContext& ct
|
||||||
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location, bool) {
|
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location, bool) {
|
||||||
EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location);
|
EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location);
|
||||||
|
|
||||||
code.MOV(Xscratch0, terminal.next.Value());
|
code.MOV(Wscratch0, A32::LocationDescriptor{terminal.next}.PC());
|
||||||
code.STUR(Xscratch0, Xstate, offsetof(A32JitState, regs) + sizeof(u32) * 15);
|
code.STR(Wscratch0, Xstate, offsetof(A32JitState, regs) + sizeof(u32) * 15);
|
||||||
EmitRelocation(code, ctx, LinkTarget::ReturnFromRunCode);
|
EmitRelocation(code, ctx, LinkTarget::ReturnFromRunCode);
|
||||||
|
|
||||||
// TODO: Implement LinkBlock optimization
|
// TODO: Implement LinkBlock optimization
|
||||||
|
@ -71,8 +71,8 @@ void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::Li
|
||||||
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location, bool) {
|
void EmitA32Terminal(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location, bool) {
|
||||||
EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location);
|
EmitSetUpperLocationDescriptor(code, ctx, terminal.next, initial_location);
|
||||||
|
|
||||||
code.MOV(Xscratch0, terminal.next.Value());
|
code.MOV(Wscratch0, A32::LocationDescriptor{terminal.next}.PC());
|
||||||
code.STUR(Xscratch0, Xstate, offsetof(A32JitState, regs) + sizeof(u32) * 15);
|
code.STR(Wscratch0, Xstate, offsetof(A32JitState, regs) + sizeof(u32) * 15);
|
||||||
EmitRelocation(code, ctx, LinkTarget::ReturnFromRunCode);
|
EmitRelocation(code, ctx, LinkTarget::ReturnFromRunCode);
|
||||||
|
|
||||||
// TODO: Implement LinkBlockFast optimization
|
// TODO: Implement LinkBlockFast optimization
|
||||||
|
|
Loading…
Reference in a new issue