diff --git a/Source/Core/Core/Src/ActionReplay.cpp b/Source/Core/Core/Src/ActionReplay.cpp index 70574b8a48..00b94ff865 100644 --- a/Source/Core/Core/Src/ActionReplay.cpp +++ b/Source/Core/Core/Src/ActionReplay.cpp @@ -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; } diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 2f005328be..609303bbdb 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -40,6 +40,8 @@ void SCoreStartupParameter::LoadDefaults() bJITOff = false; // debugger only settings bJITLoadStoreOff = false; + bJITLoadStoreFloatingOff = false; + bJITLoadStorePairedOff = false; bJITFloatingPointOff = false; bJITIntegerOff = false; bJITPairedOff = false; diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index c77c3d4b1e..e3176968be 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -39,6 +39,8 @@ struct SCoreStartupParameter bool bUseJIT; bool bJITOff; bool bJITLoadStoreOff; + bool bJITLoadStoreFloatingOff; + bool bJITLoadStorePairedOff; bool bJITFloatingPointOff; bool bJITIntegerOff; bool bJITPairedOff; diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index b7423aeccf..51330a73d3 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -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() diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp index e5c04982bc..5bbc6ca3e5 100644 --- a/Source/Core/Core/Src/MemTools.cpp +++ b/Source/Core/Core/Src/MemTools.cpp @@ -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; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index c64faea0c5..a708973b88 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -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 diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index fc5f4e868c..32470eba24 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -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); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp index ae8602f9d9..f4e729a86e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp @@ -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,42 +101,94 @@ 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 - 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; - default: - 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(); - trampolineCodePtr = GetWritableCodePtr(); - SetCodePtr(codePtr); - int bswapNopCount; - // Check the following BSWAP for REX byte - if ((GetCodePtr()[info.instructionSize] & 0xF0) == 0x40) - bswapNopCount = 3; - else - bswapNopCount = 2; - CALL(trampoline); - NOP((int)info.instructionSize + bswapNopCount - 5); - SetCodePtr(oldCodePtr); + if (accessType == 0) + { + // It's a read. Easy. + ABI_PushAllCallerSavedRegsAndAdjustStack(); + MOV(32, R(ABI_PARAM1), R((X64Reg)addrReg)); + if (info.displacement) { + ADD(32, R(ABI_PARAM1), Imm32(info.displacement)); + } + switch (info.operandSize) { + case 4: + CALL(ProtectFunction((void *)&Memory::Read_U32, 1)); + break; + default: + BackPatchError(StringFromFormat("We don't handle the size %i yet in backpatch", info.operandSize), codePtr, emAddress); + break; + } + ABI_PopAllCallerSavedRegsAndAdjustStack(); + MOV(32, R(dataReg), R(EAX)); + RET(); + trampolineCodePtr = GetWritableCodePtr(); + + SetCodePtr(codePtr); + int bswapNopCount; + // Check the following BSWAP for REX byte + if ((GetCodePtr()[info.instructionSize] & 0xF0) == 0x40) + bswapNopCount = 3; + else + bswapNopCount = 2; + 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 } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h index e64439983c..0c39151e46 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h @@ -20,8 +20,13 @@ #include "Common.h" +#ifdef _WIN32 +#include +#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 diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitRegCache.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitRegCache.cpp index 16649ba64a..645475d92e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitRegCache.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitRegCache.cpp @@ -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 } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index a4ac9376d1..cdccc5abf2 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -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 diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index 100feafad7..7ffa35babd 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -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();*/ } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp index 4b0b8249ba..740149554d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp @@ -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; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp index 750e2ff5fb..f3ead8e61c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp @@ -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; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index fce6f05268..8e0f2cfa2d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -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(); } + + } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp index 4af056d6c6..26bd014c6a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp @@ -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)); } diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index b2d76d57ce..6733f59375 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -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}}, }; diff --git a/Source/Core/Core/Src/PowerPC/Profiler.h b/Source/Core/Core/Src/PowerPC/Profiler.h index 0dae6dbfd1..e07a1f1e02 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.h +++ b/Source/Core/Core/Src/PowerPC/Profiler.h @@ -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) diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 1499c7a9ad..b9dba465ea 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -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, diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.h b/Source/Core/DebuggerWX/Src/CodeWindow.h index b4ad9c74b3..138ffef4c7 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.h +++ b/Source/Core/DebuggerWX/Src/CodeWindow.h @@ -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);