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
This commit is contained in:
skidau 2010-08-27 09:41:48 +00:00
parent d5bae7e0ad
commit eaa3371f92
2 changed files with 135 additions and 147 deletions

View File

@ -77,7 +77,7 @@ void Jit64AsmRoutineManager::Generate()
dispatcher = GetCodePtr(); dispatcher = GetCodePtr();
// The result of slice decrementation should be in flags if somebody jumped here // The result of slice decrementation should be in flags if somebody jumped here
// IMPORTANT - We jump on negative, not carry!!! // 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) if (Core::g_CoreStartupParameter.bEnableDebugging)
{ {
@ -95,8 +95,72 @@ void Jit64AsmRoutineManager::Generate()
MOV(32, R(EAX), M(&PowerPC::ppcState.pc)); MOV(32, R(EAX), M(&PowerPC::ppcState.pc));
dispatcherPcInEAX = GetCodePtr(); dispatcherPcInEAX = GetCodePtr();
FixupBranch needinst = J(true); #ifdef JIT_UNLIMITED_ICACHE
const u8* haveinst = GetCodePtr(); 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)); TEST(32, R(EAX), Imm32(0xFC));
FixupBranch notfound = J_CC(CC_NZ); FixupBranch notfound = J_CC(CC_NZ);
@ -133,7 +197,7 @@ void Jit64AsmRoutineManager::Generate()
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions)); ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
MOV(32, R(EAX), M(&NPC)); MOV(32, R(EAX), M(&NPC));
MOV(32, M(&PC), R(EAX)); MOV(32, M(&PC), R(EAX));
JMP(dispatcher); JMP(dispatcher, true);
SetJumpTarget(bail); SetJumpTarget(bail);
doTiming = GetCodePtr(); doTiming = GetCodePtr();
@ -157,77 +221,6 @@ void Jit64AsmRoutineManager::Generate()
ABI_PopAllCalleeSavedRegsAndAdjustStack(); ABI_PopAllCalleeSavedRegsAndAdjustStack();
RET(); 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(); breakpointBailout = GetCodePtr();
//Landing pad for drec space //Landing pad for drec space
ABI_PopAllCalleeSavedRegsAndAdjustStack(); ABI_PopAllCalleeSavedRegsAndAdjustStack();

View File

@ -79,7 +79,7 @@ void JitILAsmRoutineManager::Generate()
//This is the place for CPUCompare! //This is the place for CPUCompare!
//The result of slice decrement should be in flags if somebody jumped here //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) if (Core::g_CoreStartupParameter.bEnableDebugging)
{ {
@ -97,75 +97,6 @@ void JitILAsmRoutineManager::Generate()
MOV(32, R(EAX), M(&PowerPC::ppcState.pc)); MOV(32, R(EAX), M(&PowerPC::ppcState.pc));
dispatcherPcInEAX = GetCodePtr(); 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<void *>(&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<void *>(&PowerPC::CheckExceptions));
MOV(32, R(EAX), M(&NPC));
MOV(32, M(&PC), R(EAX));
JMP(dispatcher);
SetJumpTarget(bail);
doTiming = GetCodePtr();
ABI_CallFunction(reinterpret_cast<void *>(&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<void *>(&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 #ifdef JIT_UNLIMITED_ICACHE
u32 mask = 0; u32 mask = 0;
FixupBranch no_mem; FixupBranch no_mem;
@ -221,7 +152,7 @@ void JitILAsmRoutineManager::Generate()
} }
if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) if (Core::g_CoreStartupParameter.bWii || Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack)
SetJumpTarget(exit_mem); SetJumpTarget(exit_mem);
if (Core::g_CoreStartupParameter.bWii) if (Core::g_CoreStartupParameter.bWii && (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack))
SetJumpTarget(exit_vmem); SetJumpTarget(exit_vmem);
#else #else
#ifdef _M_IX86 #ifdef _M_IX86
@ -232,7 +163,71 @@ void JitILAsmRoutineManager::Generate()
MOV(32, R(EAX), MComplex(RBX, RAX, SCALE_1, 0)); MOV(32, R(EAX), MComplex(RBX, RAX, SCALE_1, 0));
#endif #endif
#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<void *>(&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<void *>(&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<void *>(&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<void *>(&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(); GenerateCommon();
} }