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
// Licensed under GPLv2 or any later version
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once

View File

@ -1,78 +1,89 @@
// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// 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
#include <string>
enum CPUVendor
{
VENDOR_INTEL = 0,
VENDOR_AMD = 1,
VENDOR_ARM = 2,
VENDOR_OTHER = 3,
VENDOR_INTEL = 0,
VENDOR_AMD = 1,
VENDOR_ARM = 2,
VENDOR_OTHER = 3,
};
struct CPUInfo
{
CPUVendor vendor;
CPUVendor vendor;
char cpu_string[0x21];
char brand_string[0x41];
bool OS64bit;
bool CPU64bit;
bool Mode64bit;
char cpu_string[0x41];
char brand_string[0x21];
bool OS64bit;
bool CPU64bit;
bool Mode64bit;
bool HTT;
int num_cores;
int logical_cpu_count;
bool HTT;
int num_cores;
int logical_cpu_count;
bool bSSE;
bool bSSE2;
bool bSSE3;
bool bSSSE3;
bool bPOPCNT;
bool bSSE4_1;
bool bSSE4_2;
bool bLZCNT;
bool bSSE4A;
bool bAVX;
bool bAES;
bool bLAHFSAHF64;
bool bLongMode;
bool bSSE;
bool bSSE2;
bool bSSE3;
bool bSSSE3;
bool bPOPCNT;
bool bSSE4_1;
bool bSSE4_2;
bool bLZCNT;
bool bSSE4A;
bool bAVX;
bool bAVX2;
bool bBMI1;
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
bool bSwp;
bool bHalf;
bool bThumb;
bool bFastMult;
bool bVFP;
bool bEDSP;
bool bThumbEE;
bool bNEON;
bool bVFPv3;
bool bTLS;
bool bVFPv4;
bool bIDIVa;
bool bIDIVt;
bool bArmV7; // enable MOVT, MOVW etc
// ARM specific CPUInfo
bool bSwp;
bool bHalf;
bool bThumb;
bool bFastMult;
bool bVFP;
bool bEDSP;
bool bThumbEE;
bool bNEON;
bool bVFPv3;
bool bTLS;
bool bVFPv4;
bool bIDIVa;
bool bIDIVt;
bool bArmV7; // enable MOVT, MOVW etc
// ARMv8 specific
bool bFP;
bool bASIMD;
// ARMv8 specific
bool bFP;
bool bASIMD;
// Call Detect()
explicit CPUInfo();
// Call Detect()
explicit CPUInfo();
// Turn the cpu info into a string we can show
std::string Summarize();
// Turn the CPU info into a string we can show
std::string Summarize();
private:
// Detects the various cpu features
void Detect();
// Detects the various CPU features
void Detect();
};
extern CPUInfo cpu_info;

View File

@ -47,6 +47,7 @@ enum class Class : ClassType {
Debug_Emulated, ///< Debug messages from the emulated programs
Debug_GPU, ///< GPU debugging tools
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
DYNA_REC, ///< Dolphin x64 emitter
Kernel, ///< The HLE implementation of the CTR kernel
Kernel_SVC, ///< Kernel system calls
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_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __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__)

View File

@ -10,9 +10,9 @@
#include <cstring>
#include <functional>
#include "Common/bit_set.h"
#include "Common/code_block.h"
#include "Common/common_types.h"
#include "common/bit_set.h"
#include "common/code_block.h"
#include "common/common_types.h"
namespace Gen
{

View File

@ -13,6 +13,8 @@ set(SRCS
arm/interpreter/armsupp.cpp
arm/interpreter/armvirt.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/vfpdouble.cpp
arm/skyeye_common/vfp/vfpinstr.cpp
@ -99,6 +101,7 @@ set(HEADERS
arm/interpreter/arm_interpreter.h
arm/jit_common/jit_util.h
arm/jit_common/jit_base.h
arm/jit_x64/jit.h
arm/skyeye_common/arm_regformat.h
arm/skyeye_common/armcpu.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
// 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/armemu.h"
#include "core/arm/skyeye_common/vfp/vfp.h"
#include "core/arm/jit_common/jit_base.h"
#include "core/arm/skyeye_common/armdefs.h"
#include "core/core.h"
#include "core/core_timing.h"
@ -71,7 +72,7 @@ void JitBase::SetCPSR(u32 cpsr) {
}
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();
}
@ -81,7 +82,7 @@ void JitBase::AddTicks(u64 ticks) {
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.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
@ -97,7 +98,7 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) {
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->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
@ -113,6 +114,6 @@ void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) {
state->NextInstr = ctx.mode;
}
void ARM_DynCom::PrepareReschedule() {
void JitBase::PrepareReschedule() {
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
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include "common/x64_abi.h"
#include "common/x64_emitter.h"
#include "common/common_types.h"
#include "jit_util.h"
#include "core/arm/arm_interface.h"
#include "core/arm/skyeye_common/armdefs.h"
@ -13,13 +16,15 @@
#define RSCRATCH RAX
#define RSCRATCH2 RDX
#define ARMSTATE(x) &state->x
class JitBase : virtual public ARM_Interface
{
protected:
struct JitState
{
u32 compilerPC;
u32 blockStart;
u32 compilerPC;
u32 blockStart;
};
public:
JitState js;
@ -38,6 +43,6 @@ private:
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
// Refer to the license.txt file included.
@ -12,9 +12,29 @@ private:
bool m_enabled = false;
public:
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; }
};
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/interpreter/arm_interpreter.h"
#include "core/arm/dyncom/arm_dyncom.h"
#include "core/arm/jit_x64/jit.h"
#include "core/hle/hle.h"
#include "core/hle/kernel/thread.h"
#include "core/hw/hw.h"
@ -62,6 +63,8 @@ int Init() {
g_sys_core = new ARM_Interpreter();
switch (Settings::values.cpu_core) {
case CPU_JIT:
g_app_core = new Jit64();
case CPU_Interpreter:
g_app_core = new ARM_DynCom();
break;

View File

@ -13,6 +13,7 @@ class ARM_Interface;
namespace Core {
enum CPUCore {
CPU_JIT,
CPU_Interpreter,
CPU_OldInterpreter,
};