x86jit: Preload sp and similar regs used often.

This can help us avoid using a temporary.

Very tiny performance improvement.
This commit is contained in:
Unknown W. Brackets 2014-10-12 14:23:59 -07:00
parent 6cb2c9c97d
commit e3a04aa2d2
5 changed files with 37 additions and 20 deletions

View file

@ -661,29 +661,35 @@ namespace MIPSAnalyst {
}
}
// Look forwards to find if a register is used again in this block.
// Don't think we use this yet.
bool IsRegisterUsed(MIPSGPReg reg, u32 addr) {
while (true) {
MIPSOpcode op = Memory::Read_Instruction(addr, true);
MIPSInfo info = MIPSGetInfo(op);
bool IsRegisterUsed(MIPSGPReg reg, u32 addr, int instrs) {
u32 end = addr + instrs * sizeof(u32);
while (addr < end) {
const MIPSOpcode op = Memory::Read_Instruction(addr, true);
const MIPSInfo info = MIPSGetInfo(op);
// Yes, used.
if ((info & IN_RS) && (MIPS_GET_RS(op) == reg))
return true;
if ((info & IN_RT) && (MIPS_GET_RT(op) == reg))
return true;
if ((info & IS_CONDBRANCH))
return true; // could also follow both paths
if ((info & IS_JUMP))
return true; // could also follow the path
// Clobbered, so not used.
if ((info & OUT_RT) && (MIPS_GET_RT(op) == reg))
return false; //the reg got clobbed! yay!
return false;
if ((info & OUT_RD) && (MIPS_GET_RD(op) == reg))
return false; //the reg got clobbed! yay!
return false;
if ((info & OUT_RA) && (reg == MIPS_REG_RA))
return false; //the reg got clobbed! yay!
return false;
// Bail early if we hit a branch (could follow each path for continuing?)
if ((info & IS_CONDBRANCH) || (info & IS_JUMP)) {
// Still need to check the delay slot (so end after it.)
// We'll assume likely are taken.
end = addr + 8;
}
addr += 4;
}
return true;
return false;
}
void HashFunctions() {

View file

@ -77,7 +77,8 @@ namespace MIPSAnalyst
AnalysisResults Analyze(u32 address);
bool IsRegisterUsed(MIPSGPReg reg, u32 addr);
// This tells us if the reg is used within intrs of addr (also includes likely delay slots.)
bool IsRegisterUsed(MIPSGPReg reg, u32 addr, int instrs);
struct AnalyzedFunction {
u32 start;

View file

@ -121,7 +121,7 @@ namespace MIPSComp
shiftReg = R9;
#endif
gpr.Lock(rt);
gpr.Lock(rt, rs);
gpr.MapReg(rt, true, !isStore);
// Grab the offset from alignment for shifting (<< 3 for bytes -> bits.)

View file

@ -233,6 +233,7 @@ void Jit::Comp_SV(MIPSOpcode op) {
{
case 50: //lv.s // VI(vt) = Memory::Read_U32(addr);
{
gpr.Lock(rs);
gpr.MapReg(rs, true, false);
fpr.MapRegV(vt, MAP_NOINIT);
@ -256,7 +257,8 @@ void Jit::Comp_SV(MIPSOpcode op) {
case 58: //sv.s // Memory::Write_U32(VI(vt), addr);
{
gpr.MapReg(rs, true, true);
gpr.Lock(rs);
gpr.MapReg(rs, true, false);
// Even if we don't use real SIMD there's still 8 or 16 scalar float registers.
fpr.MapRegV(vt, 0);
@ -302,7 +304,7 @@ void Jit::Comp_SVQ(MIPSOpcode op)
}
DISABLE;
gpr.MapReg(rs, true, true);
gpr.MapReg(rs, true, false);
gpr.FlushLockX(ECX);
u8 vregs[4];
GetVectorRegs(vregs, V_Quad, vt);
@ -364,7 +366,8 @@ void Jit::Comp_SVQ(MIPSOpcode op)
case 54: //lv.q
{
gpr.MapReg(rs, true, true);
gpr.Lock(rs);
gpr.MapReg(rs, true, false);
u8 vregs[4];
GetVectorRegs(vregs, V_Quad, vt);
@ -396,7 +399,8 @@ void Jit::Comp_SVQ(MIPSOpcode op)
case 62: //sv.q
{
gpr.MapReg(rs, true, true);
gpr.Lock(rs);
gpr.MapReg(rs, true, false);
u8 vregs[4];
GetVectorRegs(vregs, V_Quad, vt);

View file

@ -55,6 +55,12 @@ JitSafeMem::JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask)
iaddr_ = (u32) -1;
fast_ = g_Config.bFastMemory || raddr == MIPS_REG_SP;
// If raddr_ is going to get loaded soon, load it now for more optimal code.
// We assume that it was already locked.
const int LOOKAHEAD_OPS = 3;
if (!jit_->gpr.R(raddr_).IsImm() && MIPSAnalyst::IsRegisterUsed(raddr_, jit_->js.compilerPC + 4, LOOKAHEAD_OPS))
jit_->gpr.MapReg(raddr_, true, false);
}
void JitSafeMem::SetFar()