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
This commit is contained in:
parent
8e4ef9b9e5
commit
f158ca82af
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
SCoreStartupParameter::SCoreStartupParameter()
|
SCoreStartupParameter::SCoreStartupParameter()
|
||||||
: hInstance(0), hMainWindow(0),
|
: hInstance(0), hMainWindow(0),
|
||||||
bJITUnlimitedCache(false), bJITBlockLinking(false),
|
bJITNoBlockCache(false), bJITBlockLinking(false),
|
||||||
bJITOff(false),
|
bJITOff(false),
|
||||||
bJITLoadStoreOff(false), bJITLoadStorelXzOff(false),
|
bJITLoadStoreOff(false), bJITLoadStorelXzOff(false),
|
||||||
bJITLoadStorelwzOff(false), bJITLoadStorelbzxOff(false),
|
bJITLoadStorelwzOff(false), bJITLoadStorelbzxOff(false),
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct SCoreStartupParameter
|
||||||
int iCPUCore;
|
int iCPUCore;
|
||||||
|
|
||||||
// JIT (shared between JIT and JITIL)
|
// JIT (shared between JIT and JITIL)
|
||||||
bool bJITUnlimitedCache, bJITBlockLinking;
|
bool bJITNoBlockCache, bJITBlockLinking;
|
||||||
bool bJITOff;
|
bool bJITOff;
|
||||||
bool bJITLoadStoreOff, bJITLoadStorelXzOff, bJITLoadStorelwzOff, bJITLoadStorelbzxOff;
|
bool bJITLoadStoreOff, bJITLoadStorelXzOff, bJITLoadStorelwzOff, bJITLoadStorelbzxOff;
|
||||||
bool bJITLoadStoreFloatingOff;
|
bool bJITLoadStoreFloatingOff;
|
||||||
|
|
|
@ -79,7 +79,7 @@ using namespace PowerPC;
|
||||||
// Other considerations
|
// Other considerations
|
||||||
//
|
//
|
||||||
// Many instructions have shorter forms for EAX. However, I believe their performance boost
|
// 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.
|
// 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
|
// 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!!!
|
// 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
|
// 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
|
// TODO: Zeldas go whacko when you hang the gfx thread
|
||||||
|
|
||||||
// Idea - Accurate exception handling
|
// 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
|
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
|
fps with this option enabled. If you suspect that this option cause problems you can also disable it from the
|
||||||
debugging window. */
|
debugging window. */
|
||||||
#ifdef JIT_SINGLESTEP
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||||
jo.enableBlocklink = false;
|
{
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle = false;
|
jo.enableBlocklink = false;
|
||||||
#else
|
SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle = false;
|
||||||
jo.enableBlocklink = true;
|
}
|
||||||
#endif
|
else
|
||||||
|
{
|
||||||
|
jo.enableBlocklink = true;
|
||||||
|
}
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
jo.enableFastMem = SConfig::GetInstance().m_LocalCoreStartupParameter.bUseFastMem;
|
jo.enableFastMem = SConfig::GetInstance().m_LocalCoreStartupParameter.bUseFastMem;
|
||||||
#else
|
#else
|
||||||
|
@ -195,11 +198,11 @@ void Jit64::Init()
|
||||||
gpr.SetEmitter(this);
|
gpr.SetEmitter(this);
|
||||||
fpr.SetEmitter(this);
|
fpr.SetEmitter(this);
|
||||||
|
|
||||||
// Custom settings
|
|
||||||
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
|
|
||||||
CODE_SIZE = 1024*1024*8*8;
|
|
||||||
if (Core::g_CoreStartupParameter.bJITBlockLinking)
|
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();
|
trampolines.Init();
|
||||||
AllocCodeSpace(CODE_SIZE);
|
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.
|
// This is only called by Default() in this file. It will execute an instruction with the interpreter functions.
|
||||||
void Jit64::WriteCallInterpreter(UGeckoInstruction inst)
|
void Jit64::WriteCallInterpreter(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
gpr.Flush(FLUSH_ALL);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
if (js.isLastInstruction)
|
if (js.isLastInstruction)
|
||||||
|
@ -298,7 +299,6 @@ static void ImHere()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DEBUG_LOG(DYNA_REC, "I'm here - PC = %08x , LR = %08x", PC, LR);
|
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;
|
been_here[PC] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,16 +366,8 @@ void STACKALIGN Jit64::Run()
|
||||||
|
|
||||||
void Jit64::SingleStep()
|
void Jit64::SingleStep()
|
||||||
{
|
{
|
||||||
#ifndef JIT_NO_CACHE
|
|
||||||
CoreTiming::SetMaximumSlice(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
|
|
||||||
#ifndef JIT_NO_CACHE
|
|
||||||
CoreTiming::ResetSliceLength();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address)
|
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];
|
char ppcInst[256];
|
||||||
DisassembleGekko(op.inst.hex, em_address, 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)
|
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();
|
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);
|
int block_num = blocks.AllocateBlock(em_address);
|
||||||
JitBlock *b = blocks.GetBlock(block_num);
|
JitBlock *b = blocks.GetBlock(block_num);
|
||||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b));
|
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();
|
int blockSize = code_buf->GetSize();
|
||||||
|
|
||||||
#ifdef JIT_SINGLESTEP
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||||
blockSize = 1;
|
{
|
||||||
Trace(code_buf, em_address);
|
// Comment out the following to disable breakpoints (speed-up)
|
||||||
#endif
|
blockSize = 1;
|
||||||
|
Trace(code_buf, em_address);
|
||||||
|
}
|
||||||
|
|
||||||
if (em_address == 0)
|
if (em_address == 0)
|
||||||
PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR);
|
PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR);
|
||||||
|
|
||||||
int size;
|
int size = 0;
|
||||||
js.isLastInstruction = false;
|
js.isLastInstruction = false;
|
||||||
js.blockStart = em_address;
|
js.blockStart = em_address;
|
||||||
js.fifoBytesThisBlock = 0;
|
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,
|
//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.
|
//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);
|
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;
|
PPCAnalyst::CodeOp *ops = code_buf->codebuffer;
|
||||||
|
|
||||||
|
@ -511,10 +486,10 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
//TODO
|
//TODO
|
||||||
#endif
|
#endif
|
||||||
// get start tic
|
// get start tic
|
||||||
PROFILER_QUERY_PERFORMACE_COUNTER(&b->ticStart);
|
PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStart);
|
||||||
}
|
}
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(NAN_CHECK)
|
#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));
|
MOV(32, M(&PC), Imm32(js.blockStart));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -523,19 +498,14 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
gpr.Start(js.gpa);
|
gpr.Start(js.gpa);
|
||||||
fpr.Start(js.fpa);
|
fpr.Start(js.fpa);
|
||||||
|
|
||||||
#ifdef JIT_SINGLESTEP
|
|
||||||
js.downcountAmount = js.st.numCycles;
|
js.downcountAmount = js.st.numCycles;
|
||||||
#else
|
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||||
js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address);
|
js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address);
|
||||||
#endif
|
|
||||||
|
|
||||||
js.blockSize = size;
|
js.blockSize = size;
|
||||||
// Translate instructions
|
// Translate instructions
|
||||||
for (int i = 0; i < (int)size; i++)
|
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.compilerPC = ops[i].address;
|
||||||
js.op = &ops[i];
|
js.op = &ops[i];
|
||||||
js.instructionNumber = 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
|
// CAUTION!!! push on stack regs you use, do your stuff, then pop
|
||||||
PROFILER_VPUSH;
|
PROFILER_VPUSH;
|
||||||
// get end tic
|
// get end tic
|
||||||
PROFILER_QUERY_PERFORMACE_COUNTER(&b->ticStop);
|
PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStop);
|
||||||
// tic counter += (end tic - start tic)
|
// tic counter += (end tic - start tic)
|
||||||
PROFILER_ADD_DIFF_LARGE_INTEGER(&b->ticCounter, &b->ticStop, &b->ticStart);
|
PROFILER_ADD_DIFF_LARGE_INTEGER(&b->ticCounter, &b->ticStop, &b->ticStart);
|
||||||
PROFILER_VPOP;
|
PROFILER_VPOP;
|
||||||
|
@ -582,12 +552,12 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
if (js.cancel)
|
if (js.cancel)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||||
#ifdef JIT_SINGLESTEP
|
{
|
||||||
gpr.Flush(FLUSH_ALL);
|
gpr.Flush(FLUSH_ALL);
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
WriteExit(nextPC, 0);
|
WriteExit(nextPC, 0);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
b->flags = js.block_flags;
|
b->flags = js.block_flags;
|
||||||
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
b->codeSize = (u32)(GetCodePtr() - normalEntry);
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
// ----------
|
// ----------
|
||||||
#define JIT_OFF_OPTIONS // Compile with JIT off options
|
|
||||||
|
|
||||||
#ifndef _JIT64_H
|
#ifndef _JIT64_H
|
||||||
#define _JIT64_H
|
#define _JIT64_H
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,17 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
// 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);
|
||||||
|
|
||||||
|
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);
|
SetJumpTarget(skipToRealDispatch);
|
||||||
|
|
||||||
dispatcherNoCheck = GetCodePtr();
|
dispatcherNoCheck = GetCodePtr();
|
||||||
|
@ -114,11 +125,6 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc));
|
MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc));
|
||||||
CALL((void *)&Jit);
|
CALL((void *)&Jit);
|
||||||
#endif
|
#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
|
JMP(dispatcherNoCheck); // no point in special casing this
|
||||||
|
|
||||||
//FP blocks test for FPU available, jump here if false
|
//FP blocks test for FPU available, jump here if false
|
||||||
|
@ -131,9 +137,6 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
MOV(32, M(&PC), R(EAX));
|
MOV(32, M(&PC), R(EAX));
|
||||||
JMP(dispatcher);
|
JMP(dispatcher);
|
||||||
|
|
||||||
#ifdef JIT_NO_CACHE
|
|
||||||
SetJumpTarget(notRunning);
|
|
||||||
#endif
|
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
doTiming = GetCodePtr();
|
doTiming = GetCodePtr();
|
||||||
|
|
||||||
|
@ -195,8 +198,8 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SetJumpTarget(getinst);
|
|
||||||
SetJumpTarget(getinst2);
|
SetJumpTarget(getinst2);
|
||||||
|
SetJumpTarget(getinst);
|
||||||
#else
|
#else
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
||||||
|
|
|
@ -73,7 +73,7 @@ using namespace PowerPC;
|
||||||
// Other considerations
|
// Other considerations
|
||||||
//
|
//
|
||||||
// Many instructions have shorter forms for EAX. However, I believe their performance boost
|
// 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.
|
// 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
|
// 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!!!
|
// 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
|
// 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
|
// TODO: Zeldas go whacko when you hang the gfx thread
|
||||||
|
|
||||||
// Idea - Accurate exception handling
|
// Idea - Accurate exception handling
|
||||||
|
@ -163,16 +163,18 @@ namespace CPUCompare
|
||||||
|
|
||||||
void JitIL::Init()
|
void JitIL::Init()
|
||||||
{
|
{
|
||||||
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
|
|
||||||
CODE_SIZE = 1024*1024*8*8;
|
|
||||||
|
|
||||||
jo.optimizeStack = true;
|
jo.optimizeStack = true;
|
||||||
#ifdef JIT_SINGLESTEP
|
|
||||||
jo.enableBlocklink = false;
|
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||||
Core::g_CoreStartupParameter.bSkipIdle = false;
|
{
|
||||||
#else
|
jo.enableBlocklink = false;
|
||||||
jo.enableBlocklink = true; // Speed boost, but not 100% safe
|
Core::g_CoreStartupParameter.bSkipIdle = false;
|
||||||
#endif
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jo.enableBlocklink = true; // Speed boost, but not 100% safe
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
jo.enableFastMem = false;
|
jo.enableFastMem = false;
|
||||||
#else
|
#else
|
||||||
|
@ -351,16 +353,8 @@ void STACKALIGN JitIL::Run()
|
||||||
|
|
||||||
void JitIL::SingleStep()
|
void JitIL::SingleStep()
|
||||||
{
|
{
|
||||||
#ifndef JIT_NO_CACHE
|
|
||||||
CoreTiming::SetMaximumSlice(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
|
||||||
pExecAddr();
|
pExecAddr();
|
||||||
|
|
||||||
#ifndef JIT_NO_CACHE
|
|
||||||
CoreTiming::ResetSliceLength();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::Trace(PPCAnalyst::CodeBuffer *code_buf, u32 em_address)
|
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];
|
const PPCAnalyst::CodeOp &op = code_buf->codebuffer[0];
|
||||||
char ppcInst[256];
|
char ppcInst[256];
|
||||||
DisassembleGekko(op.inst.hex, em_address, 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)
|
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();
|
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);
|
int block_num = blocks.AllocateBlock(em_address);
|
||||||
JitBlock *b = blocks.GetBlock(block_num);
|
JitBlock *b = blocks.GetBlock(block_num);
|
||||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b));
|
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();
|
int blockSize = code_buf->GetSize();
|
||||||
|
|
||||||
#ifdef JIT_SINGLESTEP
|
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||||
blockSize = 1;
|
{
|
||||||
Trace(code_buf, em_address);
|
// Comment out the following to disable breakpoints (speed-up)
|
||||||
#endif
|
blockSize = 1;
|
||||||
|
Trace(code_buf, em_address);
|
||||||
|
}
|
||||||
|
|
||||||
if (em_address == 0)
|
if (em_address == 0)
|
||||||
PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR);
|
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)
|
// instruction processed by the JIT routines)
|
||||||
ibuild.Reset();
|
ibuild.Reset();
|
||||||
|
|
||||||
#ifdef JIT_SINGLESTEP
|
|
||||||
js.downcountAmount = js.st.numCycles;
|
js.downcountAmount = js.st.numCycles;
|
||||||
#else
|
|
||||||
js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address);
|
if (!Core::g_CoreStartupParameter.bEnableDebugging)
|
||||||
#endif
|
js.downcountAmount += PatchEngine::GetSpeedhackCycles(em_address);
|
||||||
|
|
||||||
// Translate instructions
|
// Translate instructions
|
||||||
for (int i = 0; i < (int)size; i++)
|
for (int i = 0; i < (int)size; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,6 +80,17 @@ void JitILAsmRoutineManager::Generate()
|
||||||
|
|
||||||
//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);
|
||||||
|
|
||||||
|
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);
|
SetJumpTarget(skipToRealDispatch);
|
||||||
|
|
||||||
dispatcherNoCheck = GetCodePtr();
|
dispatcherNoCheck = GetCodePtr();
|
||||||
|
@ -116,11 +127,6 @@ void JitILAsmRoutineManager::Generate()
|
||||||
MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc));
|
MOV(32, R(ABI_PARAM1), M(&PowerPC::ppcState.pc));
|
||||||
CALL((void *)&Jit);
|
CALL((void *)&Jit);
|
||||||
#endif
|
#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
|
JMP(dispatcherNoCheck); // no point in special casing this
|
||||||
|
|
||||||
//FP blocks test for FPU available, jump here if false
|
//FP blocks test for FPU available, jump here if false
|
||||||
|
@ -133,10 +139,6 @@ void JitILAsmRoutineManager::Generate()
|
||||||
MOV(32, M(&PC), R(EAX));
|
MOV(32, M(&PC), R(EAX));
|
||||||
JMP(dispatcher);
|
JMP(dispatcher);
|
||||||
|
|
||||||
#ifdef JIT_NO_CACHE
|
|
||||||
SetJumpTarget(notRunning);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
doTiming = GetCodePtr();
|
doTiming = GetCodePtr();
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#ifndef _JITBASE_H
|
#ifndef _JITBASE_H
|
||||||
#define _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_X86 // Enables logging of the generated x86 code
|
||||||
//#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs
|
//#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs
|
||||||
//#define JIT_LOG_FPR // Enables logging of the PPC floating point regs
|
//#define JIT_LOG_FPR // Enables logging of the PPC floating point regs
|
||||||
|
|
|
@ -72,11 +72,6 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
void JitBlockCache::Init()
|
void JitBlockCache::Init()
|
||||||
{
|
{
|
||||||
MAX_NUM_BLOCKS = 65536*2;
|
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
|
#if defined USE_OPROFILE && USE_OPROFILE
|
||||||
agent = op_open_agent();
|
agent = op_open_agent();
|
||||||
|
|
|
@ -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)
|
void OnIdle(u32 _uThreadAddr)
|
||||||
{
|
{
|
||||||
u32 nextThread = Memory::Read_U32(_uThreadAddr);
|
u32 nextThread = Memory::Read_U32(_uThreadAddr);
|
||||||
|
|
|
@ -58,11 +58,11 @@ struct GC_ALIGNED64(PowerPCState)
|
||||||
// Exception management.
|
// Exception management.
|
||||||
u32 Exceptions;
|
u32 Exceptions;
|
||||||
|
|
||||||
u32 sr[16]; // Segment registers. Unused.
|
u32 sr[16]; // Segment registers.
|
||||||
|
|
||||||
u32 DebugCount;
|
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.
|
// also for power management, but we don't care about that.
|
||||||
u32 spr[1024];
|
u32 spr[1024];
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ void SetMode(CoreMode _coreType);
|
||||||
|
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
void CheckExceptions();
|
void CheckExceptions();
|
||||||
|
void CheckBreakPoints();
|
||||||
void RunLoop();
|
void RunLoop();
|
||||||
void Start();
|
void Start();
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
|
@ -85,8 +85,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel)
|
||||||
EVT_MENU(IDM_FONTPICKER, CCodeWindow::OnChangeFont)
|
EVT_MENU(IDM_FONTPICKER, CCodeWindow::OnChangeFont)
|
||||||
|
|
||||||
EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnCPUMode) // Jit
|
EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnCPUMode) // Jit
|
||||||
EVT_MENU(IDM_JITUNLIMITED, CCodeWindow::OnCPUMode)
|
EVT_MENU(IDM_JITNOBLOCKCACHE, CCodeWindow::OnCPUMode)
|
||||||
#ifdef JIT_OFF_OPTIONS
|
|
||||||
EVT_MENU(IDM_JITOFF, CCodeWindow::OnCPUMode)
|
EVT_MENU(IDM_JITOFF, CCodeWindow::OnCPUMode)
|
||||||
EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnCPUMode)
|
EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnCPUMode)
|
||||||
EVT_MENU(IDM_JITLSLXZOFF, 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_JITIOFF, CCodeWindow::OnCPUMode)
|
||||||
EVT_MENU(IDM_JITPOFF, CCodeWindow::OnCPUMode)
|
EVT_MENU(IDM_JITPOFF, CCodeWindow::OnCPUMode)
|
||||||
EVT_MENU(IDM_JITSROFF, CCodeWindow::OnCPUMode)
|
EVT_MENU(IDM_JITSROFF, CCodeWindow::OnCPUMode)
|
||||||
#endif
|
|
||||||
EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu)
|
EVT_MENU(IDM_CLEARCODECACHE, CCodeWindow::OnJitMenu)
|
||||||
EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu)
|
EVT_MENU(IDM_LOGINSTRUCTIONS, CCodeWindow::OnJitMenu)
|
||||||
EVT_MENU(IDM_SEARCHINSTRUCTION, CCodeWindow::OnJitMenu)
|
EVT_MENU(IDM_SEARCHINSTRUCTION, CCodeWindow::OnJitMenu)
|
||||||
|
@ -433,7 +433,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
|
||||||
wxMenu* pCoreMenu = new wxMenu;
|
wxMenu* pCoreMenu = new wxMenu;
|
||||||
|
|
||||||
wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter core")
|
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"
|
" and stepping to work as explained in the Developer Documentation. But it can be very"
|
||||||
" slow, perhaps slower than 1 fps.")
|
" slow, perhaps slower than 1 fps.")
|
||||||
, wxITEM_CHECK);
|
, wxITEM_CHECK);
|
||||||
|
@ -444,7 +444,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
|
||||||
_T("Provide safer execution by not linking the JIT blocks."),
|
_T("Provide safer execution by not linking the JIT blocks."),
|
||||||
wxITEM_CHECK);
|
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("Avoid any involuntary JIT cache clearing, this may prevent Zelda TP from crashing.")
|
||||||
_T(" [This option must be selected before a game is started.]"),
|
_T(" [This option must be selected before a game is started.]"),
|
||||||
wxITEM_CHECK);
|
wxITEM_CHECK);
|
||||||
|
@ -454,22 +454,21 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
|
||||||
pCoreMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage"));
|
pCoreMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage"));
|
||||||
pCoreMenu->Append(IDM_SEARCHINSTRUCTION, _T("&Search for an op"));
|
pCoreMenu->Append(IDM_SEARCHINSTRUCTION, _T("&Search for an op"));
|
||||||
|
|
||||||
#ifdef JIT_OFF_OPTIONS
|
|
||||||
pCoreMenu->AppendSeparator();
|
pCoreMenu->AppendSeparator();
|
||||||
jitoff = pCoreMenu->Append(IDM_JITOFF, _T("&JIT off (JIT core)"),
|
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"),
|
_T("Turn off all JIT functions, but still use the JIT core from Jit.cpp"),
|
||||||
wxITEM_CHECK);
|
wxITEM_CHECK);
|
||||||
jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, 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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK);
|
||||||
jitioff = pCoreMenu->Append(IDM_JITIOFF, _T("&JIT Integer 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);
|
jitpoff = pCoreMenu->Append(IDM_JITPOFF, _T("&JIT Paired off"), wxEmptyString, wxITEM_CHECK);
|
||||||
jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK);
|
jitsroff = pCoreMenu->Append(IDM_JITSROFF, _T("&JIT SystemRegisters off"), wxEmptyString, wxITEM_CHECK);
|
||||||
#endif
|
|
||||||
|
|
||||||
pMenuBar->Append(pCoreMenu, _T("&JIT"));
|
pMenuBar->Append(pCoreMenu, _T("&JIT"));
|
||||||
|
|
||||||
|
@ -506,7 +505,7 @@ void CCodeWindow::CreateMenuOptions(wxMenuBar * _pMenuBar, wxMenu* _pMenu)
|
||||||
, wxString::FromAscii(
|
, wxString::FromAscii(
|
||||||
"Automatically load the Default ISO when Dolphin starts, or the last game you loaded,"
|
"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"
|
" 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"
|
" and retry it several times, either with changes to Dolphin or if you are"
|
||||||
" developing a homebrew game.]")
|
" developing a homebrew game.]")
|
||||||
, wxITEM_CHECK);
|
, wxITEM_CHECK);
|
||||||
|
@ -527,8 +526,6 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event)
|
||||||
bBootToPause = !bBootToPause; return;
|
bBootToPause = !bBootToPause; return;
|
||||||
case IDM_AUTOMATICSTART:
|
case IDM_AUTOMATICSTART:
|
||||||
bAutomaticStart = !bAutomaticStart; return;
|
bAutomaticStart = !bAutomaticStart; return;
|
||||||
|
|
||||||
#ifdef JIT_OFF_OPTIONS
|
|
||||||
case IDM_JITOFF:
|
case IDM_JITOFF:
|
||||||
Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break;
|
Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break;
|
||||||
case IDM_JITLSOFF:
|
case IDM_JITLSOFF:
|
||||||
|
@ -551,7 +548,6 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event)
|
||||||
Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked(); break;
|
Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked(); break;
|
||||||
case IDM_JITSROFF:
|
case IDM_JITSROFF:
|
||||||
Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break;
|
Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the JIT cache to enable these changes
|
// Clear the JIT cache to enable these changes
|
||||||
|
@ -599,9 +595,9 @@ bool CCodeWindow::AutomaticStart()
|
||||||
{
|
{
|
||||||
return GetMenuBar()->IsChecked(IDM_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()
|
bool CCodeWindow::JITBlockLinking()
|
||||||
{
|
{
|
||||||
|
@ -702,8 +698,8 @@ void CCodeWindow::UpdateButtonStates()
|
||||||
// ------------------
|
// ------------------
|
||||||
GetMenuBar()->Enable(IDM_INTERPRETER, Pause); // CPU Mode
|
GetMenuBar()->Enable(IDM_INTERPRETER, Pause); // CPU Mode
|
||||||
|
|
||||||
GetMenuBar()->Enable(IDM_JITUNLIMITED, !Initialized);
|
GetMenuBar()->Enable(IDM_JITNOBLOCKCACHE, !Initialized);
|
||||||
#ifdef JIT_OFF_OPTIONS
|
|
||||||
GetMenuBar()->Enable(IDM_JITOFF, Pause);
|
GetMenuBar()->Enable(IDM_JITOFF, Pause);
|
||||||
GetMenuBar()->Enable(IDM_JITLSOFF, Pause);
|
GetMenuBar()->Enable(IDM_JITLSOFF, Pause);
|
||||||
GetMenuBar()->Enable(IDM_JITLSLXZOFF, Pause);
|
GetMenuBar()->Enable(IDM_JITLSLXZOFF, Pause);
|
||||||
|
@ -715,7 +711,6 @@ void CCodeWindow::UpdateButtonStates()
|
||||||
GetMenuBar()->Enable(IDM_JITIOFF, Pause);
|
GetMenuBar()->Enable(IDM_JITIOFF, Pause);
|
||||||
GetMenuBar()->Enable(IDM_JITPOFF, Pause);
|
GetMenuBar()->Enable(IDM_JITPOFF, Pause);
|
||||||
GetMenuBar()->Enable(IDM_JITSROFF, Pause);
|
GetMenuBar()->Enable(IDM_JITSROFF, Pause);
|
||||||
#endif
|
|
||||||
|
|
||||||
GetMenuBar()->Enable(IDM_CLEARCODECACHE, Pause); // JIT Menu
|
GetMenuBar()->Enable(IDM_CLEARCODECACHE, Pause); // JIT Menu
|
||||||
GetMenuBar()->Enable(IDM_SEARCHINSTRUCTION, Initialized);
|
GetMenuBar()->Enable(IDM_SEARCHINSTRUCTION, Initialized);
|
||||||
|
|
|
@ -74,7 +74,7 @@ class CCodeWindow
|
||||||
bool UseInterpreter();
|
bool UseInterpreter();
|
||||||
bool BootToPause();
|
bool BootToPause();
|
||||||
bool AutomaticStart();
|
bool AutomaticStart();
|
||||||
bool UnlimitedJITCache();
|
bool JITNoBlockCache();
|
||||||
bool JITBlockLinking();
|
bool JITBlockLinking();
|
||||||
void JumpToAddress(u32 _Address);
|
void JumpToAddress(u32 _Address);
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class CCodeWindow
|
||||||
void InitBitmaps();
|
void InitBitmaps();
|
||||||
void CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter);
|
void CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter);
|
||||||
|
|
||||||
wxMenuItem* jitblocklinking, *jitunlimited, *jitoff;
|
wxMenuItem* jitblocklinking, *jitnoblockcache, *jitoff;
|
||||||
wxMenuItem* jitlsoff, *jitlslxzoff, *jitlslwzoff, *jitlslbzxoff;
|
wxMenuItem* jitlsoff, *jitlslxzoff, *jitlslwzoff, *jitlslbzxoff;
|
||||||
wxMenuItem* jitlspoff;
|
wxMenuItem* jitlspoff;
|
||||||
wxMenuItem* jitlsfoff;
|
wxMenuItem* jitlsfoff;
|
||||||
|
|
|
@ -15,28 +15,19 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// =======================================================
|
|
||||||
// File description
|
// File description
|
||||||
// -------------
|
// -------------
|
||||||
/* Purpose of this file: Collect boot settings for Core::Init()
|
// 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()
|
|
||||||
*/
|
|
||||||
// =============
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
// Includes
|
||||||
|
@ -83,7 +74,7 @@ bool BootCore(const std::string& _rFilename)
|
||||||
{
|
{
|
||||||
StartUp.bBootToPause = main_frame->g_pCodeWindow->BootToPause();
|
StartUp.bBootToPause = main_frame->g_pCodeWindow->BootToPause();
|
||||||
StartUp.bAutomaticStart = main_frame->g_pCodeWindow->AutomaticStart();
|
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.bJITBlockLinking = main_frame->g_pCodeWindow->JITBlockLinking();
|
||||||
}
|
}
|
||||||
StartUp.bEnableDebugging = main_frame->g_pCodeWindow ? true : false; // RUNNING_DEBUG
|
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 for example the ISO file is bad we return here
|
||||||
if (!StartUp.AutoSetup(SCoreStartupParameter::BOOT_DEFAULT)) return false;
|
if (!StartUp.AutoSetup(SCoreStartupParameter::BOOT_DEFAULT)) return false;
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// Load game specific settings
|
// Load game specific settings
|
||||||
IniFile game_ini;
|
IniFile game_ini;
|
||||||
std::string unique_id = StartUp.GetUniqueID();
|
std::string unique_id = StartUp.GetUniqueID();
|
||||||
|
@ -126,7 +116,6 @@ bool BootCore(const std::string& _rFilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the game
|
// Run the game
|
||||||
// --------------
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
if(main_frame)
|
if(main_frame)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +136,6 @@ bool BootCore(const std::string& _rFilename)
|
||||||
#else
|
#else
|
||||||
Core::SetState(Core::CORE_RUN);
|
Core::SetState(Core::CORE_RUN);
|
||||||
#endif
|
#endif
|
||||||
// =====================
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +145,4 @@ void Stop()
|
||||||
Core::Stop();
|
Core::Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -131,7 +131,7 @@ enum
|
||||||
IDM_INTERPRETER,
|
IDM_INTERPRETER,
|
||||||
//IDM_DUALCORE, // not used
|
//IDM_DUALCORE, // not used
|
||||||
IDM_AUTOMATICSTART, IDM_BOOTTOPAUSE,
|
IDM_AUTOMATICSTART, IDM_BOOTTOPAUSE,
|
||||||
IDM_JITUNLIMITED, IDM_JITBLOCKLINKING, // JIT
|
IDM_JITNOBLOCKCACHE, IDM_JITBLOCKLINKING, // JIT
|
||||||
IDM_JITOFF,
|
IDM_JITOFF,
|
||||||
IDM_JITLSOFF, IDM_JITLSLXZOFF, IDM_JITLSLWZOFF, IDM_JITLSLBZXOFF,
|
IDM_JITLSOFF, IDM_JITLSLXZOFF, IDM_JITLSLWZOFF, IDM_JITLSLBZXOFF,
|
||||||
IDM_JITLSPOFF, IDM_JITLSFOFF,
|
IDM_JITLSPOFF, IDM_JITLSFOFF,
|
||||||
|
|
Loading…
Reference in New Issue