From f158ca82af7c94323c0d7093e9e24b3d4f15f897 Mon Sep 17 00:00:00 2001 From: skidau <skidau@gmail.com> Date: Mon, 5 Jul 2010 02:05:47 +0000 Subject: [PATCH] Debugger enhancements: * Added JIT breakpoints functionality * Added a menu option to disable the JIT block cache * Enabled single stepping in JIT mode as a run-time option (automatically enabled when the debugger is used) * Enabled the missing JIT Off menu options * Removed the JIT Unlimited Cache hack git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5833 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/CoreParameter.cpp | 2 +- Source/Core/Core/Src/CoreParameter.h | 2 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 100 ++++++------------ Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 2 - Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp | 21 ++-- .../Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp | 73 +++++-------- .../Core/Src/PowerPC/Jit64IL/JitILAsm.cpp | 20 ++-- .../Core/Core/Src/PowerPC/JitCommon/JitBase.h | 2 - .../Core/Src/PowerPC/JitCommon/JitCache.cpp | 5 - Source/Core/Core/Src/PowerPC/PowerPC.cpp | 10 ++ Source/Core/Core/Src/PowerPC/PowerPC.h | 5 +- Source/Core/DebuggerWX/Src/CodeWindow.cpp | 55 +++++----- Source/Core/DebuggerWX/Src/CodeWindow.h | 4 +- Source/Core/DolphinWX/Src/BootManager.cpp | 36 ++----- Source/Core/DolphinWX/Src/Globals.h | 2 +- 15 files changed, 139 insertions(+), 200 deletions(-) diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 2b152387f5..dbbf573b37 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -31,7 +31,7 @@ SCoreStartupParameter::SCoreStartupParameter() : hInstance(0), hMainWindow(0), - bJITUnlimitedCache(false), bJITBlockLinking(false), + bJITNoBlockCache(false), bJITBlockLinking(false), bJITOff(false), bJITLoadStoreOff(false), bJITLoadStorelXzOff(false), bJITLoadStorelwzOff(false), bJITLoadStorelbzxOff(false), diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 0274f53eff..2c330a7513 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -50,7 +50,7 @@ struct SCoreStartupParameter int iCPUCore; // JIT (shared between JIT and JITIL) - bool bJITUnlimitedCache, bJITBlockLinking; + bool bJITNoBlockCache, bJITBlockLinking; bool bJITOff; bool bJITLoadStoreOff, bJITLoadStorelXzOff, bJITLoadStorelwzOff, bJITLoadStorelbzxOff; bool bJITLoadStoreFloatingOff; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 8ecba0260b..0d79f31084 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -79,7 +79,7 @@ using namespace PowerPC; // Other considerations // // Many instructions have shorter forms for EAX. However, I believe their performance boost -// will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their +// will be as small to be negligible, so I haven't dirtied up the code with that. AMD recommends it in their // optimization manuals, though. // // We support block linking. Reserve space at the exits of every block for a full 5-byte jmp. Save 16-bit offsets @@ -97,7 +97,7 @@ using namespace PowerPC; // TODO: SERIOUS synchronization problem with the video plugin setting tokens and breakpoints in dual core mode!!! // Somewhat fixed by disabling idle skipping when certain interrupts are enabled -// This is no permantent reliable fix +// This is no permanent reliable fix // TODO: Zeldas go whacko when you hang the gfx thread // Idea - Accurate exception handling @@ -175,12 +175,15 @@ void Jit64::Init() where this cause problems, so I'm enabling this by default, since I seem to get perhaps as much as 20% more fps with this option enabled. If you suspect that this option cause problems you can also disable it from the debugging window. */ -#ifdef JIT_SINGLESTEP - jo.enableBlocklink = false; - SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle = false; -#else - jo.enableBlocklink = true; -#endif + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) + { + jo.enableBlocklink = false; + SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle = false; + } + else + { + jo.enableBlocklink = true; + } #ifdef _M_X64 jo.enableFastMem = SConfig::GetInstance().m_LocalCoreStartupParameter.bUseFastMem; #else @@ -195,11 +198,11 @@ void Jit64::Init() gpr.SetEmitter(this); fpr.SetEmitter(this); - // Custom settings - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - CODE_SIZE = 1024*1024*8*8; if (Core::g_CoreStartupParameter.bJITBlockLinking) - { jo.enableBlocklink = false; SuccessAlert("Your game was started without JIT Block Linking"); } + { + jo.enableBlocklink = false; + SuccessAlert("Your game was started without JIT Block Linking"); + } trampolines.Init(); AllocCodeSpace(CODE_SIZE); @@ -228,8 +231,6 @@ void Jit64::Shutdown() // This is only called by Default() in this file. It will execute an instruction with the interpreter functions. void Jit64::WriteCallInterpreter(UGeckoInstruction inst) { - - gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); if (js.isLastInstruction) @@ -298,7 +299,6 @@ static void ImHere() return; } DEBUG_LOG(DYNA_REC, "I'm here - PC = %08x , LR = %08x", PC, LR); - //printf("I'm here - PC = %08x , LR = %08x", PC, LR); been_here[PC] = 1; } @@ -366,16 +366,8 @@ void STACKALIGN Jit64::Run() void Jit64::SingleStep() { -#ifndef JIT_NO_CACHE - CoreTiming::SetMaximumSlice(1); -#endif - CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; pExecAddr(); - -#ifndef JIT_NO_CACHE - CoreTiming::ResetSliceLength(); -#endif } void Jit64::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address) @@ -404,31 +396,15 @@ void Jit64::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address) char ppcInst[256]; DisassembleGekko(op.inst.hex, em_address, ppcInst, 256); - NOTICE_LOG(DYNA_REC, "JIT64 PC: %08x Cycles: %04d CR: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %s", em_address, js.st.numCycles, PowerPC::ppcState.cr, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, ppcInst); + NOTICE_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, op.inst.hex, ppcInst); } void STACKALIGN Jit64::Jit(u32 em_address) { - if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) + if (GetSpaceLeft() < 0x10000 || blocks.IsFull() || Core::g_CoreStartupParameter.bJITNoBlockCache) { - WARN_LOG(DYNA_REC, "JIT cache full - clearing.") - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - { - ERROR_LOG(DYNA_REC, "What? JIT cache still full - clearing."); - PanicAlert("What? JIT cache still full - clearing."); - } ClearCache(); } -#ifdef JIT_NO_CACHE - ClearCache(); - if (PowerPC::breakpoints.IsAddressBreakPoint(em_address)) - { - PowerPC::Pause(); - if (PowerPC::breakpoints.IsTempBreakPoint(em_address)) - PowerPC::breakpoints.Remove(em_address); - return; - } -#endif int block_num = blocks.AllocateBlock(em_address); JitBlock *b = blocks.GetBlock(block_num); blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b)); @@ -439,15 +415,17 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { int blockSize = code_buf->GetSize(); -#ifdef JIT_SINGLESTEP - blockSize = 1; - Trace(code_buf, em_address); -#endif + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) + { + // Comment out the following to disable breakpoints (speed-up) + blockSize = 1; + Trace(code_buf, em_address); + } if (em_address == 0) PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR); - int size; + int size = 0; js.isLastInstruction = false; js.blockStart = em_address; js.fifoBytesThisBlock = 0; @@ -458,9 +436,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc //Analyze the block, collect all instructions it is made of (including inlining, //if that is enabled), reorder instructions for optimal performance, and join joinable instructions. u32 nextPC = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, code_buf, blockSize); -#ifndef JIT_SINGLESTEP - (void)nextPC; -#endif PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -511,10 +486,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc //TODO #endif // get start tic - PROFILER_QUERY_PERFORMACE_COUNTER(&b->ticStart); + PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStart); } #if defined(_DEBUG) || defined(DEBUGFAST) || defined(NAN_CHECK) - // should help logged stacktraces become more accurate + // should help logged stack-traces become more accurate MOV(32, M(&PC), Imm32(js.blockStart)); #endif @@ -523,19 +498,14 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc gpr.Start(js.gpa); fpr.Start(js.fpa); -#ifdef JIT_SINGLESTEP js.downcountAmount = js.st.numCycles; -#else - js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address); -#endif + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) + js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address); js.blockSize = size; // Translate instructions for (int i = 0; i < (int)size; i++) { - // gpr.Flush(FLUSH_ALL); - // if (PPCTables::UsesFPU(_inst)) - // fpr.Flush(FLUSH_ALL); js.compilerPC = ops[i].address; js.op = &ops[i]; js.instructionNumber = i; @@ -548,7 +518,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // CAUTION!!! push on stack regs you use, do your stuff, then pop PROFILER_VPUSH; // get end tic - PROFILER_QUERY_PERFORMACE_COUNTER(&b->ticStop); + PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStop); // tic counter += (end tic - start tic) PROFILER_ADD_DIFF_LARGE_INTEGER(&b->ticCounter, &b->ticStop, &b->ticStart); PROFILER_VPOP; @@ -582,12 +552,12 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc if (js.cancel) break; } - -#ifdef JIT_SINGLESTEP - gpr.Flush(FLUSH_ALL); - fpr.Flush(FLUSH_ALL); - WriteExit(nextPC, 0); -#endif + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) + { + gpr.Flush(FLUSH_ALL); + fpr.Flush(FLUSH_ALL); + WriteExit(nextPC, 0); + } b->flags = js.block_flags; b->codeSize = (u32)(GetCodePtr() - normalEntry); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 72fafc5cdf..cbc0387243 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -29,8 +29,6 @@ // Settings // ---------- -#define JIT_OFF_OPTIONS // Compile with JIT off options - #ifndef _JIT64_H #define _JIT64_H diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index a69c1db6f7..adc8dc6d75 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -78,6 +78,17 @@ void Jit64AsmRoutineManager::Generate() // 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); + + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints)); + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); + FixupBranch noBreakpoint = J_CC(CC_Z); + ABI_PopAllCalleeSavedRegsAndAdjustStack(); + RET(); + SetJumpTarget(noBreakpoint); + } + SetJumpTarget(skipToRealDispatch); dispatcherNoCheck = GetCodePtr(); @@ -114,11 +125,6 @@ void Jit64AsmRoutineManager::Generate() MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc)); CALL((void *)&Jit); #endif -#ifdef JIT_NO_CACHE - TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); - FixupBranch notRunning = J_CC(CC_NZ); -#endif - JMP(dispatcherNoCheck); // no point in special casing this //FP blocks test for FPU available, jump here if false @@ -131,9 +137,6 @@ void Jit64AsmRoutineManager::Generate() MOV(32, M(&PC), R(EAX)); JMP(dispatcher); -#ifdef JIT_NO_CACHE - SetJumpTarget(notRunning); -#endif SetJumpTarget(bail); doTiming = GetCodePtr(); @@ -195,8 +198,8 @@ void Jit64AsmRoutineManager::Generate() MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0)); #endif - SetJumpTarget(getinst); SetJumpTarget(getinst2); + SetJumpTarget(getinst); #else #ifdef _M_IX86 AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK)); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index 478488809c..21d296d552 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -73,7 +73,7 @@ using namespace PowerPC; // Other considerations // // Many instructions have shorter forms for EAX. However, I believe their performance boost -// will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their +// will be as small to be negligible, so I haven't dirtied up the code with that. AMD recommends it in their // optimization manuals, though. // // We support block linking. Reserve space at the exits of every block for a full 5-byte jmp. Save 16-bit offsets @@ -91,7 +91,7 @@ using namespace PowerPC; // TODO: SERIOUS synchronization problem with the video plugin setting tokens and breakpoints in dual core mode!!! // Somewhat fixed by disabling idle skipping when certain interrupts are enabled -// This is no permantent reliable fix +// This is no permanent reliable fix // TODO: Zeldas go whacko when you hang the gfx thread // Idea - Accurate exception handling @@ -163,16 +163,18 @@ namespace CPUCompare void JitIL::Init() { - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - CODE_SIZE = 1024*1024*8*8; - jo.optimizeStack = true; -#ifdef JIT_SINGLESTEP - jo.enableBlocklink = false; - Core::g_CoreStartupParameter.bSkipIdle = false; -#else - jo.enableBlocklink = true; // Speed boost, but not 100% safe -#endif + + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + jo.enableBlocklink = false; + Core::g_CoreStartupParameter.bSkipIdle = false; + } + else + { + jo.enableBlocklink = true; // Speed boost, but not 100% safe + } + #ifdef _M_X64 jo.enableFastMem = false; #else @@ -351,16 +353,8 @@ void STACKALIGN JitIL::Run() void JitIL::SingleStep() { -#ifndef JIT_NO_CACHE - CoreTiming::SetMaximumSlice(1); -#endif - CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; pExecAddr(); - -#ifndef JIT_NO_CACHE - CoreTiming::ResetSliceLength(); -#endif } void JitIL::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address) @@ -388,32 +382,16 @@ void JitIL::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address) const PPCAnalyst::CodeOp &op = code_buf->codebuffer[0]; char ppcInst[256]; DisassembleGekko(op.inst.hex, em_address, ppcInst, 256); - - NOTICE_LOG(DYNA_REC, "JITIL PC: %08x Cycles: %04d CR: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %s", em_address, js.st.numCycles, PowerPC::ppcState.cr, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, ppcInst); + + NOTICE_LOG(DYNA_REC, "JITIL PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, op.inst.hex, ppcInst); } void STACKALIGN JitIL::Jit(u32 em_address) { - if (GetSpaceLeft() < 0x10000 || blocks.IsFull()) + if (GetSpaceLeft() < 0x10000 || blocks.IsFull() || Core::g_CoreStartupParameter.bJITNoBlockCache) { - INFO_LOG(DYNA_REC, "JIT cache full - clearing.") - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - { - ERROR_LOG(DYNA_REC, "What? JIT cache still full - clearing."); - PanicAlert("What? JIT cache still full - clearing."); - } ClearCache(); } -#ifdef JIT_NO_CACHE - ClearCache(); - if (PowerPC::breakpoints.IsAddressBreakPoint(em_address)) - { - PowerPC::Pause(); - if (PowerPC::breakpoints.IsTempBreakPoint(em_address)) - PowerPC::breakpoints.Remove(em_address); - return; - } -#endif int block_num = blocks.AllocateBlock(em_address); JitBlock *b = blocks.GetBlock(block_num); blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b)); @@ -423,10 +401,12 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { int blockSize = code_buf->GetSize(); -#ifdef JIT_SINGLESTEP - blockSize = 1; - Trace(code_buf, em_address); -#endif + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + // Comment out the following to disable breakpoints (speed-up) + blockSize = 1; + Trace(code_buf, em_address); + } if (em_address == 0) PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR); @@ -475,11 +455,12 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // instruction processed by the JIT routines) ibuild.Reset(); -#ifdef JIT_SINGLESTEP + js.downcountAmount = js.st.numCycles; -#else - js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address); -#endif + + if (!Core::g_CoreStartupParameter.bEnableDebugging) + js.downcountAmount += PatchEngine::GetSpeedhackCycles(em_address); + // Translate instructions for (int i = 0; i < (int)size; i++) { diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index a56502d623..820bfcd67d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -80,6 +80,17 @@ void JitILAsmRoutineManager::Generate() //The result of slice decrement should be in flags if somebody jumped here FixupBranch bail = J_CC(CC_BE); + + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints)); + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); + FixupBranch noBreakpoint = J_CC(CC_Z); + ABI_PopAllCalleeSavedRegsAndAdjustStack(); + RET(); + SetJumpTarget(noBreakpoint); + } + SetJumpTarget(skipToRealDispatch); dispatcherNoCheck = GetCodePtr(); @@ -116,11 +127,6 @@ void JitILAsmRoutineManager::Generate() MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc)); CALL((void *)&Jit); #endif -#ifdef JIT_NO_CACHE - TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); - FixupBranch notRunning = J_CC(CC_NZ); -#endif - JMP(dispatcherNoCheck); // no point in special casing this //FP blocks test for FPU available, jump here if false @@ -133,10 +139,6 @@ void JitILAsmRoutineManager::Generate() MOV(32, M(&PC), R(EAX)); JMP(dispatcher); -#ifdef JIT_NO_CACHE - SetJumpTarget(notRunning); -#endif - SetJumpTarget(bail); doTiming = GetCodePtr(); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h index 793a75c611..d8ca8e689e 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h @@ -18,8 +18,6 @@ #ifndef _JITBASE_H #define _JITBASE_H -//#define JIT_SINGLESTEP // Enables single stepping -//#define JIT_NO_CACHE // Disables the block cache and enables breakpoints //#define JIT_LOG_X86 // Enables logging of the generated x86 code //#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs //#define JIT_LOG_FPR // Enables logging of the PPC floating point regs diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index d45832cc12..e0a1a197e7 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -72,11 +72,6 @@ bool JitBlock::ContainsAddress(u32 em_address) void JitBlockCache::Init() { MAX_NUM_BLOCKS = 65536*2; - if (Core::g_CoreStartupParameter.bJITUnlimitedCache) - { - SuccessAlert("Your game was started with an unlimited JIT cache"); - MAX_NUM_BLOCKS = 65536*8; - } #if defined USE_OPROFILE && USE_OPROFILE agent = op_open_agent(); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 2b6c934697..2bc9771638 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -375,6 +375,16 @@ void CheckExceptions() } } +void CheckBreakPoints() +{ + if (PowerPC::breakpoints.IsAddressBreakPoint(PC)) + { + PowerPC::Pause(); + if (PowerPC::breakpoints.IsTempBreakPoint(PC)) + PowerPC::breakpoints.Remove(PC); + } +} + void OnIdle(u32 _uThreadAddr) { u32 nextThread = Memory::Read_U32(_uThreadAddr); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index f4a2880622..22c413afd7 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -58,11 +58,11 @@ struct GC_ALIGNED64(PowerPCState) // Exception management. u32 Exceptions; - u32 sr[16]; // Segment registers. Unused. + u32 sr[16]; // Segment registers. u32 DebugCount; - // special purpose registers - controlls quantizers, DMA, and lots of other misc extensions. + // special purpose registers - controls quantizers, DMA, and lots of other misc extensions. // also for power management, but we don't care about that. u32 spr[1024]; @@ -95,6 +95,7 @@ void SetMode(CoreMode _coreType); void SingleStep(); void CheckExceptions(); +void CheckBreakPoints(); void RunLoop(); void Start(); void Pause(); diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 1bfc095fce..7750ddb6ef 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -85,8 +85,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel) EVT_MENU(IDM_FONTPICKER, CCodeWindow::OnChangeFont) EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnCPUMode) // Jit - EVT_MENU(IDM_JITUNLIMITED, CCodeWindow::OnCPUMode) -#ifdef JIT_OFF_OPTIONS + EVT_MENU(IDM_JITNOBLOCKCACHE, CCodeWindow::OnCPUMode) + EVT_MENU(IDM_JITOFF, CCodeWindow::OnCPUMode) EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnCPUMode) EVT_MENU(IDM_JITLSLXZOFF, CCodeWindow::OnCPUMode) @@ -98,7 +98,7 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel) EVT_MENU(IDM_JITIOFF, CCodeWindow::OnCPUMode) EVT_MENU(IDM_JITPOFF, CCodeWindow::OnCPUMode) EVT_MENU(IDM_JITSROFF, CCodeWindow::OnCPUMode) -#endif + EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu) EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu) EVT_MENU(IDM_SEARCHINSTRUCTION, CCodeWindow::OnJitMenu) @@ -433,7 +433,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam wxMenu* pCoreMenu = new wxMenu; wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter core") - , wxString::FromAscii("This is nessesary to get break points" + , wxString::FromAscii("This is necessary to get break points" " and stepping to work as explained in the Developer Documentation. But it can be very" " slow, perhaps slower than 1 fps.") , wxITEM_CHECK); @@ -444,7 +444,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam _T("Provide safer execution by not linking the JIT blocks."), wxITEM_CHECK); - jitunlimited = pCoreMenu->Append(IDM_JITUNLIMITED, _T("&Unlimited JIT Cache"), + jitnoblockcache = pCoreMenu->Append(IDM_JITNOBLOCKCACHE, _T("&Disable JIT Cache"), _T("Avoid any involuntary JIT cache clearing, this may prevent Zelda TP from crashing.") _T(" [This option must be selected before a game is started.]"), wxITEM_CHECK); @@ -454,22 +454,21 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam pCoreMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage")); pCoreMenu->Append(IDM_SEARCHINSTRUCTION, _T("&Search for an op")); - #ifdef JIT_OFF_OPTIONS - pCoreMenu->AppendSeparator(); - jitoff = pCoreMenu->Append(IDM_JITOFF, _T("&JIT off (JIT core)"), - _T("Turn off all JIT functions, but still use the JIT core from Jit.cpp"), - wxITEM_CHECK); - jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, wxITEM_CHECK); - jitlslbzxoff = pCoreMenu->Append(IDM_JITLSLBZXOFF, _T(" &JIT LoadStore lbzx off"), wxEmptyString, wxITEM_CHECK); - jitlslxzoff = pCoreMenu->Append(IDM_JITLSLXZOFF, _T(" &JIT LoadStore lXz off"), wxEmptyString, wxITEM_CHECK); - jitlslwzoff = pCoreMenu->Append(IDM_JITLSLWZOFF, _T(" &JIT LoadStore lwz off"), wxEmptyString, wxITEM_CHECK); - jitlspoff = pCoreMenu->Append(IDM_JITLSFOFF, _T("&JIT LoadStore Floating off"), wxEmptyString, wxITEM_CHECK); - jitlsfoff = pCoreMenu->Append(IDM_JITLSPOFF, _T("&JIT LoadStore Paired off"), wxEmptyString, wxITEM_CHECK); - jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK); - jitioff = pCoreMenu->Append(IDM_JITIOFF, _T("&JIT Integer off"), wxEmptyString, wxITEM_CHECK); - jitpoff = pCoreMenu->Append(IDM_JITPOFF, _T("&JIT Paired off"), wxEmptyString, wxITEM_CHECK); - jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK); - #endif + + pCoreMenu->AppendSeparator(); + jitoff = pCoreMenu->Append(IDM_JITOFF, _T("&JIT off (JIT core)"), + _T("Turn off all JIT functions, but still use the JIT core from Jit.cpp"), + wxITEM_CHECK); + jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, wxITEM_CHECK); + jitlslbzxoff = pCoreMenu->Append(IDM_JITLSLBZXOFF, _T(" &JIT LoadStore lbzx off"), wxEmptyString, wxITEM_CHECK); + jitlslxzoff = pCoreMenu->Append(IDM_JITLSLXZOFF, _T(" &JIT LoadStore lXz off"), wxEmptyString, wxITEM_CHECK); + jitlslwzoff = pCoreMenu->Append(IDM_JITLSLWZOFF, _T(" &JIT LoadStore lwz off"), wxEmptyString, wxITEM_CHECK); + jitlspoff = pCoreMenu->Append(IDM_JITLSFOFF, _T("&JIT LoadStore Floating off"), wxEmptyString, wxITEM_CHECK); + jitlsfoff = pCoreMenu->Append(IDM_JITLSPOFF, _T("&JIT LoadStore Paired off"), wxEmptyString, wxITEM_CHECK); + jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK); + jitioff = pCoreMenu->Append(IDM_JITIOFF, _T("&JIT Integer off"), wxEmptyString, wxITEM_CHECK); + jitpoff = pCoreMenu->Append(IDM_JITPOFF, _T("&JIT Paired off"), wxEmptyString, wxITEM_CHECK); + jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK); pMenuBar->Append(pCoreMenu, _T("&JIT")); @@ -506,7 +505,7 @@ void CCodeWindow::CreateMenuOptions(wxMenuBar * _pMenuBar, wxMenu* _pMenu) , wxString::FromAscii( "Automatically load the Default ISO when Dolphin starts, or the last game you loaded," " if you have not given it an elf file with the --elf command line. [This can be" - " convenient if you are bugtesting with a certain game and want to rebuild" + " convenient if you are bug-testing with a certain game and want to rebuild" " and retry it several times, either with changes to Dolphin or if you are" " developing a homebrew game.]") , wxITEM_CHECK); @@ -527,8 +526,6 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event) bBootToPause = !bBootToPause; return; case IDM_AUTOMATICSTART: bAutomaticStart = !bAutomaticStart; return; - -#ifdef JIT_OFF_OPTIONS case IDM_JITOFF: Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break; case IDM_JITLSOFF: @@ -551,7 +548,6 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event) Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked(); break; case IDM_JITSROFF: Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break; -#endif } // Clear the JIT cache to enable these changes @@ -599,9 +595,9 @@ bool CCodeWindow::AutomaticStart() { return GetMenuBar()->IsChecked(IDM_AUTOMATICSTART); } -bool CCodeWindow::UnlimitedJITCache() +bool CCodeWindow::JITNoBlockCache() { - return GetMenuBar()->IsChecked(IDM_JITUNLIMITED); + return GetMenuBar()->IsChecked(IDM_JITNOBLOCKCACHE); } bool CCodeWindow::JITBlockLinking() { @@ -702,8 +698,8 @@ void CCodeWindow::UpdateButtonStates() // ------------------ GetMenuBar()->Enable(IDM_INTERPRETER, Pause); // CPU Mode - GetMenuBar()->Enable(IDM_JITUNLIMITED, !Initialized); -#ifdef JIT_OFF_OPTIONS + GetMenuBar()->Enable(IDM_JITNOBLOCKCACHE, !Initialized); + GetMenuBar()->Enable(IDM_JITOFF, Pause); GetMenuBar()->Enable(IDM_JITLSOFF, Pause); GetMenuBar()->Enable(IDM_JITLSLXZOFF, Pause); @@ -715,7 +711,6 @@ void CCodeWindow::UpdateButtonStates() GetMenuBar()->Enable(IDM_JITIOFF, Pause); GetMenuBar()->Enable(IDM_JITPOFF, Pause); GetMenuBar()->Enable(IDM_JITSROFF, Pause); -#endif GetMenuBar()->Enable(IDM_CLEARCODECACHE, Pause); // JIT Menu GetMenuBar()->Enable(IDM_SEARCHINSTRUCTION, Initialized); diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.h b/Source/Core/DebuggerWX/Src/CodeWindow.h index 40d33f2387..11c79256e9 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.h +++ b/Source/Core/DebuggerWX/Src/CodeWindow.h @@ -74,7 +74,7 @@ class CCodeWindow bool UseInterpreter(); bool BootToPause(); bool AutomaticStart(); - bool UnlimitedJITCache(); + bool JITNoBlockCache(); bool JITBlockLinking(); void JumpToAddress(u32 _Address); @@ -159,7 +159,7 @@ class CCodeWindow void InitBitmaps(); void CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter); - wxMenuItem* jitblocklinking, *jitunlimited, *jitoff; + wxMenuItem* jitblocklinking, *jitnoblockcache, *jitoff; wxMenuItem* jitlsoff, *jitlslxzoff, *jitlslwzoff, *jitlslbzxoff; wxMenuItem* jitlspoff; wxMenuItem* jitlsfoff; diff --git a/Source/Core/DolphinWX/Src/BootManager.cpp b/Source/Core/DolphinWX/Src/BootManager.cpp index 3b328d141b..cf1c1cfd77 100644 --- a/Source/Core/DolphinWX/Src/BootManager.cpp +++ b/Source/Core/DolphinWX/Src/BootManager.cpp @@ -15,28 +15,19 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - - - -// ======================================================= // File description // ------------- -/* Purpose of this file: Collect boot settings for Core::Init() - - Call sequence: This file has one of the first function called when a game is booted, - the boot sequence in the code is: - - DolphinWX: GameListCtrl.cpp OnActivated - BootManager.cpp BootCore - Core Core.cpp Init Thread creation - EmuThread Calls CBoot::BootUp - Boot.cpp CBoot::BootUp() - CBoot::EmulatedBS2_Wii() / GC() or Load_BS2() - */ -// ============= - - +// Purpose of this file: Collect boot settings for Core::Init() +// Call sequence: This file has one of the first function called when a game is booted, +// the boot sequence in the code is: + +// DolphinWX: GameListCtrl.cpp OnActivated +// BootManager.cpp BootCore +// Core Core.cpp Init Thread creation +// EmuThread Calls CBoot::BootUp +// Boot.cpp CBoot::BootUp() +// CBoot::EmulatedBS2_Wii() / GC() or Load_BS2() // Includes @@ -83,7 +74,7 @@ bool BootCore(const std::string& _rFilename) { StartUp.bBootToPause = main_frame->g_pCodeWindow->BootToPause(); StartUp.bAutomaticStart = main_frame->g_pCodeWindow->AutomaticStart(); - StartUp.bJITUnlimitedCache = main_frame->g_pCodeWindow->UnlimitedJITCache(); + StartUp.bJITNoBlockCache = main_frame->g_pCodeWindow->JITNoBlockCache(); StartUp.bJITBlockLinking = main_frame->g_pCodeWindow->JITBlockLinking(); } StartUp.bEnableDebugging = main_frame->g_pCodeWindow ? true : false; // RUNNING_DEBUG @@ -105,7 +96,6 @@ bool BootCore(const std::string& _rFilename) // If for example the ISO file is bad we return here if (!StartUp.AutoSetup(SCoreStartupParameter::BOOT_DEFAULT)) return false; - // ==================================================== // Load game specific settings IniFile game_ini; std::string unique_id = StartUp.GetUniqueID(); @@ -126,7 +116,6 @@ bool BootCore(const std::string& _rFilename) } // Run the game - // -------------- #if defined(HAVE_WX) && HAVE_WX if(main_frame) { @@ -147,7 +136,6 @@ bool BootCore(const std::string& _rFilename) #else Core::SetState(Core::CORE_RUN); #endif - // ===================== return true; } @@ -157,6 +145,4 @@ void Stop() Core::Stop(); } - - } // namespace diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h index c530df24bd..30e3cb1aae 100644 --- a/Source/Core/DolphinWX/Src/Globals.h +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -131,7 +131,7 @@ enum IDM_INTERPRETER, //IDM_DUALCORE, // not used IDM_AUTOMATICSTART, IDM_BOOTTOPAUSE, - IDM_JITUNLIMITED, IDM_JITBLOCKLINKING, // JIT + IDM_JITNOBLOCKCACHE, IDM_JITBLOCKLINKING, // JIT IDM_JITOFF, IDM_JITLSOFF, IDM_JITLSLXZOFF, IDM_JITLSLWZOFF, IDM_JITLSLBZXOFF, IDM_JITLSPOFF, IDM_JITLSFOFF,