summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorhrydgard <hrydgard@gmail.com>2008-10-28 22:38:53 +0000
committerhrydgard <hrydgard@gmail.com>2008-10-28 22:38:53 +0000
commit9e14b2575df7824769771eec77d450038c8aae39 (patch)
tree94acd71f61cd7d77bbae79770378e7c1bb0ceb67 /Source
parent2899ebc84cf8aff2592178a7951fe0f663ef6e87 (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/Src/ActionReplay.cpp7
-rw-r--r--Source/Core/Core/Src/CoreParameter.cpp2
-rw-r--r--Source/Core/Core/Src/CoreParameter.h2
-rw-r--r--Source/Core/Core/Src/HW/VideoInterface.cpp1
-rw-r--r--Source/Core/Core/Src/MemTools.cpp5
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp9
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h4
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp139
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h7
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/JitRegCache.cpp7
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp17
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp18
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp10
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp10
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_Util.cpp2
-rw-r--r--Source/Core/Core/Src/PowerPC/PPCTables.cpp4
-rw-r--r--Source/Core/Core/Src/PowerPC/Profiler.h11
-rw-r--r--Source/Core/DebuggerWX/Src/CodeWindow.cpp12
-rw-r--r--Source/Core/DebuggerWX/Src/CodeWindow.h6
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);