From eab010a0c010ccda6e2d2cb57ca148fb9be1ebb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 12 Oct 2014 14:09:35 +0200 Subject: [PATCH] x86 JIT: Sacrifice a register for a pointer to the MIPS context. Shrinks emitted x86 code considerably. Nice in 64-bit, but might be a bit too much in 32-bit though... Needs testing. --- Core/MIPS/x86/Asm.cpp | 8 ++++++++ Core/MIPS/x86/RegCache.cpp | 11 ++++++----- Core/MIPS/x86/RegCache.h | 6 ++++++ Core/MIPS/x86/RegCacheFPU.cpp | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Core/MIPS/x86/Asm.cpp b/Core/MIPS/x86/Asm.cpp index bdcfa0f712..d642f9e205 100644 --- a/Core/MIPS/x86/Asm.cpp +++ b/Core/MIPS/x86/Asm.cpp @@ -103,6 +103,14 @@ void AsmRoutineManager::Generate(MIPSState *mips, MIPSComp::Jit *jit) dispatcherNoCheck = GetCodePtr(); + // TODO: Find a less costly place to put this (or multiple..) +#ifdef _M_X64 + // From the start of the FP reg, a single byte offset can reach all GPR + all FPR (but no VFPUR) + MOV(64, R(CTXREG), ImmPtr(&mips->f[0])); +#else + MOV(32, R(CTXREG), ImmPtr(&mips->f[0])); +#endif + MOV(32, R(EAX), M(&mips->pc)); #ifdef _M_IX86 AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); diff --git a/Core/MIPS/x86/RegCache.cpp b/Core/MIPS/x86/RegCache.cpp index 14674d35d7..f0765b9cee 100644 --- a/Core/MIPS/x86/RegCache.cpp +++ b/Core/MIPS/x86/RegCache.cpp @@ -33,12 +33,12 @@ static const int allocationOrder[] = // On x64, RCX and RDX are the first args. CallProtectedFunction() assumes they're not regcached. #ifdef _M_X64 #ifdef _WIN32 - RSI, RDI, R13, R14, R8, R9, R10, R11, R12, + RSI, RDI, R13, R8, R9, R10, R11, R12, #else - RBP, R13, R14, R8, R9, R10, R11, R12, + RBP, R13, R8, R9, R10, R11, R12, #endif #elif _M_IX86 - ESI, EDI, EBP, EDX, ECX, // Let's try to free up EBX as well. + ESI, EDI, EDX, ECX, // Let's try to free up EBX as well. #endif }; @@ -218,8 +218,9 @@ const int *GPRRegCache::GetAllocationOrder(int &count) { OpArg GPRRegCache::GetDefaultLocation(MIPSGPReg reg) const { - if (reg < 32) - return M(&mips->r[reg]); + if (reg < 32) { + return MDisp(CTXREG, -128 + reg * 4); + } switch (reg) { case MIPS_REG_HI: return M(&mips->hi); diff --git a/Core/MIPS/x86/RegCache.h b/Core/MIPS/x86/RegCache.h index 297d59635d..930761ac11 100644 --- a/Core/MIPS/x86/RegCache.h +++ b/Core/MIPS/x86/RegCache.h @@ -31,6 +31,12 @@ using namespace Gen; #define NUM_MIPS_GPRS 36 +#ifdef _M_X64 +#define CTXREG R14 +#else +#define CTXREG EBP +#endif + struct MIPSCachedReg { OpArg location; bool away; // value not in source register diff --git a/Core/MIPS/x86/RegCacheFPU.cpp b/Core/MIPS/x86/RegCacheFPU.cpp index 865231d590..71cd63da87 100644 --- a/Core/MIPS/x86/RegCacheFPU.cpp +++ b/Core/MIPS/x86/RegCacheFPU.cpp @@ -20,6 +20,7 @@ #include "Common/Log.h" #include "Common/x64Emitter.h" #include "Core/MIPS/MIPSAnalyst.h" +#include "Core/MIPS/x86/RegCache.h" #include "Core/MIPS/x86/RegCacheFPU.h" u32 FPURegCache::tempValues[NUM_TEMPS]; @@ -215,7 +216,7 @@ void FPURegCache::Flush() { OpArg FPURegCache::GetDefaultLocation(int reg) const { if (reg < 32) { - return M(&mips->f[reg]); + return MDisp(CTXREG, reg * 4); } else if (reg < 32 + 128) { return M(&mips->v[voffset[reg - 32]]); } else {