ARMv7 register cache optimizations.
Enable support for not loading a destination register on FPR cache. Dump registers if they won't be used later in the block. Stolen from Fiora.
This commit is contained in:
parent
4ce1b33e55
commit
6683b194ff
|
@ -444,6 +444,13 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
|
||||||
BKPT(0x7777);
|
BKPT(0x7777);
|
||||||
}
|
}
|
||||||
JitArmTables::CompileInstruction(ops[i]);
|
JitArmTables::CompileInstruction(ops[i]);
|
||||||
|
|
||||||
|
// If we have a register that will never be used again, flush it.
|
||||||
|
for (int j : ~ops[i].gprInUse)
|
||||||
|
gpr.StoreFromRegister(j);
|
||||||
|
for (int j : ~ops[i].fprInUse)
|
||||||
|
fpr.StoreFromRegister(j);
|
||||||
|
|
||||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||||
{
|
{
|
||||||
// Don't do this yet
|
// Don't do this yet
|
||||||
|
|
|
@ -161,7 +161,8 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
|
||||||
ArmCRegs[regindex].PS1 = PS1;
|
ArmCRegs[regindex].PS1 = PS1;
|
||||||
|
|
||||||
_regs[preg][PS1].LoadToReg(regindex);
|
_regs[preg][PS1].LoadToReg(regindex);
|
||||||
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
|
if (preLoad)
|
||||||
|
emit->VLDR(ArmCRegs[regindex].Reg, R9, offset);
|
||||||
return ArmCRegs[regindex].Reg;
|
return ArmCRegs[regindex].Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +179,8 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad)
|
||||||
ArmCRegs[lastRegIndex].PS1 = PS1;
|
ArmCRegs[lastRegIndex].PS1 = PS1;
|
||||||
|
|
||||||
_regs[preg][PS1].LoadToReg(lastRegIndex);
|
_regs[preg][PS1].LoadToReg(lastRegIndex);
|
||||||
emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew);
|
if (preLoad)
|
||||||
|
emit->VLDR(ArmCRegs[lastRegIndex].Reg, R9, offsetNew);
|
||||||
return ArmCRegs[lastRegIndex].Reg;
|
return ArmCRegs[lastRegIndex].Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,3 +227,26 @@ void ArmFPRCache::Flush(FlushMode mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArmFPRCache::StoreFromRegister(u32 preg)
|
||||||
|
{
|
||||||
|
if (_regs[preg][0].GetType() != REG_NOTLOADED)
|
||||||
|
{
|
||||||
|
s16 offset = PPCSTATE_OFF(ps) + (preg * 16);
|
||||||
|
u32 regindex = _regs[preg][0].GetRegIndex();
|
||||||
|
emit->VSTR(ArmCRegs[regindex].Reg, R9, offset);
|
||||||
|
|
||||||
|
ArmCRegs[regindex].PPCReg = 33;
|
||||||
|
ArmCRegs[regindex].LastLoad = 0;
|
||||||
|
_regs[preg][0].Flush();
|
||||||
|
}
|
||||||
|
if (_regs[preg][1].GetType() != REG_NOTLOADED)
|
||||||
|
{
|
||||||
|
s16 offset = PPCSTATE_OFF(ps) + (preg * 16) + 8;
|
||||||
|
u32 regindex = _regs[preg][1].GetRegIndex();
|
||||||
|
emit->VSTR(ArmCRegs[regindex].Reg, R9, offset);
|
||||||
|
|
||||||
|
ArmCRegs[regindex].PPCReg = 33;
|
||||||
|
ArmCRegs[regindex].LastLoad = 0;
|
||||||
|
_regs[preg][1].Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -45,4 +45,6 @@ public:
|
||||||
void Flush(FlushMode mode = FLUSH_ALL);
|
void Flush(FlushMode mode = FLUSH_ALL);
|
||||||
ArmGen::ARMReg R0(u32 preg, bool preLoad = true); // Returns a cached register
|
ArmGen::ARMReg R0(u32 preg, bool preLoad = true); // Returns a cached register
|
||||||
ArmGen::ARMReg R1(u32 preg, bool preLoad = true);
|
ArmGen::ARMReg R1(u32 preg, bool preLoad = true);
|
||||||
|
|
||||||
|
void StoreFromRegister(u32 preg);
|
||||||
};
|
};
|
||||||
|
|
|
@ -300,3 +300,20 @@ void ArmRegCache::Flush(FlushMode mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArmRegCache::StoreFromRegister(u32 preg)
|
||||||
|
{
|
||||||
|
if (regs[preg].GetType() == REG_IMM)
|
||||||
|
{
|
||||||
|
// This changes the type over to a REG_REG and gets caught below.
|
||||||
|
BindToRegister(preg, true, true);
|
||||||
|
}
|
||||||
|
if (regs[preg].GetType() == REG_REG)
|
||||||
|
{
|
||||||
|
u32 regindex = regs[preg].GetRegIndex();
|
||||||
|
emit->STR(ArmCRegs[regindex].Reg, R9, PPCSTATE_OFF(gpr) + preg * 4);
|
||||||
|
|
||||||
|
ArmCRegs[regindex].PPCReg = 33;
|
||||||
|
ArmCRegs[regindex].LastLoad = 0;
|
||||||
|
regs[preg].Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -135,4 +135,6 @@ public:
|
||||||
// Public function doesn't kill immediates
|
// Public function doesn't kill immediates
|
||||||
// In reality when you call R(u32) it'll bind an immediate there
|
// In reality when you call R(u32) it'll bind an immediate there
|
||||||
void BindToRegister(u32 preg, bool doLoad = true);
|
void BindToRegister(u32 preg, bool doLoad = true);
|
||||||
|
|
||||||
|
void StoreFromRegister(u32 preg);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue