Random grab-bag of stuff: Finer grained JIT disabling (jpeterson's debug tool), show activated cheats, some comments, one more jitted instruction, support in backpatcher for writes, currently disabled because Beyond Good and Evil crashes when using it. yes this change should be split but i'm just too lazy, sorry.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@996 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-10-28 22:38:53 +00:00
parent 2899ebc84c
commit 9e14b2575d
20 changed files with 215 additions and 62 deletions

View File

@ -99,8 +99,11 @@ void LoadActionReplayCodes(IniFile &ini)
encryptedLines.clear();
}
currentCode.name = line;
if (line[0] == '+') currentCode.active = true;
else currentCode.active = false;
Core::DisplayMessage("AR code active: " + line, 5000);
if (line[0] == '+')
currentCode.active = true;
else
currentCode.active = false;
continue;
}

View File

@ -40,6 +40,8 @@ void SCoreStartupParameter::LoadDefaults()
bJITOff = false; // debugger only settings
bJITLoadStoreOff = false;
bJITLoadStoreFloatingOff = false;
bJITLoadStorePairedOff = false;
bJITFloatingPointOff = false;
bJITIntegerOff = false;
bJITPairedOff = false;

View File

@ -39,6 +39,8 @@ struct SCoreStartupParameter
bool bUseJIT;
bool bJITOff;
bool bJITLoadStoreOff;
bool bJITLoadStoreFloatingOff;
bool bJITLoadStorePairedOff;
bool bJITFloatingPointOff;
bool bJITIntegerOff;
bool bJITPairedOff;

View File

@ -181,6 +181,7 @@ void DoState(PointerWrap &p)
p.Do(LineCount);
p.Do(LinesPerField);
p.Do(LastTime);
// p.Do(NextXFBRender); // Activate when changing saves next time.
}
void Init()

View File

@ -80,11 +80,12 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
//We could emulate the memory accesses here, but then they would still be around to take up
//execution resources. Instead, we backpatch into a generic memory call and retry.
Jit64::BackPatch(codePtr, accessType, emAddress);
u8 *new_rip = Jit64::BackPatch(codePtr, accessType, emAddress, ctx);
// We no longer touch Rip, since we return back to the instruction, after overwriting it with a
// trampoline jump and some nops
//ctx->Rip = (DWORD_PTR)codeAddr + info.instructionSize;
if (new_rip)
ctx->Rip = (DWORD_PTR)new_rip;
}
return (DWORD)EXCEPTION_CONTINUE_EXECUTION;

View File

@ -108,7 +108,14 @@ extern int blocksExecuted;
(single precision can be used in write gather pipe, specialized fast check added)
* AMD only - use movaps instead of movapd when loading ps from memory?
* HLE functions like floorf, sin, memcpy, etc - they can be much faster
* ABI optimizations - drop F0-F13 on blr, for example. Watch out for context switching.
CR2-CR4 are non-volatile, rest of CR is volatile -> dropped on blr.
R5-R12 are volatile -> dropped on blr.
* classic inlining across calls.
Metroid wants
subc
subfe
Low hanging fruit:
stfd -- guaranteed in memory

View File

@ -122,6 +122,7 @@ namespace Jit64
void mfmsr(UGeckoInstruction inst);
void mftb(UGeckoInstruction inst);
void mtcrf(UGeckoInstruction inst);
void mfcr(UGeckoInstruction inst);
void reg_imm(UGeckoInstruction inst);
@ -166,9 +167,12 @@ namespace Jit64
void srwx(UGeckoInstruction inst);
void dcbz(UGeckoInstruction inst);
void lfsx(UGeckoInstruction inst);
void subfic(UGeckoInstruction inst);
void subfcx(UGeckoInstruction inst);
void subfx(UGeckoInstruction inst);
void subfex(UGeckoInstruction inst);
void lbzx(UGeckoInstruction inst);
void lmw(UGeckoInstruction inst);

View File

