From dca457e6dfd2bfb76605a9a5fec99d6540e85cf0 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 19 Nov 2013 15:04:41 +0100 Subject: [PATCH] Optimize multiple sv.s and lv.s calls on ARM. Also some cleanup. --- Core/MIPS/ARM/ArmCompVFPU.cpp | 28 ++++++++++++++++++++-------- Core/MIPS/ARM/ArmJit.cpp | 11 +++++------ Core/MIPS/ARM/ArmRegCache.h | 1 + 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 77973d8f45..645f8c8b76 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -241,7 +241,7 @@ namespace MIPSComp void Jit::Comp_SV(MIPSOpcode op) { CONDITIONAL_DISABLE; - s32 imm = (signed short)(op&0xFFFC); + s32 offset = (signed short)(op & 0xFFFC); int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5); MIPSGPReg rs = _RS; @@ -250,19 +250,24 @@ namespace MIPSComp { case 50: //lv.s // VI(vt) = Memory::Read_U32(addr); { - // TODO: Fastpath like FPULS. + if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) { + gpr.MapRegAsPointer(rs); + fpr.MapRegV(vt, MAP_NOINIT | MAP_DIRTY); + VLDR(fpr.V(vt), gpr.RPtr(rs), offset); + break; + } // CC might be set by slow path below, so load regs first. fpr.MapRegV(vt, MAP_DIRTY | MAP_NOINIT); if (gpr.IsImm(rs)) { - u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF; + u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF; gpr.SetRegImm(R0, addr + (u32)Memory::base); } else { gpr.MapReg(rs); if (g_Config.bFastMemory) { - SetR0ToEffectiveAddress(rs, imm); + SetR0ToEffectiveAddress(rs, offset); } else { - SetCCAndR0ForSafeAddress(rs, imm, R1); + SetCCAndR0ForSafeAddress(rs, offset, R1); doCheck = true; } ADD(R0, R0, MEMBASEREG); @@ -290,17 +295,24 @@ namespace MIPSComp case 58: //sv.s // Memory::Write_U32(VI(vt), addr); { + if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) { + gpr.MapRegAsPointer(rs); + fpr.MapRegV(vt, 0); + VSTR(fpr.V(vt), gpr.RPtr(rs), offset); + break; + } + // CC might be set by slow path below, so load regs first. fpr.MapRegV(vt); if (gpr.IsImm(rs)) { - u32 addr = (imm + gpr.GetImm(rs)) & 0x3FFFFFFF; + u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF; gpr.SetRegImm(R0, addr + (u32)Memory::base); } else { gpr.MapReg(rs); if (g_Config.bFastMemory) { - SetR0ToEffectiveAddress(rs, imm); + SetR0ToEffectiveAddress(rs, offset); } else { - SetCCAndR0ForSafeAddress(rs, imm, R1); + SetCCAndR0ForSafeAddress(rs, offset, R1); doCheck = true; } ADD(R0, R0, MEMBASEREG); diff --git a/Core/MIPS/ARM/ArmJit.cpp b/Core/MIPS/ARM/ArmJit.cpp index e170072748..dcf78937c5 100644 --- a/Core/MIPS/ARM/ArmJit.cpp +++ b/Core/MIPS/ARM/ArmJit.cpp @@ -372,12 +372,12 @@ void Jit::MovToPC(ARMReg r) { void Jit::SaveDowncount() { if (jo.downcountInRegister) - STR(R7, CTXREG, offsetof(MIPSState, downcount)); + STR(DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount)); } void Jit::RestoreDowncount() { if (jo.downcountInRegister) - LDR(R7, CTXREG, offsetof(MIPSState, downcount)); + LDR(DOWNCOUNTREG, CTXREG, offsetof(MIPSState, downcount)); } void Jit::WriteDownCount(int offset) @@ -386,12 +386,12 @@ void Jit::WriteDownCount(int offset) int theDowncount = js.downcountAmount + offset; Operand2 op2; if (TryMakeOperand2(theDowncount, op2)) { - SUBS(R7, R7, op2); + SUBS(DOWNCOUNTREG, DOWNCOUNTREG, op2); } else { // Should be fine to use R2 here, flushed the regcache anyway. // If js.downcountAmount can be expressed as an Imm8, we don't need this anyway. gpr.SetRegImm(R2, theDowncount); - SUBS(R7, R7, R2); + SUBS(DOWNCOUNTREG, DOWNCOUNTREG, R2); } } else { int theDowncount = js.downcountAmount + offset; @@ -399,14 +399,13 @@ void Jit::WriteDownCount(int offset) Operand2 op2; if (TryMakeOperand2(theDowncount, op2)) { SUBS(R1, R1, op2); - STR(R1, CTXREG, offsetof(MIPSState, downcount)); } else { // Should be fine to use R2 here, flushed the regcache anyway. // If js.downcountAmount can be expressed as an Imm8, we don't need this anyway. gpr.SetRegImm(R2, theDowncount); SUBS(R1, R1, R2); - STR(R1, CTXREG, offsetof(MIPSState, downcount)); } + STR(R1, CTXREG, offsetof(MIPSState, downcount)); } } diff --git a/Core/MIPS/ARM/ArmRegCache.h b/Core/MIPS/ARM/ArmRegCache.h index cb980b43e2..e1f7393a77 100644 --- a/Core/MIPS/ARM/ArmRegCache.h +++ b/Core/MIPS/ARM/ArmRegCache.h @@ -25,6 +25,7 @@ using namespace ArmGen; #define CTXREG (R10) #define MEMBASEREG (R11) +#define DOWNCOUNTREG (R7) // R2 to R8: mapped MIPS regs // R9 = code pointers