summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorFiora <fioraaeterna@gmail.com>2014-08-29 12:19:58 -0700
committerFiora <fioraaeterna@gmail.com>2014-08-29 12:19:58 -0700
commit6f617c41755a5d6aff3ef59fc4eae3fd53b261d9 (patch)
tree87642662b127e795ca1592ac432fab40dbc1aaaf /Source
parentd159bc9998f13f7e3271662a0a7ddfa3225e1aff (diff)
JIT64: try enabling dcbz again
This time, check the address carefully beforehand, since apparently some games do horrible things like running it on non-RAM addresses, or at the very least virtual addresses.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HW/Memmap.cpp14
-rw-r--r--Source/Core/Core/HW/Memmap.h1
-rw-r--r--Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp34
4 files changed, 43 insertions, 8 deletions
diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp
index c3d3099851..f6a4dbe2c2 100644
--- a/Source/Core/Core/HW/Memmap.cpp
+++ b/Source/Core/Core/HW/Memmap.cpp
@@ -235,6 +235,20 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength)
}
}
+void ClearCacheLine(const u32 _Address)
+{
+ u8 *ptr = GetPointer(_Address);
+ if (ptr != nullptr)
+ {
+ memset(ptr, 0, 32);
+ }
+ else
+ {
+ for (u32 i = 0; i < 32; i += 8)
+ Write_U64(0, _Address + i);
+ }
+}
+
void DMA_LCToMemory(const u32 _MemAddr, const u32 _CacheAddr, const u32 _iNumBlocks)
{
const u8 *src = m_pL1Cache + (_CacheAddr & 0x3FFFF);
diff --git a/Source/Core/Core/HW/Memmap.h b/Source/Core/Core/HW/Memmap.h
index d1ae34711d..f130cf643f 100644
--- a/Source/Core/Core/HW/Memmap.h
+++ b/Source/Core/Core/HW/Memmap.h
@@ -126,6 +126,7 @@ u8* GetPointer(const u32 _Address);
void DMA_LCToMemory(const u32 _iMemAddr, const u32 _iCacheAddr, const u32 _iNumBlocks);
void DMA_MemoryToLC(const u32 _iCacheAddr, const u32 _iMemAddr, const u32 _iNumBlocks);
void Memset(const u32 _Address, const u8 _Data, const u32 _iLength);
+void ClearCacheLine(const u32 _Address); // Zeroes 32 bytes; address should be 32-byte-aligned
// TLB functions
void SDRUpdated();
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
index 199b3661f3..fc04cbfb9b 100644
--- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
@@ -376,7 +376,7 @@ void Interpreter::dcbz(UGeckoInstruction _inst)
{
// HACK but works... we think
if (!Core::g_CoreStartupParameter.bDCBZOFF)
- Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
+ Memory::ClearCacheLine(Helper_Get_EA_X(_inst) & (~31));
if (!JitInterface::GetCore())
PowerPC::CheckExceptions();
}
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
index 9c3e5bd876..a9e7cb94ab 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -260,17 +260,37 @@ void Jit64::dcbz(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff);
+ if (Core::g_CoreStartupParameter.bDCBZOFF)
+ return;
+
+ int a = inst.RA;
+ int b = inst.RB;
- // FIXME
- FALLBACK_IF(true);
+ u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS;
+ if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
+ mem_mask |= Memory::ADDR_MASK_MEM1;
- MOV(32, R(EAX), gpr.R(inst.RB));
- if (inst.RA)
- ADD(32, R(EAX), gpr.R(inst.RA));
+ MOV(32, R(EAX), gpr.R(b));
+ if (a)
+ ADD(32, R(EAX), gpr.R(a));
AND(32, R(EAX), Imm32(~31));
+ TEST(32, R(EAX), Imm32(mem_mask));
+ FixupBranch fast = J_CC(CC_Z, true);
+
+ // Should this code ever run? I can't find any games that use DCBZ on non-physical addresses, but
+ // supposedly there are, at least for some MMU titles. Let's be careful and support it to be sure.
+ MOV(32, M(&PC), Imm32(jit->js.compilerPC));
+ u32 registersInUse = CallerSavedRegistersInUse();
+ ABI_PushRegistersAndAdjustStack(registersInUse, false);
+ ABI_CallFunctionR((void *)&Memory::ClearCacheLine, EAX);
+ ABI_PopRegistersAndAdjustStack(registersInUse, false);
+
+ FixupBranch exit = J();
+ SetJumpTarget(fast);
PXOR(XMM0, R(XMM0));
- MOVAPS(MComplex(EBX, EAX, SCALE_1, 0), XMM0);
- MOVAPS(MComplex(EBX, EAX, SCALE_1, 16), XMM0);
+ MOVAPS(MComplex(RBX, RAX, SCALE_1, 0), XMM0);
+ MOVAPS(MComplex(RBX, RAX, SCALE_1, 16), XMM0);
+ SetJumpTarget(exit);
}
void Jit64::stX(UGeckoInstruction inst)