@ -19,6 +19,7 @@
#include "Common.h"
#include "disasm.h"
#include "JitAsm.h"
#include "JitBackpatch.h"
#include "../../HW/Memmap.h"
@ -58,28 +59,28 @@ void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) {
// 1) It's really necessary. We don't know anything about the context.
// 2) It doesn't really hurt. Only instructions that access I/O will get these, and there won't be
// that many of them in a typical program/game.
void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
{
#ifdef _M_X64
if (!IsInJitCode(codePtr))
return; // this will become a regular crash real soon after this
return 0; // this will become a regular crash real soon after this
// TODO: also mark and remember the instruction address as known HW memory access, for use in later compiles.
// But to do that we need to be able to reconstruct what instruction wrote this code, and we can't do that yet.
u8 *oldCodePtr = GetWritableCodePtr();
InstructionInfo info;
if (!DisassembleMov(codePtr, info, accessType)) {
BackPatchError("BackPatch - failed to disassemble MOV instruction", codePtr, emAddress);
}
/*
if (info.isMemoryWrite) {
if (!Memory::IsRAMAddress(emAddress, true)) {
PanicAlert("Write to invalid address %08x", emAddress);
PanicAlert("Exception: Caught write to invalid address %08x", emAddress);
return;
}
BackPatchError("BackPatch - determined that MOV is write, not yet supported and should have been caught before",
codePtr, emAddress);
}
}*/
if (info.operandSize != 4) {
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
}
@ -89,9 +90,9 @@ void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
if (info.otherReg != RBX)
PanicAlert("BackPatch : Base reg not RBX."
"\n\nAttempted to access %08x.", emAddress);
if (accessType == OP_ACCESS_WRITE)
PanicAlert("BackPatch : Currently only supporting reads."
"\n\nAttempted to write to %08x.", emAddress);
//if (accessType == OP_ACCESS_WRITE)
// PanicAlert("BackPatch : Currently only supporting reads."
// "\n\nAttempted to write to %08x.", emAddress);
// OK, let's write a trampoline, and a jump to it.
// Later, let's share trampolines.
@ -100,19 +101,16 @@ void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
// Next step - support writes, special case FIFO writes. Also, support 32-bit mode.
u8 *trampoline = trampolineCodePtr;
SetCodePtr(trampolineCodePtr);
// * Save all volatile regs
if (accessType == 0)
{
// It's a read. Easy.
ABI_PushAllCallerSavedRegsAndAdjustStack();
// * Set up stack frame.
// * Call ReadMemory32
//LEA(32, ABI_PARAM1, MDisp((X64Reg)addrReg, info.displacement));
MOV(32, R(ABI_PARAM1), R((X64Reg)addrReg));
if (info.displacement) {
ADD(32, R(ABI_PARAM1), Imm32(info.displacement));
}
switch (info.operandSize) {
//case 1:
// CALL((void *)&Memory::Read_U8);
// break;
case 4:
CALL(ProtectFunction((void *)&Memory::Read_U32, 1));
break;
@ -120,7 +118,6 @@ void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
BackPatchError(StringFromFormat("We don't handle the size %i yet in backpatch", info.operandSize), codePtr, emAddress);
break;
}
// * Tear down stack frame.
ABI_PopAllCallerSavedRegsAndAdjustStack();
MOV(32, R(dataReg), R(EAX));
RET();
@ -136,6 +133,62 @@ void BackPatch(u8 *codePtr, int accessType, u32 emAddress)
CALL(trampoline);
NOP((int)info.instructionSize + bswapNopCount - 5);
SetCodePtr(oldCodePtr);
return codePtr;
}
else if (accessType == 1)
{
// It's a write. Yay. Remember that we don't have to be super efficient since it's "just" a
// hardware access - we can take shortcuts.
//if (emAddress == 0xCC008000)
// PanicAlert("caught a fifo write");
if (dataReg != EAX)
PanicAlert("Backpatch write - not through EAX");
CMP(32, R(addrReg), Imm32(0xCC008000));
FixupBranch skip_fast = J_CC(CC_NE, false);
MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg));
CALL((void*)Asm::fifoDirectWrite32);
RET();
SetJumpTarget(skip_fast);
ABI_PushAllCallerSavedRegsAndAdjustStack();
if (addrReg != ABI_PARAM1) {
//INT3();
MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg));
MOV(32, R(ABI_PARAM2), R((X64Reg)addrReg));
} else {
MOV(32, R(ABI_PARAM2), R((X64Reg)addrReg));
MOV(32, R(ABI_PARAM1), R((X64Reg)dataReg));
}
if (info.displacement) {
ADD(32, R(ABI_PARAM2), Imm32(info.displacement));
}
switch (info.operandSize) {
case 4:
CALL(ProtectFunction((void *)&Memory::Write_U32, 2));
break;
default:
BackPatchError(StringFromFormat("We don't handle the size %i yet in backpatch", info.operandSize), codePtr, emAddress);
break;
}
ABI_PopAllCallerSavedRegsAndAdjustStack();
RET();
trampolineCodePtr = GetWritableCodePtr();
// We know it's EAX so the BSWAP before will be two byte. Overwrite it.
SetCodePtr(codePtr - 2);
CALL(trampoline);
NOP((int)info.instructionSize - 3);
if (info.instructionSize < 3)
PanicAlert("instruction too small");
SetCodePtr(oldCodePtr);
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
ctx->Rax = _byteswap_ulong(ctx->Rax);
return codePtr - 2;
}
return 0;
#endif
}

