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:
parent
d159bc9998
commit
6f617c4175
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue