From e3a04aa2d2578bcb59aa5d977bea1efc2a1fcf2f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 12 Oct 2014 14:23:59 -0700 Subject: [PATCH] x86jit: Preload sp and similar regs used often. This can help us avoid using a temporary. Very tiny performance improvement. --- Core/MIPS/MIPSAnalyst.cpp | 34 +++++++++++++++++++-------------- Core/MIPS/MIPSAnalyst.h | 3 ++- Core/MIPS/x86/CompLoadStore.cpp | 2 +- Core/MIPS/x86/CompVFPU.cpp | 12 ++++++++---- Core/MIPS/x86/JitSafeMem.cpp | 6 ++++++ 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 9dc3ea4cee..3cf3262f40 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -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() { diff --git a/Core/MIPS/MIPSAnalyst.h b/Core/MIPS/MIPSAnalyst.h index 4eaefbb91b..fa6188913d 100644 --- a/Core/MIPS/MIPSAnalyst.h +++ b/Core/MIPS/MIPSAnalyst.h @@ -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; diff --git a/Core/MIPS/x86/CompLoadStore.cpp b/Core/MIPS/x86/CompLoadStore.cpp index f56afb3cbf..4884c0057c 100644 --- a/Core/MIPS/x86/CompLoadStore.cpp +++ b/Core/MIPS/x86/CompLoadStore.cpp @@ -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.) diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 12359aa4ee..e60a753483 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -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); diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index 086ac7a5c9..a79052d1cd 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -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()