View File

@ -20,8 +20,13 @@
#include "Common.h"
#ifdef _WIN32
#include <windows.h>
#endif
namespace Jit64 {
void BackPatch(u8 *codePtr, int accessType, u32 emAddress);
// Returns the new RIP value
u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
}
#endif

View File

@ -46,17 +46,18 @@ namespace Jit64
}
// todo: sort to find the most popular regs
int maxPreload = 3;
/*
int maxPreload = 2;
for (int i = 0; i < 32; i++)
{
if (stats.numReads[i] > 2 || stats.numWrites[i] >= 2)
{
LoadToX64(i, true, false); //, stats.firstRead[i] <= stats.firstWrite[i], false);
LoadToX64(i, true, false); //stats.firstRead[i] <= stats.firstWrite[i], false);
maxPreload--;
if (!maxPreload)
break;
}
}
}*/
//Find top regs - preload them (load bursts ain't bad)
//But only preload IF written OR reads >= 3
}

View File

@ -436,6 +436,23 @@ namespace Jit64
*/
}
void subfex(UGeckoInstruction inst)
{
INSTRUCTION_START;
Default(inst);
return;
/*
u32 a = m_GPR[_inst.RA];
u32 b = m_GPR[_inst.RB];
int carry = GetCarry();
m_GPR[_inst.RD] = (~a) + b + carry;
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
if (_inst.OE) PanicAlert("OE: subfcx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
*/
}
void subfx(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS

View File

@ -112,6 +112,9 @@ namespace Jit64
return;
}
// R2 always points to the small read-only data area. We could bake R2-relative loads into immediates.
// R13 always points to the small read/write data area. Not so exciting but at least could drop checks in 32-bit safe mode.
s32 offset = (s32)(s16)inst.SIMM_16;
if (!a)
{
@ -293,6 +296,19 @@ namespace Jit64
return;
}
/* // TODO - figure out why Beyond Good and Evil hates this
#ifdef _M_X64
if (accessSize == 32 && !update && jo.enableFastMem)
{
// Fast and daring - requires 64-bit
MOV(32, R(EAX), gpr.R(s));
gpr.LoadToX64(a, true, false);
BSWAP(32, EAX);
MOV(accessSize, MComplex(RBX, gpr.RX(a), SCALE_1, (u32)offset), R(EAX));
return;
}
#endif*/
//Still here? Do regular path.
#ifndef _WIN32
if(accessSize == 8)
@ -345,6 +361,7 @@ namespace Jit64
INSTRUCTION_START;
Default(inst);
return;
/*
/// BUGGY
//return _inst.RA ? (m_GPR[_inst.RA] + _inst.SIMM_16) : _inst.SIMM_16;
@ -363,7 +380,6 @@ namespace Jit64
ADD(32, R(ESI), Imm8(4));
ADD(32, R(ECX), Imm8(1));
CMP(32, R(ECX), Imm8(32));
J_CC(CC_NE, loopPtr, false);
gpr.UnlockAllX();*/
}

View File

