diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9aabd7e3a..6bc3a763b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -97,6 +97,8 @@ set(HEADERS arm/dyncom/arm_dyncom_run.h arm/dyncom/arm_dyncom_thumb.h arm/interpreter/arm_interpreter.h + arm/jit_common/jit_util.h + arm/jit_common/jit_base.h arm/skyeye_common/arm_regformat.h arm/skyeye_common/armcpu.h arm/skyeye_common/armdefs.h diff --git a/src/core/arm/jit_common/jit_base.cpp b/src/core/arm/jit_common/jit_base.cpp new file mode 100644 index 000000000..81409d697 --- /dev/null +++ b/src/core/arm/jit_common/jit_base.cpp @@ -0,0 +1,118 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/arm/skyeye_common/armcpu.h" +#include "core/arm/skyeye_common/armemu.h" +#include "core/arm/skyeye_common/vfp/vfp.h" + +#include "core/arm/jit_common/jit_base.h" + +#include "core/core.h" +#include "core/core_timing.h" + +const static cpu_config_t s_arm11_cpu_info = { + "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE +}; + +JitBase::JitBase() { + state = std::unique_ptr(new ARMul_State); + + ARMul_EmulateInit(); + memset(state.get(), 0, sizeof(ARMul_State)); + + ARMul_NewState((ARMul_State*)state.get()); + + state->abort_model = 0; + state->cpu = (cpu_config_t*)&s_arm11_cpu_info; + state->bigendSig = LOW; + + ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); + state->lateabtSig = LOW; + + // Reset the core to initial state + ARMul_CoProInit(state.get()); + ARMul_Reset(state.get()); + state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext + state->Emulate = 3; + + state->pc = state->Reg[15] = 0x00000000; + state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack + state->servaddr = 0xFFFF0000; + state->NirqSig = HIGH; + + VFPInit(state.get()); // Initialize the VFP + + ARMul_EmulateInit(); +} + +void JitBase::SetPC(u32 pc) { + state->pc = state->Reg[15] = pc; +} + +u32 JitBase::GetPC() const { + return state->Reg[15]; +} + +u32 JitBase::GetReg(int index) const { + return state->Reg[index]; +} + +void JitBase::SetReg(int index, u32 value) { + state->Reg[index] = value; +} + +u32 JitBase::GetCPSR() const { + return state->Cpsr; +} + +void JitBase::SetCPSR(u32 cpsr) { + state->Cpsr = cpsr; +} + +u64 JitBase::GetTicks() const { + // TODO(Subv): Remove ARM_DynCom::GetTicks() and use CoreTiming::GetTicks() directly once ARMemu is gone + return CoreTiming::GetTicks(); +} + +void JitBase::AddTicks(u64 ticks) { + down_count -= ticks; + if (down_count < 0) + CoreTiming::Advance(); +} + +void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { + memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); + memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); + + ctx.sp = state->Reg[13]; + ctx.lr = state->Reg[14]; + ctx.pc = state->Reg[15]; + ctx.cpsr = state->Cpsr; + + ctx.fpscr = state->VFP[1]; + ctx.fpexc = state->VFP[2]; + + ctx.reg_15 = state->Reg[15]; + ctx.mode = state->NextInstr; +} + +void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) { + memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); + memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); + + state->Reg[13] = ctx.sp; + state->Reg[14] = ctx.lr; + state->pc = ctx.pc; + state->Cpsr = ctx.cpsr; + + state->VFP[1] = ctx.fpscr; + state->VFP[2] = ctx.fpexc; + + state->Reg[15] = ctx.reg_15; + state->NextInstr = ctx.mode; +} + +void ARM_DynCom::PrepareReschedule() { + state->NumInstrsToExecute = 0; +} diff --git a/src/core/arm/jit_common/jit_base.h b/src/core/arm/jit_common/jit_base.h new file mode 100644 index 000000000..9c6d72fef --- /dev/null +++ b/src/core/arm/jit_common/jit_base.h @@ -0,0 +1,43 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/x64_abi.h" +#include "common/x64_emitter.h" +#include "jit_util.h" +#include "core/arm/arm_interface.h" +#include "core/arm/skyeye_common/armdefs.h" + +#define RSCRATCH RAX +#define RSCRATCH2 RDX + +class JitBase : virtual public ARM_Interface +{ +protected: + struct JitState + { + u32 compilerPC; + u32 blockStart; + }; +public: + JitState js; + void SetPC(u32 pc) override; + u32 GetPC() const override; + void SetReg(int index, u32 value) override; + u32 GetReg(int index) const override; + void SetCPSR(u32 pc) override; + u32 GetCPSR() const override; + u64 GetTicks() const override; + void AddTicks(u64 ticks) override; + void SaveContext(Core::ThreadContext& ctx) override; + void LoadContext(const Core::ThreadContext& ctx) override; + void PrepareReschedule() override; +private: + std::unique_ptr state; +}; + +class Jitx64Base : public JitBase, X64CodeBlock +{ +}; diff --git a/src/core/arm/jit_common/jit_util.h b/src/core/arm/jit_common/jit_util.h new file mode 100644 index 000000000..1aa5f273a --- /dev/null +++ b/src/core/arm/jit_common/jit_util.h @@ -0,0 +1,20 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/x64_emitter.h" + +class FarCodeCache : public Gen::X64CodeBlock +{ +private: + bool m_enabled = false; +public: + bool Enabled() { return m_enabled; } + void Init() { AllocCodeSpace(size); m_enabled = true; } + void Shutdown() { FreeCodeSpace(); m_enabled = false; } +}; + +static const int CODE_SIZE = 1024 * 1024 * 32; +static const int FARCODE_SIZE = 1024 * 1024 * 8; \ No newline at end of file