core/arm: Backend-specific context implementations
This commit is contained in:
parent
7d5c3b00a8
commit
fb2d34997e
9 changed files with 212 additions and 73 deletions
|
@ -3,6 +3,7 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include <dynarmic/context.h>
|
||||
#include <dynarmic/dynarmic.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/microprofile.h"
|
||||
|
@ -14,6 +15,59 @@
|
|||
#include "core/hle/kernel/svc.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
class DynarmicThreadContext final : public ARM_Interface::ThreadContext {
|
||||
public:
|
||||
DynarmicThreadContext() {
|
||||
Reset();
|
||||
}
|
||||
~DynarmicThreadContext() override = default;
|
||||
|
||||
void Reset() override {
|
||||
ctx.Regs() = {};
|
||||
ctx.SetCpsr(0);
|
||||
ctx.ExtRegs() = {};
|
||||
ctx.SetFpscr(0);
|
||||
fpexc = 0;
|
||||
}
|
||||
|
||||
u32 GetCpuRegister(size_t index) const override {
|
||||
return ctx.Regs()[index];
|
||||
}
|
||||
void SetCpuRegister(size_t index, u32 value) override {
|
||||
ctx.Regs()[index] = value;
|
||||
}
|
||||
u32 GetCpsr() const override {
|
||||
return ctx.Cpsr();
|
||||
}
|
||||
void SetCpsr(u32 value) override {
|
||||
ctx.SetCpsr(value);
|
||||
}
|
||||
u32 GetFpuRegister(size_t index) const override {
|
||||
return ctx.ExtRegs()[index];
|
||||
}
|
||||
void SetFpuRegister(size_t index, u32 value) override {
|
||||
ctx.ExtRegs()[index] = value;
|
||||
}
|
||||
u32 GetFpscr() const override {
|
||||
return ctx.Fpscr();
|
||||
}
|
||||
void SetFpscr(u32 value) override {
|
||||
ctx.SetFpscr(value);
|
||||
}
|
||||
u32 GetFpexc() const override {
|
||||
return fpexc;
|
||||
}
|
||||
void SetFpexc(u32 value) override {
|
||||
fpexc = value;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ARM_Dynarmic;
|
||||
|
||||
Dynarmic::Context ctx;
|
||||
u32 fpexc;
|
||||
};
|
||||
|
||||
static void InterpreterFallback(u32 pc, Dynarmic::Jit* jit, void* user_arg) {
|
||||
ARMul_State* state = static_cast<ARMul_State*>(user_arg);
|
||||
|
||||
|
@ -148,30 +202,24 @@ void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) {
|
|||
interpreter_state->CP15[reg] = value;
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
|
||||
memcpy(ctx.cpu_registers, jit->Regs().data(), sizeof(ctx.cpu_registers));
|
||||
memcpy(ctx.fpu_registers, jit->ExtRegs().data(), sizeof(ctx.fpu_registers));
|
||||
|
||||
ctx.sp = jit->Regs()[13];
|
||||
ctx.lr = jit->Regs()[14];
|
||||
ctx.pc = jit->Regs()[15];
|
||||
ctx.cpsr = jit->Cpsr();
|
||||
|
||||
ctx.fpscr = jit->Fpscr();
|
||||
ctx.fpexc = interpreter_state->VFP[VFP_FPEXC];
|
||||
std::unique_ptr<ARM_Interface::ThreadContext> ARM_Dynarmic::NewContext() const {
|
||||
return std::make_unique<DynarmicThreadContext>();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
|
||||
memcpy(jit->Regs().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
|
||||
memcpy(jit->ExtRegs().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
|
||||
void ARM_Dynarmic::SaveContext(const std::unique_ptr<ThreadContext>& arg) {
|
||||
DynarmicThreadContext* ctx = dynamic_cast<DynarmicThreadContext*>(arg.get());
|
||||
ASSERT(ctx);
|
||||
|
||||
jit->Regs()[13] = ctx.sp;
|
||||
jit->Regs()[14] = ctx.lr;
|
||||
jit->Regs()[15] = ctx.pc;
|
||||
jit->SetCpsr(ctx.cpsr);
|
||||
jit->SaveContext(ctx->ctx);
|
||||
ctx->fpexc = interpreter_state->VFP[VFP_FPEXC];
|
||||
}
|
||||
|
||||
jit->SetFpscr(ctx.fpscr);
|
||||
interpreter_state->VFP[VFP_FPEXC] = ctx.fpexc;
|
||||
void ARM_Dynarmic::LoadContext(const std::unique_ptr<ThreadContext>& arg) {
|
||||
const DynarmicThreadContext* ctx = dynamic_cast<DynarmicThreadContext*>(arg.get());
|
||||
ASSERT(ctx);
|
||||
|
||||
jit->LoadContext(ctx->ctx);
|
||||
interpreter_state->VFP[VFP_FPEXC] = ctx->fpexc;
|
||||
}
|
||||
|
||||
void ARM_Dynarmic::PrepareReschedule() {
|
||||
|
|
|
@ -35,8 +35,9 @@ public:
|
|||
u32 GetCP15Register(CP15Register reg) override;
|
||||
void SetCP15Register(CP15Register reg, u32 value) override;
|
||||
|
||||
void SaveContext(ThreadContext& ctx) override;
|
||||
void LoadContext(const ThreadContext& ctx) override;
|
||||
std::unique_ptr<ThreadContext> NewContext() const override;
|
||||
void SaveContext(const std::unique_ptr<ThreadContext>& arg) override;
|
||||
void LoadContext(const std::unique_ptr<ThreadContext>& arg) override;
|
||||
|
||||
void PrepareReschedule() override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue