mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add experimental mode to cache pointers in the arm jit.
Turned off for now as it needs more work but seems quite promising already.
This commit is contained in:
parent
58c39a38ee
commit
502f772856
4 changed files with 48 additions and 3 deletions
|
@ -97,6 +97,13 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
|||
switch(op >> 26)
|
||||
{
|
||||
case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
|
||||
if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) {
|
||||
gpr.MapRegAsPointer(rs);
|
||||
fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY);
|
||||
VLDR(fpr.R(ft), gpr.RPtr(rs), offset);
|
||||
break;
|
||||
}
|
||||
|
||||
fpr.SpillLock(ft);
|
||||
fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY);
|
||||
if (gpr.IsImm(rs)) {
|
||||
|
@ -135,6 +142,13 @@ void Jit::Comp_FPULS(MIPSOpcode op)
|
|||
break;
|
||||
|
||||
case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1
|
||||
if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) {
|
||||
gpr.MapRegAsPointer(rs);
|
||||
fpr.MapReg(ft, 0);
|
||||
VSTR(fpr.R(ft), gpr.RPtr(rs), offset);
|
||||
break;
|
||||
}
|
||||
|
||||
fpr.MapReg(ft);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF;
|
||||
|
|
|
@ -152,6 +152,33 @@ namespace MIPSComp
|
|||
case 40: //sb
|
||||
case 41: //sh
|
||||
case 43: //sw
|
||||
// Map base register as pointer and go from there - if the displacement isn't too big.
|
||||
// This is faster if there are multiple loads from the same pointer. Need to hook up the MIPS analyzer..
|
||||
if (jo.cachePointers && g_Config.bFastMemory) {
|
||||
// ARM has smaller load/store immediate displacements than MIPS, 12 bits - and some memory ops only have 8 bits.
|
||||
int offsetRange = 0x3ff;
|
||||
if (o == 41 || o == 33 || o == 37 || o == 32)
|
||||
offsetRange = 0xff; // 8 bit offset only
|
||||
if (!gpr.IsImm(rs) && rs != rt && (offset <= offsetRange) && offset >= -offsetRange) {
|
||||
gpr.SpillLock(rs, rt);
|
||||
gpr.MapRegAsPointer(rs);
|
||||
gpr.MapReg(rt, load ? (MAP_NOINIT | MAP_DIRTY) : 0);
|
||||
switch (o) {
|
||||
case 35: LDR (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 37: LDRH (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 33: LDRSH(gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 36: LDRB (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 32: LDRSB(gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
// Store
|
||||
case 43: STR (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 41: STRH (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
case 40: STRB (gpr.R(rt), gpr.RPtr(rs), Operand2(offset, TYPE_IMM)); break;
|
||||
}
|
||||
gpr.ReleaseSpillLocks();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpr.IsImm(rs) && Memory::IsValidAddress(iaddr)) {
|
||||
// TODO: Avoid mapping a register for the "zero" register, use R0 instead.
|
||||
|
||||
|
@ -171,6 +198,7 @@ namespace MIPSComp
|
|||
SetR0ToEffectiveAddress(rs, offset);
|
||||
}
|
||||
}
|
||||
|
||||
switch (o)
|
||||
{
|
||||
// Load
|
||||
|
|
|
@ -63,6 +63,7 @@ ArmJitOptions::ArmJitOptions()
|
|||
downcountInRegister = true;
|
||||
useBackJump = false;
|
||||
useForwardJump = false;
|
||||
cachePointers = false;
|
||||
}
|
||||
|
||||
Jit::Jit(MIPSState *mips) : blocks(mips, this), gpr(mips, &jo), fpr(mips), mips_(mips)
|
||||
|
@ -218,7 +219,9 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
|||
js.inDelaySlot = false;
|
||||
js.PrefixStart();
|
||||
|
||||
// We add a check before the block, used when entering from a linked block.
|
||||
// We add a downcount flag check before the block, used when entering from a linked block.
|
||||
// The last block decremented downcounter, and the flag should still be available.
|
||||
// Got three variants here of where we position the code, needs detailed benchmarking.
|
||||
|
||||
FixupBranch bail;
|
||||
if (jo.useBackJump) {
|
||||
|
@ -239,7 +242,6 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
|||
bail = B();
|
||||
SetCC(CC_AL);
|
||||
} else {
|
||||
// Downcount flag check. The last block decremented downcounter, and the flag should still be available.
|
||||
b->checkedEntry = GetCodePtr();
|
||||
SetCC(CC_LT);
|
||||
MOVI2R(R0, js.blockStart);
|
||||
|
@ -247,7 +249,6 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
|||
SetCC(CC_AL);
|
||||
}
|
||||
|
||||
|
||||
b->normalEntry = GetCodePtr();
|
||||
// TODO: this needs work
|
||||
MIPSAnalyst::AnalysisResults analysis; // = MIPSAnalyst::Analyze(em_address);
|
||||
|
@ -290,6 +291,7 @@ const u8 *Jit::DoJit(u32 em_address, JitBlock *b)
|
|||
|
||||
char temp[256];
|
||||
if (logBlocks > 0 && dontLogBlocks == 0) {
|
||||
INFO_LOG(JIT, "=============== mips ===============");
|
||||
for (u32 cpc = em_address; cpc != js.compilerPC + 4; cpc += 4) {
|
||||
MIPSDisAsm(Memory::Read_Instruction(cpc), cpc, temp, true);
|
||||
INFO_LOG(JIT, "M: %08x %s", cpc, temp);
|
||||
|
|
|
@ -40,6 +40,7 @@ struct ArmJitOptions
|
|||
bool downcountInRegister;
|
||||
bool useBackJump;
|
||||
bool useForwardJump;
|
||||
bool cachePointers;
|
||||
};
|
||||
|
||||
class Jit : public ArmGen::ARMXCodeBlock
|
||||
|
|
Loading…
Add table
Reference in a new issue