Make the IRJit core selectable in developer tools

This commit is contained in:
Henrik Rydgard 2016-05-08 01:43:27 +02:00
parent 09969c0156
commit ce8aae5ed1
17 changed files with 84 additions and 45 deletions

View File

@ -282,9 +282,20 @@ static int DefaultNumWorkers() {
return cpu_info.num_cores; return cpu_info.num_cores;
} }
static bool DefaultJit() { // TODO: Default to IRJit on iOS when it's done.
static int DefaultCpuCore() {
#ifdef IOS #ifdef IOS
return iosCanUseJit; return iosCanUseJit ? CPU_CORE_JIT : CPU_CORE_INTERPRETER;
#elif defined(ARM) || defined(ARM64) || defined(_M_IX86) || defined(_M_X64)
return CPU_CORE_JIT;
#else
return CPU_CORE_INTERPRETER;
#endif
}
static bool DefaultCodeGen() {
#ifdef IOS
return iosCanUseJit ? true : false;
#elif defined(ARM) || defined(ARM64) || defined(_M_IX86) || defined(_M_X64) #elif defined(ARM) || defined(ARM64) || defined(_M_IX86) || defined(_M_X64)
return true; return true;
#else #else
@ -353,8 +364,7 @@ static bool DefaultSasThread() {
} }
static ConfigSetting cpuSettings[] = { static ConfigSetting cpuSettings[] = {
ReportedConfigSetting("Jit", &g_Config.bJit, &DefaultJit, true, true), ReportedConfigSetting("CPUCore", &g_Config.iCpuCore, &DefaultCpuCore, true, true),
ReportedConfigSetting("CPUCore", &g_Config.bJit, &DefaultJit, true, true),
ReportedConfigSetting("SeparateCPUThread", &g_Config.bSeparateCPUThread, false, true, true), ReportedConfigSetting("SeparateCPUThread", &g_Config.bSeparateCPUThread, false, true, true),
ReportedConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, true, true), ReportedConfigSetting("SeparateSASThread", &g_Config.bSeparateSASThread, &DefaultSasThread, true, true),
ReportedConfigSetting("SeparateIOThread", &g_Config.bSeparateIOThread, true, true, true), ReportedConfigSetting("SeparateIOThread", &g_Config.bSeparateIOThread, true, true, true),
@ -464,7 +474,7 @@ static ConfigSetting graphicsSettings[] = {
ReportedConfigSetting("VertexCache", &g_Config.bVertexCache, true, true, true), ReportedConfigSetting("VertexCache", &g_Config.bVertexCache, true, true, true),
ReportedConfigSetting("TextureBackoffCache", &g_Config.bTextureBackoffCache, false, true, true), ReportedConfigSetting("TextureBackoffCache", &g_Config.bTextureBackoffCache, false, true, true),
ReportedConfigSetting("TextureSecondaryCache", &g_Config.bTextureSecondaryCache, false, true, true), ReportedConfigSetting("TextureSecondaryCache", &g_Config.bTextureSecondaryCache, false, true, true),
ReportedConfigSetting("VertexDecJit", &g_Config.bVertexDecoderJit, &DefaultJit, false), ReportedConfigSetting("VertexDecJit", &g_Config.bVertexDecoderJit, &DefaultCodeGen, false),
#ifndef MOBILE_DEVICE #ifndef MOBILE_DEVICE
ConfigSetting("FullScreen", &g_Config.bFullScreen, false), ConfigSetting("FullScreen", &g_Config.bFullScreen, false),
@ -959,16 +969,16 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
} }
// Override ppsspp.ini JIT value to prevent crashing // Override ppsspp.ini JIT value to prevent crashing
if (!DefaultJit() && g_Config.bJit) { if (DefaultCpuCore() != CPU_CORE_JIT && g_Config.iCpuCore == CPU_CORE_JIT) {
jitForcedOff = true; jitForcedOff = true;
g_Config.bJit = false; g_Config.iCpuCore = CPU_CORE_INTERPRETER;
} }
} }
void Config::Save() { void Config::Save() {
if (jitForcedOff) { if (jitForcedOff) {
// if JIT has been forced off, we don't want to screw up the user's ppsspp.ini // if JIT has been forced off, we don't want to screw up the user's ppsspp.ini
g_Config.bJit = true; g_Config.iCpuCore = CPU_CORE_JIT;
} }
if (iniFilename_.size() && g_Config.bSaveSettings) { if (iniFilename_.size() && g_Config.bSaveSettings) {
@ -1037,7 +1047,7 @@ void Config::Save() {
} }
if (jitForcedOff) { if (jitForcedOff) {
// force JIT off again just in case Config::Save() is called without exiting PPSSPP // force JIT off again just in case Config::Save() is called without exiting PPSSPP
g_Config.bJit = false; g_Config.iCpuCore = CPU_CORE_INTERPRETER;
} }
} }

View File

@ -33,6 +33,12 @@ const int PSP_DEFAULT_FIRMWARE = 150;
static const s8 VOLUME_OFF = 0; static const s8 VOLUME_OFF = 0;
static const s8 VOLUME_MAX = 10; static const s8 VOLUME_MAX = 10;
enum CPUCore {
CPU_CORE_INTERPRETER = 0,
CPU_CORE_JIT = 1,
CPU_CORE_IRJIT = 2,
};
enum { enum {
ROTATION_AUTO = 0, ROTATION_AUTO = 0,
ROTATION_LOCKED_HORIZONTAL = 1, ROTATION_LOCKED_HORIZONTAL = 1,
@ -119,7 +125,6 @@ public:
// Core // Core
bool bIgnoreBadMemAccess; bool bIgnoreBadMemAccess;
bool bFastMemory; bool bFastMemory;
bool bJit;
int iCpuCore; int iCpuCore;
bool bCheckForNewVersion; bool bCheckForNewVersion;
bool bForceLagSync; bool bForceLagSync;

View File

@ -20,12 +20,7 @@
#include <string> #include <string>
#include "Core/Compatibility.h" #include "Core/Compatibility.h"
#include "Core/Config.h"
enum CPUCore {
CPU_INTERPRETER,
CPU_JIT,
CPU_IRJIT,
};
enum GPUCore { enum GPUCore {
GPUCORE_NULL, GPUCORE_NULL,
@ -47,6 +42,7 @@ struct CoreParameter {
CPUCore cpuCore; CPUCore cpuCore;
GPUCore gpuCore; GPUCore gpuCore;
GraphicsContext *graphicsContext; // TODO: Find a better place. GraphicsContext *graphicsContext; // TODO: Find a better place.
Thin3DContext *thin3d; Thin3DContext *thin3d;
bool enableSound; // there aren't multiple sound cores. bool enableSound; // there aren't multiple sound cores.

View File

@ -219,7 +219,7 @@ void IRJit::BranchVFPUFlag(MIPSOpcode op, IRComparison cc, bool likely) {
MIPSOpcode delaySlotOp = GetOffsetInstruction(1); MIPSOpcode delaySlotOp = GetOffsetInstruction(1);
ir.Write(IROp::VfpCondToReg, IRTEMP_0); ir.Write(IROp::VfpuCtrlToReg, IRTEMP_0, VFPU_CTRL_CC);
ir.Write(IROp::Downcount, 0, js.downcountAmount & 0xFF, js.downcountAmount >> 8); ir.Write(IROp::Downcount, 0, js.downcountAmount & 0xFF, js.downcountAmount >> 8);

View File

@ -81,6 +81,7 @@ static const IRMeta irMeta[] = {
{ IROp::FMovFromGPR, "FMovFromGPR", "FG" }, { IROp::FMovFromGPR, "FMovFromGPR", "FG" },
{ IROp::FMovToGPR, "FMovToGPR", "GF" }, { IROp::FMovToGPR, "FMovToGPR", "GF" },
{ IROp::FpCondToReg, "FpCondToReg", "G" }, { IROp::FpCondToReg, "FpCondToReg", "G" },
{ IROp::VfpuCtrlToReg, "VfpuCtrlToReg", "GI" },
{ IROp::SetCtrlVFPU, "SetCtrlVFPU", "TC" }, { IROp::SetCtrlVFPU, "SetCtrlVFPU", "TC" },
{ IROp::Interpret, "Interpret", "_C" }, { IROp::Interpret, "Interpret", "_C" },
{ IROp::Downcount, "Downcount", "_II" }, { IROp::Downcount, "Downcount", "_II" },
@ -329,6 +330,9 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
case IROp::FpCondToReg: case IROp::FpCondToReg:
mips->r[inst->dest] = mips->fpcond; mips->r[inst->dest] = mips->fpcond;
break; break;
case IROp::VfpuCtrlToReg:
mips->r[inst->dest] = mips->vfpuCtrl[inst->src1];
break;
case IROp::FRound: case IROp::FRound:
mips->r[inst->dest] = (int)floorf(mips->f[inst->src1] + 0.5f); mips->r[inst->dest] = (int)floorf(mips->f[inst->src1] + 0.5f);
break; break;

View File

@ -119,7 +119,7 @@ enum class IROp : u8 {
FMovToGPR, FMovToGPR,
FpCondToReg, FpCondToReg,
VfpCondToReg, VfpuCtrlToReg,
ZeroFpCond, ZeroFpCond,
FCmpUnordered, FCmpUnordered,

View File

@ -255,6 +255,12 @@ void IRJit::DoJit(u32 em_address, IRBlock *b) {
MIPSCompileOp(inst, this); MIPSCompileOp(inst, this);
js.compilerPC += 4; js.compilerPC += 4;
js.numInstructions++; js.numInstructions++;
if (ir.GetConstants().size() > 128) {
// Need to break the block
ir.Write(IROp::ExitToConst, ir.AddConstant(js.compilerPC));
js.compiling = false;
}
} }
ir.Simplify(); ir.Simplify();

View File

@ -47,9 +47,6 @@ namespace MIPSComp {
} }
JitInterface *CreateNativeJit(MIPSState *mips) { JitInterface *CreateNativeJit(MIPSState *mips) {
#if 1
return new MIPSComp::IRJit(mips);
#else
#if defined(ARM) #if defined(ARM)
return new MIPSComp::ArmJit(mips); return new MIPSComp::ArmJit(mips);
#elif defined(ARM64) #elif defined(ARM64)
@ -60,7 +57,6 @@ namespace MIPSComp {
return new MIPSComp::MipsJit(mips); return new MIPSComp::MipsJit(mips);
#else #else
return new MIPSComp::FakeJit(mips); return new MIPSComp::FakeJit(mips);
#endif
#endif #endif
} }

View File

@ -27,6 +27,7 @@
#include "Core/MIPS/MIPSTables.h" #include "Core/MIPS/MIPSTables.h"
#include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSDebugInterface.h"
#include "Core/MIPS/MIPSVFPUUtils.h" #include "Core/MIPS/MIPSVFPUUtils.h"
#include "Core/MIPS/IR/IRJit.h"
#include "Core/Reporting.h" #include "Core/Reporting.h"
#include "Core/System.h" #include "Core/System.h"
#include "Core/HLE/sceDisplay.h" #include "Core/HLE/sceDisplay.h"
@ -206,8 +207,10 @@ void MIPSState::Init() {
// Initialize the VFPU random number generator with .. something? // Initialize the VFPU random number generator with .. something?
rng.Init(0x1337); rng.Init(0x1337);
if (PSP_CoreParameter().cpuCore == CPU_JIT) { if (PSP_CoreParameter().cpuCore == CPU_CORE_JIT) {
MIPSComp::jit = MIPSComp::CreateNativeJit(this); MIPSComp::jit = MIPSComp::CreateNativeJit(this);
} else if (PSP_CoreParameter().cpuCore == CPU_CORE_IRJIT) {
MIPSComp::jit = new MIPSComp::IRJit(this);
} else { } else {
MIPSComp::jit = nullptr; MIPSComp::jit = nullptr;
} }
@ -224,14 +227,23 @@ void MIPSState::UpdateCore(CPUCore desired) {
PSP_CoreParameter().cpuCore = desired; PSP_CoreParameter().cpuCore = desired;
switch (PSP_CoreParameter().cpuCore) { switch (PSP_CoreParameter().cpuCore) {
case CPU_JIT: case CPU_CORE_JIT:
INFO_LOG(CPU, "Switching to JIT"); INFO_LOG(CPU, "Switching to JIT");
if (!MIPSComp::jit) { if (MIPSComp::jit) {
MIPSComp::jit = MIPSComp::CreateNativeJit(this); delete MIPSComp::jit;
} }
MIPSComp::jit = MIPSComp::CreateNativeJit(this);
break; break;
case CPU_INTERPRETER: case CPU_CORE_IRJIT:
INFO_LOG(CPU, "Switching to IRJIT");
if (MIPSComp::jit) {
delete MIPSComp::jit;
}
MIPSComp::jit = new MIPSComp::IRJit(this);
break;
case CPU_CORE_INTERPRETER:
INFO_LOG(CPU, "Switching to interpreter"); INFO_LOG(CPU, "Switching to interpreter");
delete MIPSComp::jit; delete MIPSComp::jit;
MIPSComp::jit = 0; MIPSComp::jit = 0;
@ -292,11 +304,12 @@ void MIPSState::SingleStep() {
// returns 1 if reached ticks limit // returns 1 if reached ticks limit
int MIPSState::RunLoopUntil(u64 globalTicks) { int MIPSState::RunLoopUntil(u64 globalTicks) {
switch (PSP_CoreParameter().cpuCore) { switch (PSP_CoreParameter().cpuCore) {
case CPU_JIT: case CPU_CORE_JIT:
case CPU_CORE_IRJIT:
MIPSComp::jit->RunLoopUntil(globalTicks); MIPSComp::jit->RunLoopUntil(globalTicks);
break; break;
case CPU_INTERPRETER: case CPU_CORE_INTERPRETER:
return MIPSInterpret_RunUntil(globalTicks); return MIPSInterpret_RunUntil(globalTicks);
} }
return 1; return 1;

View File

@ -87,7 +87,7 @@ inline void ReadFromHardware(T &var, const u32 address) {
var = *((const T*)GetPointerUnchecked(address)); var = *((const T*)GetPointerUnchecked(address));
} else { } else {
// In jit, we only flush PC when bIgnoreBadMemAccess is off. // In jit, we only flush PC when bIgnoreBadMemAccess is off.
if (g_Config.bJit && g_Config.bIgnoreBadMemAccess) { if (g_Config.iCpuCore != CPU_CORE_INTERPRETER && g_Config.bIgnoreBadMemAccess) {
WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address); WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address);
} else { } else {
WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
@ -123,7 +123,7 @@ inline void WriteToHardware(u32 address, const T data) {
*(T*)GetPointerUnchecked(address) = data; *(T*)GetPointerUnchecked(address) = data;
} else { } else {
// In jit, we only flush PC when bIgnoreBadMemAccess is off. // In jit, we only flush PC when bIgnoreBadMemAccess is off.
if (g_Config.bJit && g_Config.bIgnoreBadMemAccess) { if (g_Config.iCpuCore != CPU_CORE_INTERPRETER && g_Config.bIgnoreBadMemAccess) {
WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address); WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address);
} else { } else {
WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);

View File

@ -101,7 +101,7 @@ void EmuScreen::bootGame(const std::string &filename) {
invalid_ = true; invalid_ = true;
CoreParameter coreParam; CoreParameter coreParam;
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.cpuCore = (CPUCore)g_Config.iCpuCore;
coreParam.gpuCore = GPUCORE_GLES; coreParam.gpuCore = GPUCORE_GLES;
switch (GetGPUBackend()) { switch (GetGPUBackend()) {
case GPUBackend::OPENGL: case GPUBackend::OPENGL:
@ -282,7 +282,7 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
} else if (!strcmp(message, "clear jit")) { } else if (!strcmp(message, "clear jit")) {
currentMIPS->ClearJitCache(); currentMIPS->ClearJitCache();
if (PSP_IsInited()) { if (PSP_IsInited()) {
currentMIPS->UpdateCore(g_Config.bJit ? CPU_JIT : CPU_INTERPRETER); currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore);
} }
} else if (!strcmp(message, "window minimized")) { } else if (!strcmp(message, "window minimized")) {
if (!strcmp(value, "true")) { if (!strcmp(value, "true")) {

View File

@ -1059,8 +1059,11 @@ void DeveloperToolsScreen::CreateViews() {
} }
} }
#endif #endif
if (canUseJit) {
list->Add(new CheckBox(&g_Config.bJit, sy->T("Dynarec", "Dynarec (JIT)")))->OnClick.Handle(this, &DeveloperToolsScreen::OnJitAffectingSetting); static const char *cpuCores[] = { "Interpreter", "Dynarec (JIT)", "IRJit" };
PopupMultiChoice *core = list->Add(new PopupMultiChoice(&g_Config.iCpuCore, gr->T("CPU Core"), cpuCores, 0, ARRAY_SIZE(cpuCores), sy->GetName(), screenManager()));
if (!canUseJit) {
core->HideChoice(1);
} }
list->Add(new CheckBox(&g_Config.bShowDeveloperMenu, dev->T("Show Developer Menu"))); list->Add(new CheckBox(&g_Config.bShowDeveloperMenu, dev->T("Show Developer Menu")));

View File

@ -133,7 +133,7 @@ void HandleCommonMessages(const char *message, const char *value, ScreenManager
MIPSComp::jit->ClearCache(); MIPSComp::jit->ClearCache();
} }
if (PSP_IsInited()) { if (PSP_IsInited()) {
currentMIPS->UpdateCore(g_Config.bJit ? CPU_JIT : CPU_INTERPRETER); currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore);
} }
} }
} }

View File

@ -392,11 +392,15 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
gfxLog = true; gfxLog = true;
break; break;
case 'j': case 'j':
g_Config.bJit = true; g_Config.iCpuCore = CPU_CORE_JIT;
g_Config.bSaveSettings = false; g_Config.bSaveSettings = false;
break; break;
case 'i': case 'i':
g_Config.bJit = false; g_Config.iCpuCore = CPU_CORE_INTERPRETER;
g_Config.bSaveSettings = false;
break;
case 'r':
g_Config.iCpuCore = CPU_CORE_IRJIT;
g_Config.bSaveSettings = false; g_Config.bSaveSettings = false;
break; break;
case '-': case '-':

View File

@ -69,7 +69,7 @@ void RunTests()
#endif #endif
CoreParameter coreParam; CoreParameter coreParam;
coreParam.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParam.cpuCore = (CPUCore)g_Config.iCpuCore;
coreParam.gpuCore = g_Config.bSoftwareRendering ? GPUCORE_SOFTWARE : GPUCORE_GLES; coreParam.gpuCore = g_Config.bSoftwareRendering ? GPUCORE_SOFTWARE : GPUCORE_GLES;
coreParam.enableSound = g_Config.bEnableSound; coreParam.enableSound = g_Config.bEnableSound;
coreParam.graphicsContext = PSP_CoreParameter().graphicsContext; coreParam.graphicsContext = PSP_CoreParameter().graphicsContext;

View File

@ -207,11 +207,11 @@ int main(int argc, const char* argv[])
#endif #endif
bool fullLog = false; bool fullLog = false;
bool useJit = true;
bool autoCompare = false; bool autoCompare = false;
bool verbose = false; bool verbose = false;
const char *stateToLoad = 0; const char *stateToLoad = 0;
GPUCore gpuCore = GPUCORE_NULL; GPUCore gpuCore = GPUCORE_NULL;
CPUCore cpuCore = CPU_CORE_JIT;
std::vector<std::string> testFilenames; std::vector<std::string> testFilenames;
const char *mountIso = 0; const char *mountIso = 0;
@ -236,9 +236,11 @@ int main(int argc, const char* argv[])
else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log")) else if (!strcmp(argv[i], "-l") || !strcmp(argv[i], "--log"))
fullLog = true; fullLog = true;
else if (!strcmp(argv[i], "-i")) else if (!strcmp(argv[i], "-i"))
useJit = false; cpuCore = CPU_CORE_INTERPRETER;
else if (!strcmp(argv[i], "-j")) else if (!strcmp(argv[i], "-j"))
useJit = true; cpuCore = CPU_CORE_JIT;
else if (!strcmp(argv[i], "-ir"))
cpuCore = CPU_CORE_IRJIT;
else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compare")) else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compare"))
autoCompare = true; autoCompare = true;
else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")) else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose"))
@ -311,7 +313,7 @@ int main(int argc, const char* argv[])
} }
CoreParameter coreParameter; CoreParameter coreParameter;
coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER; coreParameter.cpuCore = cpuCore;
coreParameter.gpuCore = glWorking ? gpuCore : GPUCORE_NULL; coreParameter.gpuCore = glWorking ? gpuCore : GPUCORE_NULL;
coreParameter.graphicsContext = graphicsContext; coreParameter.graphicsContext = graphicsContext;
coreParameter.enableSound = false; coreParameter.enableSound = false;

View File

@ -83,7 +83,7 @@ static void SetupJitHarness() {
coreState = CORE_POWERUP; coreState = CORE_POWERUP;
currentMIPS = &mipsr4k; currentMIPS = &mipsr4k;
Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE;
PSP_CoreParameter().cpuCore = CPU_INTERPRETER; PSP_CoreParameter().cpuCore = CPU_CORE_INTERPRETER;
PSP_CoreParameter().unthrottle = true; PSP_CoreParameter().unthrottle = true;
Memory::Init(); Memory::Init();
@ -169,7 +169,7 @@ bool TestJit() {
double jit_speed = 0.0, interp_speed = 0.0; double jit_speed = 0.0, interp_speed = 0.0;
if (compileSuccess) { if (compileSuccess) {
interp_speed = ExecCPUTest(); interp_speed = ExecCPUTest();
mipsr4k.UpdateCore(CPU_JIT); mipsr4k.UpdateCore(CPU_CORE_JIT);
jit_speed = ExecCPUTest(); jit_speed = ExecCPUTest();
// Disassemble // Disassemble