From eaa3371f92fd1b2cc8a8fd19413317a904927689 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 27 Aug 2010 09:41:48 +0000 Subject: [PATCH] Further optimised the JIT cache lookup. Attempted to fix the Wii games in ICC builds. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6136 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp | 143 +++++++++--------- .../Core/Src/PowerPC/Jit64IL/JitILAsm.cpp | 139 ++++++++--------- 2 files changed, 135 insertions(+), 147 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index 511e1b5dbb..cc8b6edfda 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -77,7 +77,7 @@ void Jit64AsmRoutineManager::Generate() dispatcher = GetCodePtr(); // The result of slice decrementation should be in flags if somebody jumped here // IMPORTANT - We jump on negative, not carry!!! - FixupBranch bail = J_CC(CC_BE); + FixupBranch bail = J_CC(CC_BE, true); if (Core::g_CoreStartupParameter.bEnableDebugging) { @@ -95,8 +95,72 @@ void Jit64AsmRoutineManager::Generate() MOV(32, R(EAX), M(&PowerPC::ppcState.pc)); dispatcherPcInEAX = GetCodePtr(); - FixupBranch needinst = J(true); - const u8* haveinst = GetCodePtr(); +#ifdef JIT_UNLIMITED_ICACHE + u32 mask = 0; + FixupBranch no_mem; + FixupBranch exit_mem; + FixupBranch exit_vmem; + if (Core::g_CoreStartupParameter.bWii) + mask = JIT_ICACHE_EXRAM_BIT; + if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + mask |= JIT_ICACHE_VMEM_BIT; + if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + { + TEST(32, R(EAX), Imm32(mask)); + no_mem = J_CC(CC_NZ); + } + AND(32, R(EAX), Imm32(JIT_ICACHE_MASK)); +#ifdef _M_IX86 + MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICache())); +#else + MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICache())); + MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); +#endif + if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + { + exit_mem = J(); + SetJumpTarget(no_mem); + } + if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + { + TEST(32, R(EAX), Imm32(JIT_ICACHE_VMEM_BIT)); + FixupBranch no_vmem = J_CC(CC_Z); + AND(32, R(EAX), Imm32(JIT_ICACHE_MASK)); +#ifdef _M_IX86 + MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICacheVMEM())); +#else + MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICacheVMEM())); + MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); +#endif + if (Core::g_CoreStartupParameter.bWii) exit_vmem = J(); + SetJumpTarget(no_vmem); + } + if (Core::g_CoreStartupParameter.bWii) + { + TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT)); + FixupBranch no_exram = J_CC(CC_Z); + AND(32, R(EAX), Imm32(JIT_ICACHEEX_MASK)); +#ifdef _M_IX86 + MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICacheEx())); +#else + MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICacheEx())); + MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); +#endif + SetJumpTarget(no_exram); + } + if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + SetJumpTarget(exit_mem); + if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack)) + SetJumpTarget(exit_vmem); +#else +#ifdef _M_IX86 + AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); + MOV(32, R(EBX), Imm32((u32)Memory::base)); + MOV(32, R(EAX), MComplex(EBX, EAX, SCALE_1, 0)); +#else + MOV(32, R(EAX), MComplex(RBX, RAX, SCALE_1, 0)); +#endif +#endif TEST(32, R(EAX), Imm32(0xFC)); FixupBranch notfound = J_CC(CC_NZ); @@ -133,7 +197,7 @@ void Jit64AsmRoutineManager::Generate() ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); MOV(32, R(EAX), M(&NPC)); MOV(32, M(&PC), R(EAX)); - JMP(dispatcher); + JMP(dispatcher, true); SetJumpTarget(bail); doTiming = GetCodePtr(); @@ -157,77 +221,6 @@ void Jit64AsmRoutineManager::Generate() ABI_PopAllCalleeSavedRegsAndAdjustStack(); RET(); - - SetJumpTarget(needinst); -#ifdef JIT_UNLIMITED_ICACHE - u32 mask = 0; - FixupBranch no_mem; - FixupBranch exit_mem; - FixupBranch exit_vmem; - if (Core::g_CoreStartupParameter.bWii) - mask = JIT_ICACHE_EXRAM_BIT; - if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - mask |= JIT_ICACHE_VMEM_BIT; - if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - { - TEST(32, R(EAX), Imm32(mask)); - no_mem = J_CC(CC_NZ); - } - AND(32, R(EAX), Imm32(JIT_ICACHE_MASK)); -#ifdef _M_IX86 - MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICache())); -#else - MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICache())); - MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); -#endif - if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - { - exit_mem = J(); - SetJumpTarget(no_mem); - } - if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - { - TEST(32, R(EAX), Imm32(JIT_ICACHE_VMEM_BIT)); - FixupBranch no_vmem = J_CC(CC_Z); - AND(32, R(EAX), Imm32(JIT_ICACHE_MASK)); -#ifdef _M_IX86 - MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICacheVMEM())); -#else - MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICacheVMEM())); - MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); -#endif - if (Core::g_CoreStartupParameter.bWii) exit_vmem = J(); - SetJumpTarget(no_vmem); - } - if (Core::g_CoreStartupParameter.bWii) - { - TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT)); - FixupBranch no_exram = J_CC(CC_Z); - AND(32, R(EAX), Imm32(JIT_ICACHEEX_MASK)); -#ifdef _M_IX86 - MOV(32, R(EAX), MDisp(EAX, (u32)jit->GetBlockCache()->GetICacheEx())); -#else - MOV(64, R(RSI), Imm64((u64)jit->GetBlockCache()->GetICacheEx())); - MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); -#endif - SetJumpTarget(no_exram); - } - if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - SetJumpTarget(exit_mem); - if (Core::g_CoreStartupParameter.bWii) - SetJumpTarget(exit_vmem); -#else -#ifdef _M_IX86 - AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); - MOV(32, R(EBX), Imm32((u32)Memory::base)); - MOV(32, R(EAX), MComplex(EBX, EAX, SCALE_1, 0)); -#else - MOV(32, R(EAX), MComplex(RBX, RAX, SCALE_1, 0)); -#endif -#endif - JMP(haveinst, true); - - breakpointBailout = GetCodePtr(); //Landing pad for drec space ABI_PopAllCalleeSavedRegsAndAdjustStack(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index 38ba5ec1ca..cd2708512f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -79,7 +79,7 @@ void JitILAsmRoutineManager::Generate() //This is the place for CPUCompare! //The result of slice decrement should be in flags if somebody jumped here - FixupBranch bail = J_CC(CC_BE); + FixupBranch bail = J_CC(CC_BE, true); if (Core::g_CoreStartupParameter.bEnableDebugging) { @@ -97,75 +97,6 @@ void JitILAsmRoutineManager::Generate() MOV(32, R(EAX), M(&PowerPC::ppcState.pc)); dispatcherPcInEAX = GetCodePtr(); - FixupBranch needinst = J(true); - const u8* haveinst = GetCodePtr(); - - TEST(32, R(EAX), Imm32(0xFC)); - FixupBranch notfound = J_CC(CC_NZ); - BSWAP(32, EAX); - //IDEA - we have 26 bits, why not just use offsets from base of code? - if (enableDebug) - { - ADD(32, M(&PowerPC::ppcState.DebugCount), Imm8(1)); - } - //grab from list and jump to it -#ifdef _M_IX86 - MOV(32, R(EDX), ImmPtr(jit->GetBlockCache()->GetCodePointers())); - JMPptr(MComplex(EDX, EAX, 4, 0)); -#else - JMPptr(MComplex(R15, RAX, 8, 0)); -#endif - SetJumpTarget(notfound); - - //Ok, no block, let's jit -#ifdef _M_IX86 - ABI_AlignStack(4); - PUSH(32, M(&PowerPC::ppcState.pc)); - CALL(reinterpret_cast(&Jit)); - ABI_RestoreStack(4); -#else - MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc)); - CALL((void *)&Jit); -#endif - JMP(dispatcherNoCheck); // no point in special casing this - - //FP blocks test for FPU available, jump here if false - fpException = AlignCode4(); - MOV(32, R(EAX), M(&PC)); - MOV(32, M(&NPC), R(EAX)); - OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); - ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); - MOV(32, R(EAX), M(&NPC)); - MOV(32, M(&PC), R(EAX)); - JMP(dispatcher); - - SetJumpTarget(bail); - doTiming = GetCodePtr(); - - ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); - - testExceptions = GetCodePtr(); - TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); - FixupBranch skipExceptions = J_CC(CC_Z); - MOV(32, R(EAX), M(&PC)); - MOV(32, M(&NPC), R(EAX)); - ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); - MOV(32, R(EAX), M(&NPC)); - MOV(32, M(&PC), R(EAX)); - SetJumpTarget(skipExceptions); - - TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); - J_CC(CC_Z, outerLoop, true); - //Landing pad for drec space - ABI_PopAllCalleeSavedRegsAndAdjustStack(); - RET(); - - breakpointBailout = GetCodePtr(); - //Landing pad for drec space - ABI_PopAllCalleeSavedRegsAndAdjustStack(); - RET(); - - SetJumpTarget(needinst); #ifdef JIT_UNLIMITED_ICACHE u32 mask = 0; FixupBranch no_mem; @@ -221,7 +152,7 @@ void JitILAsmRoutineManager::Generate() } if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) SetJumpTarget(exit_mem); - if (Core::g_CoreStartupParameter.bWii) + if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack)) SetJumpTarget(exit_vmem); #else #ifdef _M_IX86 @@ -232,7 +163,71 @@ void JitILAsmRoutineManager::Generate() MOV(32, R(EAX), MComplex(RBX, RAX, SCALE_1, 0)); #endif #endif - JMP(haveinst, true); + + TEST(32, R(EAX), Imm32(0xFC)); + FixupBranch notfound = J_CC(CC_NZ); + BSWAP(32, EAX); + //IDEA - we have 26 bits, why not just use offsets from base of code? + if (enableDebug) + { + ADD(32, M(&PowerPC::ppcState.DebugCount), Imm8(1)); + } + //grab from list and jump to it +#ifdef _M_IX86 + MOV(32, R(EDX), ImmPtr(jit->GetBlockCache()->GetCodePointers())); + JMPptr(MComplex(EDX, EAX, 4, 0)); +#else + JMPptr(MComplex(R15, RAX, 8, 0)); +#endif + SetJumpTarget(notfound); + + //Ok, no block, let's jit +#ifdef _M_IX86 + ABI_AlignStack(4); + PUSH(32, M(&PowerPC::ppcState.pc)); + CALL(reinterpret_cast(&Jit)); + ABI_RestoreStack(4); +#else + MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc)); + CALL((void *)&Jit); +#endif + JMP(dispatcherNoCheck); // no point in special casing this + + //FP blocks test for FPU available, jump here if false + fpException = AlignCode4(); + MOV(32, R(EAX), M(&PC)); + MOV(32, M(&NPC), R(EAX)); + OR(32, M(&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE)); + ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); + MOV(32, R(EAX), M(&NPC)); + MOV(32, M(&PC), R(EAX)); + JMP(dispatcher, true); + + SetJumpTarget(bail); + doTiming = GetCodePtr(); + + ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); + + testExceptions = GetCodePtr(); + TEST(32, M(&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF)); + FixupBranch skipExceptions = J_CC(CC_Z); + MOV(32, R(EAX), M(&PC)); + MOV(32, M(&NPC), R(EAX)); + ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); + MOV(32, R(EAX), M(&NPC)); + MOV(32, M(&PC), R(EAX)); + SetJumpTarget(skipExceptions); + + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); + J_CC(CC_Z, outerLoop, true); + //Landing pad for drec space + ABI_PopAllCalleeSavedRegsAndAdjustStack(); + RET(); + + breakpointBailout = GetCodePtr(); + //Landing pad for drec space + ABI_PopAllCalleeSavedRegsAndAdjustStack(); + RET(); GenerateCommon(); }