From bc9c3db3038e20bc7cde4344ae0ca7fd425d14f1 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Fri, 11 Jan 2013 17:25:54 +0100 Subject: [PATCH] Armjit: Add option for fastmem. Small optimization. --- Core/MIPS/ARM/ArmCompALU.cpp | 30 +++++++------------- Core/MIPS/ARM/ArmCompBranch.cpp | 3 +- Core/MIPS/ARM/ArmCompLoadStore.cpp | 44 +++++++++++++++--------------- Core/MIPS/ARM/ArmRegCache.cpp | 19 +++++++++---- Core/MIPS/ARM/ArmRegCache.h | 5 ++-- android/jni/MenuScreens.cpp | 6 ++-- 6 files changed, 54 insertions(+), 53 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 8b522b812c..3b4127dd67 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -43,10 +43,7 @@ namespace MIPSComp if (gpr.IsImm(rs)) { gpr.SetImm(rt, (*eval)(gpr.GetImm(rs), uimm)); } else { - gpr.SpillLock(rs, rt); - gpr.MapReg(rt, MAP_DIRTY); - gpr.MapReg(rs); - gpr.ReleaseSpillLocks(); + gpr.MapDirtyIn(rt, rs); // TODO: Special case when uimm can be represented as an Operand2 Operand2 op2; if (TryMakeOperand2(uimm, op2)) { @@ -76,13 +73,14 @@ namespace MIPSComp } else if (rs == 0) { // add to zero register = immediate gpr.SetImm(rt, (u32)simm); } else { - gpr.SpillLock(rs, rt); - gpr.MapReg(rt, MAP_DIRTY); - gpr.MapReg(rs); - gpr.ReleaseSpillLocks(); + gpr.MapDirtyIn(rt, rs); Operand2 op2; - if (TryMakeOperand2(simm, op2)) { - ADD(gpr.R(rt), gpr.R(rs), op2); + bool negated; + if (TryMakeOperand2_AllowNegation(simm, op2, &negated)) { + if (!negated) + ADD(gpr.R(rt), gpr.R(rs), op2); + else + SUB(gpr.R(rt), gpr.R(rs), op2); } else { ARMABI_MOVI2R(R0, (u32)simm); ADD(gpr.R(rt), gpr.R(rs), R0); @@ -96,11 +94,7 @@ namespace MIPSComp case 14: CompImmLogic(rs, rt, uimm, &ARMXEmitter::EOR, &EvalXor); break; case 10: // R(rt) = (s32)R(rs) < simm; break; //slti - gpr.SpillLock(rt, rs); - gpr.MapReg(rs); - gpr.MapReg(rt, MAP_DIRTY); - gpr.ReleaseSpillLocks(); - + gpr.MapDirtyIn(rt, rs); { Operand2 op2; if (TryMakeOperand2(simm, op2)) { @@ -253,11 +247,7 @@ namespace MIPSComp int rt = _RT; int sa = _SA; - gpr.SpillLock(rd, rt); - gpr.MapReg(rt); - gpr.MapReg(rd, MAP_DIRTY); - gpr.ReleaseSpillLocks(); - + gpr.MapDirtyIn(rd, rt); MOV(gpr.R(rd), Operand2(sa, shiftType, gpr.R(rt))); } diff --git a/Core/MIPS/ARM/ArmCompBranch.cpp b/Core/MIPS/ARM/ArmCompBranch.cpp index 20d1fa18b2..32d75392b6 100644 --- a/Core/MIPS/ARM/ArmCompBranch.cpp +++ b/Core/MIPS/ARM/ArmCompBranch.cpp @@ -425,7 +425,8 @@ void Jit::Comp_Syscall(u32 op) { FlushAll(); - ARMABI_CallFunctionC((void *)&CallSyscall, op); + ARMABI_MOVI2R(R0, op); + QuickCallFunction(R1, (void *)&CallSyscall); WriteSyscallExit(); js.compiling = false; diff --git a/Core/MIPS/ARM/ArmCompLoadStore.cpp b/Core/MIPS/ARM/ArmCompLoadStore.cpp index 782bfc04ec..1fdba9d5fd 100644 --- a/Core/MIPS/ARM/ArmCompLoadStore.cpp +++ b/Core/MIPS/ARM/ArmCompLoadStore.cpp @@ -52,20 +52,20 @@ namespace MIPSComp case 35: //R(rt) = ReadMem32(addr); //lw case 36: //R(rt) = ReadMem8 (addr); break; //lbu - if (true || g_Config.bFastMemory) { - gpr.SpillLock(rt, rs); - gpr.MapReg(rt, MAP_DIRTY); - gpr.MapReg(rs); - gpr.ReleaseSpillLocks(); - + if (g_Config.bFastMemory) { + gpr.MapDirtyIn(rt, rs); Operand2 op2; - if (TryMakeOperand2(offset, op2)) { - ADD(R0, gpr.R(rs), op2); + if (offset) { + if (TryMakeOperand2(offset, op2)) { + ADD(R0, gpr.R(rs), op2); + } else { + ARMABI_MOVI2R(R0, (u32)offset); + ADD(R0, gpr.R(rs), R0); + } + BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF } else { - ARMABI_MOVI2R(R0, (u32)offset); - ADD(R0, gpr.R(rs), R0); + BIC(R0, gpr.R(rs), Operand2(0xC0, 4)); // &= 0x3FFFFFFF } - BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF ADD(R0, R0, R11); // TODO: Merge with next instruction if (o == 35) { LDR(gpr.R(rt), R0); @@ -84,20 +84,20 @@ namespace MIPSComp case 40: //sb case 43: //WriteMem32(addr, R(rt)); break; //sw - if (true || g_Config.bFastMemory) { - gpr.SpillLock(rt, rs); - gpr.MapReg(rt); - gpr.MapReg(rs); - gpr.ReleaseSpillLocks(); - + if (g_Config.bFastMemory) { + gpr.MapInIn(rt, rs); Operand2 op2; - if (TryMakeOperand2(offset, op2)) { - ADD(R0, gpr.R(rs), op2); + if (offset) { + if (TryMakeOperand2(offset, op2)) { + ADD(R0, gpr.R(rs), op2); + } else { + ARMABI_MOVI2R(R0, (u32)offset); + ADD(R0, gpr.R(rs), R0); + } + BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF } else { - ARMABI_MOVI2R(R0, (u32)offset); - ADD(R0, gpr.R(rs), R0); + BIC(R0, gpr.R(rs), Operand2(0xC0, 4)); // &= 0x3FFFFFFF } - BIC(R0, R0, Operand2(0xC0, 4)); // &= 0x3FFFFFFF ADD(R0, R0, R11); if (o == 43) { STR(R0, gpr.R(rt)); diff --git a/Core/MIPS/ARM/ArmRegCache.cpp b/Core/MIPS/ARM/ArmRegCache.cpp index 14587b4562..277fbb33b0 100644 --- a/Core/MIPS/ARM/ArmRegCache.cpp +++ b/Core/MIPS/ARM/ArmRegCache.cpp @@ -125,18 +125,25 @@ allocate: return INVALID_REG; } -void ArmRegCache::MapDirtyIn(MIPSReg rd, MIPSReg rs) { +void ArmRegCache::MapInIn(MIPSReg rd, MIPSReg rs) { SpillLock(rd, rs); - // bool overlap == rd == rs - MapReg(rd, MAP_DIRTY); // can get rid of INITVAL in some cases + MapReg(rd); MapReg(rs); ReleaseSpillLocks(); } -void ArmRegCache::MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt) { +void ArmRegCache::MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad) { + SpillLock(rd, rs); + bool overlap = avoidLoad && rd == rs; + MapReg(rd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT)); + MapReg(rs); + ReleaseSpillLocks(); +} + +void ArmRegCache::MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad) { SpillLock(rd, rs, rt); - // bool overlap == rd == rs || rt == rd || rs == rt; - MapReg(rd, MAP_DIRTY); // can get rid of INITVAL in some cases + bool overlap = avoidLoad && (rd == rs || rd == rt); + MapReg(rd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT)); MapReg(rt); MapReg(rs); ReleaseSpillLocks(); diff --git a/Core/MIPS/ARM/ArmRegCache.h b/Core/MIPS/ARM/ArmRegCache.h index 8bdaa8a40c..691bb9d0c7 100644 --- a/Core/MIPS/ARM/ArmRegCache.h +++ b/Core/MIPS/ARM/ArmRegCache.h @@ -85,8 +85,9 @@ public: // Returns an ARM register containing the requested MIPS register. ARMReg MapReg(MIPSReg reg, int mapFlags = 0); - void MapDirtyIn(MIPSReg rd, MIPSReg rs); - void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt); + void MapInIn(MIPSReg rd, MIPSReg rs); + void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true); + void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true); void FlushArmReg(ARMReg r); void FlushMipsReg(MIPSReg r); diff --git a/android/jni/MenuScreens.cpp b/android/jni/MenuScreens.cpp index af4d878490..6d5759bdfd 100644 --- a/android/jni/MenuScreens.cpp +++ b/android/jni/MenuScreens.cpp @@ -287,10 +287,12 @@ void SettingsScreen::render() { g_Config.iWindowZoom = doubleRes ? 2 : 1; } UICheckBox(GEN_ID, x, y += stride, "Hardware Transform", ALIGN_TOPLEFT, &g_Config.bHardwareTransform); - UICheckBox(GEN_ID, x, y += stride, "Use VBO for drawing", ALIGN_TOPLEFT, &g_Config.bUseVBO); + UICheckBox(GEN_ID, x, y += stride, "Draw using VBO", ALIGN_TOPLEFT, &g_Config.bUseVBO); bool useJit = g_Config.iCpuCore == CPU_JIT; - UICheckBox(GEN_ID, x, y += stride, "Use Dynarec (JIT)", ALIGN_TOPLEFT, &useJit); + UICheckBox(GEN_ID, x, y += stride, "JIT (Dynarec)", ALIGN_TOPLEFT, &useJit); + if (g_Config.iCpuCore == CPU_JIT) + UICheckBox(GEN_ID, x + 350, y, "Fastmem (unstable)", ALIGN_TOPLEFT, &g_Config.bFastMemory); g_Config.iCpuCore = useJit ? CPU_JIT : CPU_INTERPRETER; // ui_draw2d.DrawText(UBUNTU48, "much faster JIT coming later", x, y+=50, 0xcFFFFFFF, ALIGN_LEFT); UICheckBox(GEN_ID, x, y += stride, "On-screen Touch Controls", ALIGN_TOPLEFT, &g_Config.bShowTouchControls);