mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-23 19:20:09 +00:00
Unfinished JIT
Committing because I'm not sure what else to do about these remaining errors. Inheritance problems are kicking my ass.
This commit is contained in:
parent
689b1cd810
commit
a334179275
@ -1,5 +1,5 @@
|
|||||||
// Copyright 2013 Dolphin Emulator Project
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -1,78 +1,89 @@
|
|||||||
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
|
||||||
// Detect the cpu, so we'll know which optimizations to use
|
// Detect the CPU, so we'll know which optimizations to use
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
enum CPUVendor
|
enum CPUVendor
|
||||||
{
|
{
|
||||||
VENDOR_INTEL = 0,
|
VENDOR_INTEL = 0,
|
||||||
VENDOR_AMD = 1,
|
VENDOR_AMD = 1,
|
||||||
VENDOR_ARM = 2,
|
VENDOR_ARM = 2,
|
||||||
VENDOR_OTHER = 3,
|
VENDOR_OTHER = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPUInfo
|
struct CPUInfo
|
||||||
{
|
{
|
||||||
CPUVendor vendor;
|
CPUVendor vendor;
|
||||||
|
|
||||||
char cpu_string[0x21];
|
char cpu_string[0x41];
|
||||||
char brand_string[0x41];
|
char brand_string[0x21];
|
||||||
bool OS64bit;
|
bool OS64bit;
|
||||||
bool CPU64bit;
|
bool CPU64bit;
|
||||||
bool Mode64bit;
|
bool Mode64bit;
|
||||||
|
|
||||||
bool HTT;
|
bool HTT;
|
||||||
int num_cores;
|
int num_cores;
|
||||||
int logical_cpu_count;
|
int logical_cpu_count;
|
||||||
|
|
||||||
bool bSSE;
|
bool bSSE;
|
||||||
bool bSSE2;
|
bool bSSE2;
|
||||||
bool bSSE3;
|
bool bSSE3;
|
||||||
bool bSSSE3;
|
bool bSSSE3;
|
||||||
bool bPOPCNT;
|
bool bPOPCNT;
|
||||||
bool bSSE4_1;
|
bool bSSE4_1;
|
||||||
bool bSSE4_2;
|
bool bSSE4_2;
|
||||||
bool bLZCNT;
|
bool bLZCNT;
|
||||||
bool bSSE4A;
|
bool bSSE4A;
|
||||||
bool bAVX;
|
bool bAVX;
|
||||||
bool bAES;
|
bool bAVX2;
|
||||||
bool bLAHFSAHF64;
|
bool bBMI1;
|
||||||
bool bLongMode;
|
bool bBMI2;
|
||||||
|
bool bFMA;
|
||||||
|
bool bAES;
|
||||||
|
// FXSAVE/FXRSTOR
|
||||||
|
bool bFXSR;
|
||||||
|
bool bMOVBE;
|
||||||
|
// This flag indicates that the hardware supports some mode
|
||||||
|
// in which denormal inputs _and_ outputs are automatically set to (signed) zero.
|
||||||
|
bool bFlushToZero;
|
||||||
|
bool bLAHFSAHF64;
|
||||||
|
bool bLongMode;
|
||||||
|
bool bAtom;
|
||||||
|
|
||||||
// ARM specific CPUInfo
|
// ARM specific CPUInfo
|
||||||
bool bSwp;
|
bool bSwp;
|
||||||
bool bHalf;
|
bool bHalf;
|
||||||
bool bThumb;
|
bool bThumb;
|
||||||
bool bFastMult;
|
bool bFastMult;
|
||||||
bool bVFP;
|
bool bVFP;
|
||||||
bool bEDSP;
|
bool bEDSP;
|
||||||
bool bThumbEE;
|
bool bThumbEE;
|
||||||
bool bNEON;
|
bool bNEON;
|
||||||
bool bVFPv3;
|
bool bVFPv3;
|
||||||
bool bTLS;
|
bool bTLS;
|
||||||
bool bVFPv4;
|
bool bVFPv4;
|
||||||
bool bIDIVa;
|
bool bIDIVa;
|
||||||
bool bIDIVt;
|
bool bIDIVt;
|
||||||
bool bArmV7; // enable MOVT, MOVW etc
|
bool bArmV7; // enable MOVT, MOVW etc
|
||||||
|
|
||||||
// ARMv8 specific
|
// ARMv8 specific
|
||||||
bool bFP;
|
bool bFP;
|
||||||
bool bASIMD;
|
bool bASIMD;
|
||||||
|
|
||||||
// Call Detect()
|
// Call Detect()
|
||||||
explicit CPUInfo();
|
explicit CPUInfo();
|
||||||
|
|
||||||
// Turn the cpu info into a string we can show
|
// Turn the CPU info into a string we can show
|
||||||
std::string Summarize();
|
std::string Summarize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Detects the various cpu features
|
// Detects the various CPU features
|
||||||
void Detect();
|
void Detect();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CPUInfo cpu_info;
|
extern CPUInfo cpu_info;
|
||||||
|
@ -47,6 +47,7 @@ enum class Class : ClassType {
|
|||||||
Debug_Emulated, ///< Debug messages from the emulated programs
|
Debug_Emulated, ///< Debug messages from the emulated programs
|
||||||
Debug_GPU, ///< GPU debugging tools
|
Debug_GPU, ///< GPU debugging tools
|
||||||
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
|
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
|
||||||
|
DYNA_REC, ///< Dolphin x64 emitter
|
||||||
Kernel, ///< The HLE implementation of the CTR kernel
|
Kernel, ///< The HLE implementation of the CTR kernel
|
||||||
Kernel_SVC, ///< Kernel system calls
|
Kernel_SVC, ///< Kernel system calls
|
||||||
Service, ///< HLE implementation of system services. Each major service
|
Service, ///< HLE implementation of system services. Each major service
|
||||||
@ -105,4 +106,5 @@ void LogMessage(Class log_class, Level log_level,
|
|||||||
#define LOG_INFO( log_class, ...) LOG_GENERIC(log_class, Info, __VA_ARGS__)
|
#define LOG_INFO( log_class, ...) LOG_GENERIC(log_class, Info, __VA_ARGS__)
|
||||||
#define LOG_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __VA_ARGS__)
|
#define LOG_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __VA_ARGS__)
|
||||||
#define LOG_ERROR( log_class, ...) LOG_GENERIC(log_class, Error, __VA_ARGS__)
|
#define LOG_ERROR( log_class, ...) LOG_GENERIC(log_class, Error, __VA_ARGS__)
|
||||||
|
#define ERROR_LOG LOG_ERROR
|
||||||
#define LOG_CRITICAL(log_class, ...) LOG_GENERIC(log_class, Critical, __VA_ARGS__)
|
#define LOG_CRITICAL(log_class, ...) LOG_GENERIC(log_class, Critical, __VA_ARGS__)
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "Common/bit_set.h"
|
#include "common/bit_set.h"
|
||||||
#include "Common/code_block.h"
|
#include "common/code_block.h"
|
||||||
#include "Common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Gen
|
namespace Gen
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,8 @@ set(SRCS
|
|||||||
arm/interpreter/armsupp.cpp
|
arm/interpreter/armsupp.cpp
|
||||||
arm/interpreter/armvirt.cpp
|
arm/interpreter/armvirt.cpp
|
||||||
arm/interpreter/thumbemu.cpp
|
arm/interpreter/thumbemu.cpp
|
||||||
|
arm/jit_common/jit_base.cpp
|
||||||
|
arm/jit_x64/jit.cpp
|
||||||
arm/skyeye_common/vfp/vfp.cpp
|
arm/skyeye_common/vfp/vfp.cpp
|
||||||
arm/skyeye_common/vfp/vfpdouble.cpp
|
arm/skyeye_common/vfp/vfpdouble.cpp
|
||||||
arm/skyeye_common/vfp/vfpinstr.cpp
|
arm/skyeye_common/vfp/vfpinstr.cpp
|
||||||
@ -99,6 +101,7 @@ set(HEADERS
|
|||||||
arm/interpreter/arm_interpreter.h
|
arm/interpreter/arm_interpreter.h
|
||||||
arm/jit_common/jit_util.h
|
arm/jit_common/jit_util.h
|
||||||
arm/jit_common/jit_base.h
|
arm/jit_common/jit_base.h
|
||||||
|
arm/jit_x64/jit.h
|
||||||
arm/skyeye_common/arm_regformat.h
|
arm/skyeye_common/arm_regformat.h
|
||||||
arm/skyeye_common/armcpu.h
|
arm/skyeye_common/armcpu.h
|
||||||
arm/skyeye_common/armdefs.h
|
arm/skyeye_common/armdefs.h
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
// Copyright 2015 Citra Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/arm/jit_common/jit_base.h"
|
||||||
|
|
||||||
#include "core/arm/skyeye_common/armcpu.h"
|
#include "core/arm/skyeye_common/armcpu.h"
|
||||||
#include "core/arm/skyeye_common/armemu.h"
|
#include "core/arm/skyeye_common/armemu.h"
|
||||||
#include "core/arm/skyeye_common/vfp/vfp.h"
|
#include "core/arm/skyeye_common/vfp/vfp.h"
|
||||||
|
#include "core/arm/skyeye_common/armdefs.h"
|
||||||
#include "core/arm/jit_common/jit_base.h"
|
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
@ -71,7 +72,7 @@ void JitBase::SetCPSR(u32 cpsr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 JitBase::GetTicks() const {
|
u64 JitBase::GetTicks() const {
|
||||||
// TODO(Subv): Remove ARM_DynCom::GetTicks() and use CoreTiming::GetTicks() directly once ARMemu is gone
|
// TODO(Subv, Alegend45): Remove JitBase::GetTicks() and use CoreTiming::GetTicks() directly once ARMemu is gone
|
||||||
return CoreTiming::GetTicks();
|
return CoreTiming::GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ void JitBase::AddTicks(u64 ticks) {
|
|||||||
CoreTiming::Advance();
|
CoreTiming::Advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
|
void JitBase::SaveContext(Core::ThreadContext& ctx) {
|
||||||
memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
|
memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
|
||||||
memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
|
memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
|
|||||||
ctx.mode = state->NextInstr;
|
ctx.mode = state->NextInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
|
void JitBase::LoadContext(const Core::ThreadContext& ctx) {
|
||||||
memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
|
memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
|
||||||
memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
|
memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
|
||||||
|
|
||||||
@ -113,6 +114,6 @@ void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
|
|||||||
state->NextInstr = ctx.mode;
|
state->NextInstr = ctx.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::PrepareReschedule() {
|
void JitBase::PrepareReschedule() {
|
||||||
state->NumInstrsToExecute = 0;
|
state->NumInstrsToExecute = 0;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
// Copyright 2015 Citra Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "common/x64_abi.h"
|
#include "common/x64_abi.h"
|
||||||
#include "common/x64_emitter.h"
|
#include "common/x64_emitter.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
#include "jit_util.h"
|
#include "jit_util.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/arm/skyeye_common/armdefs.h"
|
#include "core/arm/skyeye_common/armdefs.h"
|
||||||
@ -13,13 +16,15 @@
|
|||||||
#define RSCRATCH RAX
|
#define RSCRATCH RAX
|
||||||
#define RSCRATCH2 RDX
|
#define RSCRATCH2 RDX
|
||||||
|
|
||||||
|
#define ARMSTATE(x) &state->x
|
||||||
|
|
||||||
class JitBase : virtual public ARM_Interface
|
class JitBase : virtual public ARM_Interface
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
struct JitState
|
struct JitState
|
||||||
{
|
{
|
||||||
u32 compilerPC;
|
u32 compilerPC;
|
||||||
u32 blockStart;
|
u32 blockStart;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
JitState js;
|
JitState js;
|
||||||
@ -38,6 +43,6 @@ private:
|
|||||||
std::unique_ptr<ARMul_State> state;
|
std::unique_ptr<ARMul_State> state;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Jitx64Base : public JitBase, X64CodeBlock
|
class Jitx64Base : public JitBase, public EmuCodeBlock
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2014 Citra Emulator Project
|
// Copyright 2015 Citra Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -12,9 +12,29 @@ private:
|
|||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
public:
|
public:
|
||||||
bool Enabled() { return m_enabled; }
|
bool Enabled() { return m_enabled; }
|
||||||
void Init() { AllocCodeSpace(size); m_enabled = true; }
|
void Init(int size) { AllocCodeSpace(size); m_enabled = true; }
|
||||||
void Shutdown() { FreeCodeSpace(); m_enabled = false; }
|
void Shutdown() { FreeCodeSpace(); m_enabled = false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int CODE_SIZE = 1024 * 1024 * 32;
|
static const int CODE_SIZE = 1024 * 1024 * 32;
|
||||||
static const int FARCODE_SIZE = 1024 * 1024 * 8;
|
static const int FARCODE_SIZE = 1024 * 1024 * 8;
|
||||||
|
|
||||||
|
class EmuCodeBlock : public Gen::X64CodeBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FarCodeCache farcode;
|
||||||
|
u8* nearcode; // Backed up when we switch to far code.
|
||||||
|
|
||||||
|
// Simple functions to switch between near and far code emitting
|
||||||
|
void SwitchToFarCode()
|
||||||
|
{
|
||||||
|
nearcode = GetWritableCodePtr();
|
||||||
|
SetCodePtr(farcode.GetWritableCodePtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwitchToNearCode()
|
||||||
|
{
|
||||||
|
farcode.SetCodePtr(GetWritableCodePtr());
|
||||||
|
SetCodePtr(nearcode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
44
src/core/arm/jit_x64/jit.cpp
Normal file
44
src/core/arm/jit_x64/jit.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2015 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/x64_abi.h"
|
||||||
|
#include "common/x64_emitter.h"
|
||||||
|
#include "core/arm/arm_interface.h"
|
||||||
|
#include "core/arm/dyncom/arm_dyncom.h"
|
||||||
|
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
||||||
|
#include "core/arm/skyeye_common/armdefs.h"
|
||||||
|
#include "core/arm/jit_common/jit_util.h"
|
||||||
|
#include "core/arm/jit_common/jit_base.h"
|
||||||
|
#include "core/arm/jit_x64/jit.h"
|
||||||
|
|
||||||
|
Jit64::Jit64()
|
||||||
|
{
|
||||||
|
interpreter = new ARM_DynCom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit64::ExecuteInstructions(int num_instructions)
|
||||||
|
{
|
||||||
|
unsigned ticks_executed = MainLoop(num_instructions);
|
||||||
|
AddTicks(ticks_executed);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned Jit64::MainLoop(int num_instructions)
|
||||||
|
{
|
||||||
|
//Always fallback to dyncom
|
||||||
|
for(;num_instructions>0;num_instructions--)
|
||||||
|
{
|
||||||
|
FallbackToInterpreter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Jit64::FallbackToInterpreter()
|
||||||
|
{
|
||||||
|
MOV(32, ARMSTATE(pc), Imm32(js.compilerPC - 8));
|
||||||
|
MOV(32, ARMSTATE(Reg(15)), Imm32(js.compilerPC)); //R15 -> R15 + 8 in execute stage.
|
||||||
|
ABI_PushRegistersAndAdjustStack({},0);
|
||||||
|
//Hacky but should get the job done.
|
||||||
|
MOV(32, ARMSTATE(NumInstrsToExecute), Imm32(1));
|
||||||
|
ABI_CallFunctionC((void*)InterpreterMainLoop,M(state.get()));
|
||||||
|
ABI_PopRegistersAndAdjustStack({},0);
|
||||||
|
}
|
24
src/core/arm/jit_x64/jit.h
Normal file
24
src/core/arm/jit_x64/jit.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2015 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 "core/arm/arm_interface.h"
|
||||||
|
#include "core/arm/dyncom/arm_dyncom.h"
|
||||||
|
#include "core/arm/skyeye_common/armdefs.h"
|
||||||
|
#include "core/arm/jit_common/jit_util.h"
|
||||||
|
#include "core/arm/jit_common/jit_base.h"
|
||||||
|
|
||||||
|
class Jit64 final : public Jitx64Base
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ARM_DynCom* interpreter = nullptr;
|
||||||
|
public:
|
||||||
|
Jit64();
|
||||||
|
void ExecuteInstructions(int num_instructions) override;
|
||||||
|
unsigned MainLoop(int num_instructions);
|
||||||
|
void FallbackToInterpreter();
|
||||||
|
};
|
@ -12,6 +12,7 @@
|
|||||||
#include "core/arm/disassembler/arm_disasm.h"
|
#include "core/arm/disassembler/arm_disasm.h"
|
||||||
#include "core/arm/interpreter/arm_interpreter.h"
|
#include "core/arm/interpreter/arm_interpreter.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom.h"
|
#include "core/arm/dyncom/arm_dyncom.h"
|
||||||
|
#include "core/arm/jit_x64/jit.h"
|
||||||
#include "core/hle/hle.h"
|
#include "core/hle/hle.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/hw/hw.h"
|
#include "core/hw/hw.h"
|
||||||
@ -62,6 +63,8 @@ int Init() {
|
|||||||
g_sys_core = new ARM_Interpreter();
|
g_sys_core = new ARM_Interpreter();
|
||||||
|
|
||||||
switch (Settings::values.cpu_core) {
|
switch (Settings::values.cpu_core) {
|
||||||
|
case CPU_JIT:
|
||||||
|
g_app_core = new Jit64();
|
||||||
case CPU_Interpreter:
|
case CPU_Interpreter:
|
||||||
g_app_core = new ARM_DynCom();
|
g_app_core = new ARM_DynCom();
|
||||||
break;
|
break;
|
||||||
|
@ -13,6 +13,7 @@ class ARM_Interface;
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
enum CPUCore {
|
enum CPUCore {
|
||||||
|
CPU_JIT,
|
||||||
CPU_Interpreter,
|
CPU_Interpreter,
|
||||||
CPU_OldInterpreter,
|
CPU_OldInterpreter,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user