Add an optimization to discard registers at the end of functions when possible.

Works in some games but crashes many so hiding it for now. Do not add UI.
This commit is contained in:
Henrik Rydgard 2013-11-08 12:30:31 +01:00
parent 9a51d25279
commit 5a95e267fb
7 changed files with 49 additions and 2 deletions

View file

@ -315,6 +315,9 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
speedhacks->Get("PrescaleUV", &bPrescaleUV, false);
speedhacks->Get("DisableAlphaTest", &bDisableAlphaTest, false);
IniFile::Section *jitConfig = iniFile.GetOrCreateSection("JIT");
jitConfig->Get("DiscardRegsOnJRRA", &bDiscardRegsOnJRRA, false);
INFO_LOG(LOADER, "Loading controller config: %s", controllerIniFilename_.c_str());
bSaveSettings = true;

View file

@ -185,6 +185,9 @@ public:
bool bDisableAlphaTest; // Helps PowerVR immensely, breaks some graphics
// End GLES hacks.
// Risky JIT optimizations
bool bDiscardRegsOnJRRA;
// SystemParam
std::string sNickName;
int iLanguage;

View file

@ -16,7 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Core/Reporting.h"
#include "Core/Config.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/HLETables.h"
@ -388,6 +388,16 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
CompileDelaySlot(DELAYSLOT_NICE);
gpr.MapReg(rs);
destReg = gpr.R(rs); // Safe because FlushAll doesn't change any regs
if (rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) {
// According to the MIPS ABI, there are some regs we don't need to preserve.
// Let's discard them so we don't need to write them back.
// NOTE: Not all games follow the MIPS ABI! Tekken 6, for example, will crash
// with this enabled.
for (int i = MIPS_REG_A0; i <= MIPS_REG_T7; i++)
gpr.DiscardR((MIPSGPReg)i);
gpr.DiscardR(MIPS_REG_T8);
gpr.DiscardR(MIPS_REG_T9);
}
FlushAll();
} else {
// Delay slot

View file

@ -200,6 +200,17 @@ void ArmRegCache::FlushArmReg(ARMReg r) {
ar[r].mipsReg = -1;
}
void ArmRegCache::DiscardR(MIPSReg r) {
if (mr[r].loc == ML_ARMREG) {
ARMReg a = mr[r].reg;
ar[a].isDirty = false;
ar[a].mipsReg = -1;
mr[r].reg = INVALID_REG;
mr[r].loc = ML_MEM;
mr[r].imm = 0;
}
}
void ArmRegCache::FlushR(MIPSReg r) {
switch (mr[r].loc) {
case ML_IMM:

View file

@ -101,6 +101,7 @@ public:
void FlushR(MIPSReg r);
void FlushBeforeCall();
void FlushAll();
void DiscardR(MIPSReg r);
ARMReg R(int preg); // Returns a cached register

View file

@ -39,6 +39,11 @@ enum MIPSGPReg
MIPS_REG_A4=8, // Seems to be N32 register calling convention - there are 8 args instead of 4.
MIPS_REG_A5=9,
MIPS_REG_T4=12,
MIPS_REG_T5=13,
MIPS_REG_T6=14,
MIPS_REG_T7=15,
MIPS_REG_S0=16,
MIPS_REG_S1=17,
MIPS_REG_S2=18,
@ -47,6 +52,8 @@ enum MIPSGPReg
MIPS_REG_S5=21,
MIPS_REG_S6=22,
MIPS_REG_S7=23,
MIPS_REG_T8=24,
MIPS_REG_T9=25,
MIPS_REG_K0=26,
MIPS_REG_K1=27,
MIPS_REG_GP=28,

View file

@ -16,7 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Core/Reporting.h"
#include "Core/Config.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/HLETables.h"
#include "Core/Host.h"
@ -596,6 +596,18 @@ void Jit::Comp_JumpReg(MIPSOpcode op)
{
CompileDelaySlot(DELAYSLOT_NICE);
MOV(32, R(EAX), gpr.R(rs));
if (rs == MIPS_REG_RA && g_Config.bDiscardRegsOnJRRA) {
// According to the MIPS ABI, there are some regs we don't need to preserve.
// Let's discard them so we don't need to write them back.
// NOTE: Not all games follow the MIPS ABI! Tekken 6, for example, will crash
// with this enabled.
for (int i = MIPS_REG_A0; i <= MIPS_REG_T7; i++)
gpr.DiscardRegContentsIfCached((MIPSGPReg)i);
gpr.DiscardRegContentsIfCached(MIPS_REG_T8);
gpr.DiscardRegContentsIfCached(MIPS_REG_T9);
}
FlushAll();
}
else