Added memchecks when the MMU is enabled. Thanks to comex for the fix.

Fixes issue 6754.
This commit is contained in:
skidau 2013-10-26 14:32:03 +11:00
parent 005af7bd63
commit 41f6f6adc9
4 changed files with 32 additions and 13 deletions

View File

@ -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:

View File

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

View File

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

View File

@ -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
{ {