diff options
Diffstat (limited to 'Source/Core')
20 files changed, 215 insertions, 62 deletions
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));
+
+ 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;
}
- 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;
+ 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;
}
- // * 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);
+ 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 <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
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);
|