@ -67,7 +67,7 @@ u32 GC_ALIGNED16(temp32);
void lfs(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
@ -107,7 +107,7 @@ void lfd(UGeckoInstruction inst)
Default(inst);
return;
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
@ -155,7 +155,7 @@ void lfd(UGeckoInstruction inst)
void stfd(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
@ -202,7 +202,7 @@ void stfd(UGeckoInstruction inst)
void stfs(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
@ -269,7 +269,7 @@ void stfsx(UGeckoInstruction inst)
void lfsx(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;

View File

@ -110,7 +110,7 @@ const double GC_ALIGNED16(m_dequantizeTableD[]) =
void psq_st(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStorePairedOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;
@ -302,7 +302,7 @@ void psq_st(UGeckoInstruction inst)
void psq_l(UGeckoInstruction inst)
{
#ifdef JIT_OFF_OPTIONS
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStorePairedOff)
{Default(inst); return;} // turn off from debugger
#endif
INSTRUCTION_START;

View File

@ -49,6 +49,7 @@ namespace Jit64
{
case SPR_LR:
case SPR_CTR:
case SPR_XER:
// These are safe to do the easy way, see the bottom of this function.
break;
@ -157,6 +158,13 @@ namespace Jit64
mfspr(inst);
}
void mfcr(UGeckoInstruction inst)
{
int d = inst.RD;
gpr.LoadToX64(d, false, true);
MOV(32, gpr.R(d), M(&PowerPC::ppcState.cr));
}
void mtcrf(UGeckoInstruction inst)
{
u32 mask = 0;
@ -180,5 +188,7 @@ namespace Jit64
}
gpr.UnlockAllX();
}
}

View File

@ -131,10 +131,12 @@ void WriteFloatToConstRamAddress(const Gen::X64Reg& xmm_reg, u32 address)
}
void ForceSinglePrecisionS(X64Reg xmm) {
// Most games don't need these. Zelda requires it though - some platforms get stuck without them.
CVTSD2SS(xmm, R(xmm));
CVTSS2SD(xmm, R(xmm));
}
void ForceSinglePrecisionP(X64Reg xmm) {
// Most games don't need these. Zelda requires it though - some platforms get stuck without them.
CVTPD2PS(xmm, R(xmm));
CVTPS2PD(xmm, R(xmm));
}

View File

@ -357,7 +357,7 @@ GekkoOPTemplate table31[] =
{759, Interpreter::stfdux, Jit64::Default, {"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
{983, Interpreter::stfiwx, Jit64::Default, {"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
{19, Interpreter::mfcr, Jit64::Default, {"mfcr", OPTYPE_SYSTEM, 0}},
{19, Interpreter::mfcr, Jit64::mfcr, {"mfcr", OPTYPE_SYSTEM, 0}},
{83, Interpreter::mfmsr, Jit64::mfmsr, {"mfmsr", OPTYPE_SYSTEM, 0}},
{144, Interpreter::mtcrf, Jit64::mtcrf, {"mtcrf", OPTYPE_SYSTEM, 0}},
{146, Interpreter::mtmsr, Jit64::mtmsr, {"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}},
@ -399,7 +399,7 @@ GekkoOPTemplate table31_2[] =
{104, Interpreter::negx, Jit64::negx, {"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}},
{40, Interpreter::subfx, Jit64::subfx, {"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}},
{8, Interpreter::subfcx, Jit64::subfcx, {"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_SET_CA | FL_RC_BIT}},
{136, Interpreter::subfex, Jit64::Default, {"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{136, Interpreter::subfex, Jit64::subfex, {"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{232, Interpreter::subfmex, Jit64::Default, {"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{200, Interpreter::subfzex, Jit64::Default, {"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
};

View File

@ -20,6 +20,8 @@
#define _PROFILER_H
#ifdef _WIN32
#ifdef _M_IX86
#define PROFILER_QUERY_PERFORMACE_COUNTER(pt) \
LEA(32, EAX, M(pt)); PUSH(EAX); \
CALL(QueryPerformanceCounter)
@ -38,6 +40,15 @@
#define PROFILER_VPUSH PUSH(EAX);PUSH(ECX);PUSH(EDX)
#define PROFILER_VPOP POP(EDX);POP(ECX);POP(EAX)
#else
#define PROFILER_QUERY_PERFORMACE_COUNTER(pt)
#define PROFILER_ADD_DIFF_LARGE_INTEGER(pdt, pt1, pt0)
#define PROFILER_VPUSH
#define PROFILER_VPOP
#endif
#else
// TODO
#define PROFILER_QUERY_PERFORMACE_COUNTER(pt)

View File

@ -92,6 +92,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnInterpreter) // CPU Mode
EVT_MENU(IDM_JITOFF, CCodeWindow::OnJITOff)
EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnJITLSOff)
EVT_MENU(IDM_JITLSFOFF, CCodeWindow::OnJITLSFOff)
EVT_MENU(IDM_JITLSPOFF, CCodeWindow::OnJITLSPOff)
EVT_MENU(IDM_JITFPOFF, CCodeWindow::OnJITFPOff)
EVT_MENU(IDM_JITIOFF, CCodeWindow::OnJITIOff)
EVT_MENU(IDM_JITPOFF, CCodeWindow::OnJITPOff)
@ -334,6 +336,12 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
jitlsoff = pCoreMenu->Append(IDM_JITLSOFF, _T("&JIT LoadStore off"), wxEmptyString, wxITEM_CHECK);
jitlsoff->Check(_LocalCoreStartupParameter.bJITLoadStoreOff);
jitlspoff = pCoreMenu->Append(IDM_JITLSFOFF, _T("&JIT LoadStore Floating off"), wxEmptyString, wxITEM_CHECK);
jitlspoff->Check(_LocalCoreStartupParameter.bJITLoadStoreFloatingOff);
jitlsfoff = pCoreMenu->Append(IDM_JITLSPOFF, _T("&JIT LoadStore Paired off"), wxEmptyString, wxITEM_CHECK);
jitlsfoff->Check(_LocalCoreStartupParameter.bJITLoadStorePairedOff);
jitfpoff = pCoreMenu->Append(IDM_JITFPOFF, _T("&JIT FloatingPoint off"), wxEmptyString, wxITEM_CHECK);
jitfpoff->Check(_LocalCoreStartupParameter.bJITFloatingPointOff);
@ -470,6 +478,10 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event) {DoJITOff(event, jitoff,
Core::g_CoreStartupParameter.bJITOff);}
void CCodeWindow::OnJITLSOff(wxCommandEvent& event) {DoJITOff(event, jitlsoff,
Core::g_CoreStartupParameter.bJITLoadStoreOff);}
void CCodeWindow::OnJITLSFOff(wxCommandEvent& event) {DoJITOff(event, jitlsoff,
Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff);}
void CCodeWindow::OnJITLSPOff(wxCommandEvent& event) {DoJITOff(event, jitlsoff,
Core::g_CoreStartupParameter.bJITLoadStorePairedOff);}
void CCodeWindow::OnJITFPOff(wxCommandEvent& event) {DoJITOff(event, jitfpoff,
Core::g_CoreStartupParameter.bJITFloatingPointOff);}
void CCodeWindow::OnJITIOff(wxCommandEvent& event) {DoJITOff(event, jitioff,

View File

@ -81,6 +81,8 @@ class CCodeWindow
IDM_INTERPRETER,
IDM_JITOFF, // jit
IDM_JITLSOFF,
IDM_JITLSPOFF,
IDM_JITLSFOFF,
IDM_JITIOFF,
IDM_JITFPOFF,
IDM_JITPOFF,
@ -129,6 +131,8 @@ class CCodeWindow
wxMenuItem* jitoff;
wxMenuItem* jitlsoff;
wxMenuItem* jitlspoff;
wxMenuItem* jitlsfoff;
wxMenuItem* jitfpoff;
wxMenuItem* jitioff;
wxMenuItem* jitpoff;
@ -173,6 +177,8 @@ class CCodeWindow
void OnInterpreter(wxCommandEvent& event); // cpu mode menu
void OnJITOff(wxCommandEvent& event);
void OnJITLSOff(wxCommandEvent& event);
void OnJITLSPOff(wxCommandEvent& event);
void OnJITLSFOff(wxCommandEvent& event);
void OnJITFPOff(wxCommandEvent& event);
void OnJITIOff(wxCommandEvent& event);
void OnJITPOff(wxCommandEvent& event);