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:
Darius Goad 2015-01-18 21:03:15 -06:00
parent 689b1cd810
commit a334179275
12 changed files with 185 additions and 71 deletions

View File

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

View File

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

View File

@ -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__)

View File

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

View File

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

View File

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

View File

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

View File

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

View 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);
}

View 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();
};

View File

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

View File

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