Added memchecks when the MMU is enabled. Thanks to comex for the fix.
Fixes issue 6754.
This commit is contained in:
parent
005af7bd63
commit
41f6f6adc9
|
@ -47,16 +47,6 @@
|
||||||
Core::g_CoreStartupParameter.setting) \
|
Core::g_CoreStartupParameter.setting) \
|
||||||
{Default(inst); return;}
|
{Default(inst); return;}
|
||||||
|
|
||||||
#define MEMCHECK_START \
|
|
||||||
FixupBranch memException; \
|
|
||||||
if (js.memcheck) \
|
|
||||||
{ TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); \
|
|
||||||
memException = J_CC(CC_NZ); }
|
|
||||||
|
|
||||||
#define MEMCHECK_END \
|
|
||||||
if (js.memcheck) \
|
|
||||||
SetJumpTarget(memException);
|
|
||||||
|
|
||||||
class Jit64 : public Jitx86Base
|
class Jit64 : public Jitx86Base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -199,12 +199,12 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
gpr.Lock(a, b, d);
|
gpr.Lock(a, b, d);
|
||||||
gpr.BindToRegister(d, false, true);
|
gpr.BindToRegister(d, js.memcheck, true);
|
||||||
SafeLoadToReg(gpr.RX(d), opAddress, accessSize, 0, RegistersInUse(), signExtend);
|
SafeLoadToReg(gpr.RX(d), opAddress, accessSize, 0, RegistersInUse(), signExtend);
|
||||||
|
|
||||||
if (update && js.memcheck && !zeroOffset)
|
if (update && js.memcheck && !zeroOffset)
|
||||||
{
|
{
|
||||||
gpr.BindToRegister(a, false, true);
|
gpr.BindToRegister(a, true, true);
|
||||||
MEMCHECK_START
|
MEMCHECK_START
|
||||||
MOV(32, gpr.R(a), opAddress);
|
MOV(32, gpr.R(a), opAddress);
|
||||||
MEMCHECK_END
|
MEMCHECK_END
|
||||||
|
|
|
@ -119,7 +119,10 @@ u8 *EmuCodeBlock::UnsafeLoadToReg(X64Reg reg_value, Gen::OpArg opAddress, int ac
|
||||||
|
|
||||||
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend)
|
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress, int accessSize, s32 offset, u32 registersInUse, bool signExtend)
|
||||||
{
|
{
|
||||||
|
if (!jit->js.memcheck)
|
||||||
|
{
|
||||||
registersInUse &= ~(1 << RAX | 1 << reg_value);
|
registersInUse &= ~(1 << RAX | 1 << reg_value);
|
||||||
|
}
|
||||||
#if defined(_M_X64)
|
#if defined(_M_X64)
|
||||||
#ifdef ENABLE_MEM_CHECK
|
#ifdef ENABLE_MEM_CHECK
|
||||||
if (!Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging && Core::g_CoreStartupParameter.bFastmem)
|
if (!Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging && Core::g_CoreStartupParameter.bFastmem)
|
||||||
|
@ -164,6 +167,9 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
case 8: ABI_CallFunctionC((void *)&Memory::Read_U8_ZX, address); break;
|
case 8: ABI_CallFunctionC((void *)&Memory::Read_U8_ZX, address); break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
||||||
|
|
||||||
|
MEMCHECK_START
|
||||||
|
|
||||||
if (signExtend && accessSize < 32)
|
if (signExtend && accessSize < 32)
|
||||||
{
|
{
|
||||||
// Need to sign extend values coming from the Read_U* functions.
|
// Need to sign extend values coming from the Read_U* functions.
|
||||||
|
@ -173,6 +179,8 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
{
|
{
|
||||||
MOVZX(32, accessSize, reg_value, R(EAX));
|
MOVZX(32, accessSize, reg_value, R(EAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEMCHECK_END
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -192,6 +200,9 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
case 8: ABI_CallFunctionR((void *)&Memory::Read_U8_ZX, EAX); break;
|
case 8: ABI_CallFunctionR((void *)&Memory::Read_U8_ZX, EAX); break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
||||||
|
|
||||||
|
MEMCHECK_START
|
||||||
|
|
||||||
if (signExtend && accessSize < 32)
|
if (signExtend && accessSize < 32)
|
||||||
{
|
{
|
||||||
// Need to sign extend values coming from the Read_U* functions.
|
// Need to sign extend values coming from the Read_U* functions.
|
||||||
|
@ -202,6 +213,8 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
MOVZX(32, accessSize, reg_value, R(EAX));
|
MOVZX(32, accessSize, reg_value, R(EAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEMCHECK_END
|
||||||
|
|
||||||
FixupBranch exit = J();
|
FixupBranch exit = J();
|
||||||
SetJumpTarget(fast);
|
SetJumpTarget(fast);
|
||||||
UnsafeLoadToReg(reg_value, R(EAX), accessSize, 0, signExtend);
|
UnsafeLoadToReg(reg_value, R(EAX), accessSize, 0, signExtend);
|
||||||
|
@ -220,6 +233,9 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
case 8: ABI_CallFunctionA((void *)&Memory::Read_U8_ZX, opAddress); break;
|
case 8: ABI_CallFunctionA((void *)&Memory::Read_U8_ZX, opAddress); break;
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
ABI_PopRegistersAndAdjustStack(registersInUse, false);
|
||||||
|
|
||||||
|
MEMCHECK_START
|
||||||
|
|
||||||
if (signExtend && accessSize < 32)
|
if (signExtend && accessSize < 32)
|
||||||
{
|
{
|
||||||
// Need to sign extend values coming from the Read_U* functions.
|
// Need to sign extend values coming from the Read_U* functions.
|
||||||
|
@ -230,6 +246,8 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg & opAddress,
|
||||||
MOVZX(32, accessSize, reg_value, R(EAX));
|
MOVZX(32, accessSize, reg_value, R(EAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEMCHECK_END
|
||||||
|
|
||||||
FixupBranch exit = J();
|
FixupBranch exit = J();
|
||||||
SetJumpTarget(fast);
|
SetJumpTarget(fast);
|
||||||
UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend);
|
UnsafeLoadToReg(reg_value, opAddress, accessSize, offset, signExtend);
|
||||||
|
|
|
@ -8,6 +8,17 @@
|
||||||
#include "x64Emitter.h"
|
#include "x64Emitter.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#define MEMCHECK_START \
|
||||||
|
FixupBranch memException; \
|
||||||
|
if (jit->js.memcheck) \
|
||||||
|
{ TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_DSI)); \
|
||||||
|
memException = J_CC(CC_NZ, true); }
|
||||||
|
|
||||||
|
#define MEMCHECK_END \
|
||||||
|
if (jit->js.memcheck) \
|
||||||
|
SetJumpTarget(memException);
|
||||||
|
|
||||||
|
|
||||||
// Like XCodeBlock but has some utilities for memory access.
|
// Like XCodeBlock but has some utilities for memory access.
|
||||||
class EmuCodeBlock : public Gen::XCodeBlock
|
class EmuCodeBlock : public Gen::XCodeBlock
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue