Merge pull request #904 from FioraAeterna/dcbz

JIT64: try enabling dcbz again
This commit is contained in:
Pierre Bourdon 2014-09-02 15:41:40 +02:00
commit ddb2aefedf
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) void DMA_LCToMemory(const u32 _MemAddr, const u32 _CacheAddr, const u32 _iNumBlocks)
{ {
const u8 *src = m_pL1Cache + (_CacheAddr & 0x3FFFF); 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_LCToMemory(const u32 _iMemAddr, const u32 _iCacheAddr, const u32 _iNumBlocks);
void DMA_MemoryToLC(const u32 _iCacheAddr, const u32 _iMemAddr, 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 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 // TLB functions
void SDRUpdated(); void SDRUpdated();

View File

@ -376,7 +376,7 @@ void Interpreter::dcbz(UGeckoInstruction _inst)
{ {
// HACK but works... we think // HACK but works... we think
if (!Core::g_CoreStartupParameter.bDCBZOFF) 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()) if (!JitInterface::GetCore())
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
} }

View File

@ -260,17 +260,37 @@ void Jit64::dcbz(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITLoadStoreOff); JITDISABLE(bJITLoadStoreOff);
if (Core::g_CoreStartupParameter.bDCBZOFF)
return;
// FIXME int a = inst.RA;
FALLBACK_IF(true); int b = inst.RB;
MOV(32, R(EAX), gpr.R(inst.RB)); u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS;
if (inst.RA) if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.bTLBHack)
ADD(32, R(EAX), gpr.R(inst.RA)); 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)); 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)); PXOR(XMM0, R(XMM0));
MOVAPS(MComplex(EBX, EAX, SCALE_1, 0), XMM0); MOVAPS(MComplex(RBX, RAX, SCALE_1, 0), XMM0);
MOVAPS(MComplex(EBX, EAX, SCALE_1, 16), XMM0); MOVAPS(MComplex(RBX, RAX, SCALE_1, 16), XMM0);
SetJumpTarget(exit);
} }
void Jit64::stX(UGeckoInstruction inst) void Jit64::stX(UGeckoInstruction inst)