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)
|
||||
{
|
||||
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_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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue