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.
This commit is contained in:
Fiora 2014-08-29 12:19:58 -07:00
parent d159bc9998
commit 6f617c4175
4 changed files with 43 additions and 8 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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();
}

View File

@ -260,17 +260,37 @@ void Jit64::dcbz(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff);
if (Core::g_CoreStartupParameter.bDCBZOFF)
return;
// FIXME
FALLBACK_IF(true);
int a = inst.RA;
int b = inst.RB;
MOV(32, R(EAX), gpr.R(inst.RB));
if (inst.RA)
ADD(32, R(EAX), gpr.R(inst.RA));
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(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)