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,