core/arm: Backend-specific context implementations

This commit is contained in:
MerryMage 2017-12-12 19:12:03 +00:00
parent 7d5c3b00a8
commit fb2d34997e
9 changed files with 212 additions and 73 deletions

View file

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

View file

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