mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-11-03 23:28:48 +00:00 
			
		
		
		
	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