mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #2316 from comex/fix-watch
Fix watchpoints ("memory breakpoints") with JIT
This commit is contained in:
@@ -165,8 +165,13 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mcstrs)
|
||||
|
||||
void MemChecks::Add(const TMemCheck& _rMemoryCheck)
|
||||
{
|
||||
bool had_any = HasAny();
|
||||
if (GetMemCheck(_rMemoryCheck.StartAddress) == nullptr)
|
||||
m_MemChecks.push_back(_rMemoryCheck);
|
||||
// If this is the first one, clear the JIT cache so it can switch to
|
||||
// watchpoint-compatible code.
|
||||
if (!had_any)
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
void MemChecks::Remove(u32 _Address)
|
||||
@@ -179,6 +184,8 @@ void MemChecks::Remove(u32 _Address)
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!HasAny())
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
TMemCheck *MemChecks::GetMemCheck(u32 address)
|
||||
@@ -200,7 +207,7 @@ TMemCheck *MemChecks::GetMemCheck(u32 address)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, bool write, int size, u32 pc)
|
||||
bool TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, bool write, int size, u32 pc)
|
||||
{
|
||||
if ((write && OnWrite) || (!write && OnRead))
|
||||
{
|
||||
@@ -213,9 +220,9 @@ void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr, bo
|
||||
);
|
||||
}
|
||||
|
||||
if (Break)
|
||||
debug_interface->BreakNow();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ struct TMemCheck
|
||||
|
||||
u32 numHits;
|
||||
|
||||
void Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr,
|
||||
// returns whether to break
|
||||
bool Action(DebugInterface *dbg_interface, u32 _iValue, u32 addr,
|
||||
bool write, int size, u32 pc);
|
||||
};
|
||||
|
||||
@@ -105,6 +106,8 @@ public:
|
||||
void Remove(u32 _Address);
|
||||
|
||||
void Clear() { m_MemChecks.clear(); }
|
||||
|
||||
bool HasAny() const { return !m_MemChecks.empty(); }
|
||||
};
|
||||
|
||||
class Watches
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
virtual void SetPC(unsigned int /*address*/) {}
|
||||
virtual void Step() {}
|
||||
virtual void RunToBreakpoint() {}
|
||||
virtual void BreakNow() {}
|
||||
virtual void InsertBLR(unsigned int /*address*/, unsigned int /*value*/) {}
|
||||
virtual int GetColor(unsigned int /*address*/){return 0xFFFFFFFF;}
|
||||
virtual std::string GetDescription(unsigned int /*address*/) = 0;
|
||||
|
||||
@@ -169,11 +169,6 @@ void PPCDebugInterface::InsertBLR(unsigned int address, unsigned int value)
|
||||
PowerPC::HostWrite_U32(value, address);
|
||||
}
|
||||
|
||||
void PPCDebugInterface::BreakNow()
|
||||
{
|
||||
CCPU::Break();
|
||||
}
|
||||
|
||||
|
||||
// =======================================================
|
||||
// Separate the blocks with colors.
|
||||
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
virtual unsigned int GetPC() override;
|
||||
virtual void SetPC(unsigned int address) override;
|
||||
virtual void Step() override {}
|
||||
virtual void BreakNow() override;
|
||||
virtual void RunToBreakpoint() override;
|
||||
virtual void InsertBLR(unsigned int address, unsigned int value) override;
|
||||
virtual int GetColor(unsigned int address) override;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/HW/DSP.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
|
||||
@@ -117,7 +118,14 @@ void CCPU::EnableStepping(const bool _bStepping)
|
||||
{
|
||||
// SingleStep so that the "continue", "step over" and "step out" debugger functions
|
||||
// work when the PC is at a breakpoint at the beginning of the block
|
||||
if (PowerPC::breakpoints.IsAddressBreakPoint(PC) && PowerPC::GetMode() != PowerPC::MODE_INTERPRETER)
|
||||
// If watchpoints are enabled, any instruction could be a breakpoint.
|
||||
bool could_be_bp;
|
||||
#ifdef ENABLE_MEM_CHECK
|
||||
could_be_bp = true;
|
||||
#else
|
||||
could_be_bp = PowerPC::breakpoints.IsAddressBreakPoint(PC);
|
||||
#endif
|
||||
if (could_be_bp && PowerPC::GetMode() != PowerPC::MODE_INTERPRETER)
|
||||
{
|
||||
PowerPC::CoreMode oldMode = PowerPC::GetMode();
|
||||
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
||||
|
||||
@@ -235,10 +235,10 @@ void Clear()
|
||||
|
||||
bool AreMemoryBreakpointsActivated()
|
||||
{
|
||||
#ifndef ENABLE_MEM_CHECK
|
||||
return false;
|
||||
#else
|
||||
#ifdef ENABLE_MEM_CHECK
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -831,7 +831,9 @@ enum
|
||||
EXCEPTION_ALIGNMENT = 0x00000020,
|
||||
EXCEPTION_FPU_UNAVAILABLE = 0x00000040,
|
||||
EXCEPTION_PROGRAM = 0x00000080,
|
||||
EXCEPTION_PERFORMANCE_MONITOR = 0x00000100
|
||||
EXCEPTION_PERFORMANCE_MONITOR = 0x00000100,
|
||||
|
||||
EXCEPTION_FAKE_MEMCHECK_HIT = 0x00000200,
|
||||
};
|
||||
|
||||
inline s32 SignExt16(s16 x) {return (s32)(s16)x;}
|
||||
|
||||
@@ -178,14 +178,14 @@ void Jit64::Init()
|
||||
|
||||
jo.optimizeGatherPipe = true;
|
||||
jo.accurateSinglePrecision = true;
|
||||
js.memcheck = SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU;
|
||||
UpdateMemoryOptions();
|
||||
js.fastmemLoadStore = nullptr;
|
||||
js.compilerPC = 0;
|
||||
|
||||
gpr.SetEmitter(this);
|
||||
fpr.SetEmitter(this);
|
||||
|
||||
trampolines.Init(js.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE);
|
||||
trampolines.Init(jo.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE);
|
||||
AllocCodeSpace(CODE_SIZE);
|
||||
|
||||
// BLR optimization has the same consequences as block linking, as well as
|
||||
@@ -202,7 +202,7 @@ void Jit64::Init()
|
||||
|
||||
// important: do this *after* generating the global asm routines, because we can't use farcode in them.
|
||||
// it'll crash because the farcode functions get cleared on JIT clears.
|
||||
farcode.Init(js.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||
farcode.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||
|
||||
code_block.m_stats = &js.st;
|
||||
code_block.m_gpa = &js.gpa;
|
||||
@@ -216,6 +216,7 @@ void Jit64::ClearCache()
|
||||
trampolines.ClearCodeSpace();
|
||||
farcode.ClearCodeSpace();
|
||||
ClearCodeSpace();
|
||||
UpdateMemoryOptions();
|
||||
m_clear_cache_asap = false;
|
||||
}
|
||||
|
||||
@@ -788,7 +789,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
|
||||
Jit64Tables::CompileInstruction(ops[i]);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
if (jo.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
{
|
||||
// If we have a fastmem loadstore, we can omit the exception check and let fastmem handle it.
|
||||
FixupBranch memException;
|
||||
|
||||
@@ -182,14 +182,14 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((inst.OPCD != 31) && gpr.R(a).IsImm() && !js.memcheck)
|
||||
if ((inst.OPCD != 31) && gpr.R(a).IsImm() && !jo.memcheck)
|
||||
{
|
||||
u32 val = gpr.R(a).Imm32() + inst.SIMM_16;
|
||||
opAddress = Imm32(val);
|
||||
if (update)
|
||||
gpr.SetImmediate32(a, val);
|
||||
}
|
||||
else if ((inst.OPCD == 31) && gpr.R(a).IsImm() && gpr.R(b).IsImm() && !js.memcheck)
|
||||
else if ((inst.OPCD == 31) && gpr.R(a).IsImm() && gpr.R(b).IsImm() && !jo.memcheck)
|
||||
{
|
||||
u32 val = gpr.R(a).Imm32() + gpr.R(b).Imm32();
|
||||
opAddress = Imm32(val);
|
||||
@@ -206,7 +206,7 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
||||
offset = inst.OPCD == 31 ? gpr.R(b).SImm32() : (s32)inst.SIMM_16;
|
||||
// Depending on whether we have an immediate and/or update, find the optimum way to calculate
|
||||
// the load address.
|
||||
if ((update || use_constant_offset) && !js.memcheck)
|
||||
if ((update || use_constant_offset) && !jo.memcheck)
|
||||
{
|
||||
gpr.BindToRegister(a, true, update);
|
||||
opAddress = gpr.R(a);
|
||||
@@ -259,7 +259,7 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
||||
// clobber it, then restore the value in the exception path.
|
||||
// TODO: no other load has to do this at the moment, since no other loads go directly to the
|
||||
// target registers, but if that ever changes, we need to do it there too.
|
||||
if (js.memcheck)
|
||||
if (jo.memcheck)
|
||||
{
|
||||
gpr.StoreFromRegister(d);
|
||||
js.revertGprLoad = d;
|
||||
@@ -392,7 +392,7 @@ void Jit64::stX(UGeckoInstruction inst)
|
||||
bool exception = WriteToConstAddress(accessSize, gpr.R(s), addr, CallerSavedRegistersInUse());
|
||||
if (update)
|
||||
{
|
||||
if (!js.memcheck || !exception)
|
||||
if (!jo.memcheck || !exception)
|
||||
{
|
||||
gpr.SetImmediate32(a, addr);
|
||||
}
|
||||
@@ -445,7 +445,7 @@ void Jit64::stXx(UGeckoInstruction inst)
|
||||
int a = inst.RA, b = inst.RB, s = inst.RS;
|
||||
bool update = !!(inst.SUBOP10 & 32);
|
||||
bool byte_reverse = !!(inst.SUBOP10 & 512);
|
||||
FALLBACK_IF(!a || (update && a == s) || (update && js.memcheck && a == b));
|
||||
FALLBACK_IF(!a || (update && a == s) || (update && jo.memcheck && a == b));
|
||||
|
||||
gpr.Lock(a, b, s);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ void Jit64::lfXXX(UGeckoInstruction inst)
|
||||
|
||||
s32 offset = 0;
|
||||
OpArg addr = gpr.R(a);
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
{
|
||||
addr = R(RSCRATCH2);
|
||||
MOV(32, addr, gpr.R(a));
|
||||
@@ -66,14 +66,14 @@ void Jit64::lfXXX(UGeckoInstruction inst)
|
||||
}
|
||||
|
||||
fpr.Lock(d);
|
||||
if (js.memcheck && single)
|
||||
if (jo.memcheck && single)
|
||||
{
|
||||
fpr.StoreFromRegister(d);
|
||||
js.revertFprLoad = d;
|
||||
}
|
||||
fpr.BindToRegister(d, !single);
|
||||
BitSet32 registersInUse = CallerSavedRegistersInUse();
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
registersInUse[RSCRATCH2] = true;
|
||||
SafeLoadToReg(RSCRATCH, addr, single ? 32 : 64, offset, registersInUse, false);
|
||||
|
||||
@@ -87,7 +87,7 @@ void Jit64::lfXXX(UGeckoInstruction inst)
|
||||
MOVQ_xmm(XMM0, R(RSCRATCH));
|
||||
MOVSD(fpr.RX(d), R(XMM0));
|
||||
}
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
MOV(32, gpr.R(a), addr);
|
||||
fpr.UnlockAll();
|
||||
gpr.UnlockAll();
|
||||
@@ -108,7 +108,7 @@ void Jit64::stfXXX(UGeckoInstruction inst)
|
||||
s32 imm = (s16)inst.SIMM_16;
|
||||
int accessSize = single ? 32 : 64;
|
||||
|
||||
FALLBACK_IF(update && js.memcheck && a == b);
|
||||
FALLBACK_IF(update && jo.memcheck && a == b);
|
||||
|
||||
if (single)
|
||||
{
|
||||
@@ -138,7 +138,7 @@ void Jit64::stfXXX(UGeckoInstruction inst)
|
||||
|
||||
if (update)
|
||||
{
|
||||
if (!js.memcheck || !exception)
|
||||
if (!jo.memcheck || !exception)
|
||||
{
|
||||
gpr.SetImmediate32(a, addr);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
|
||||
X64Reg addr = gpr.RX(a);
|
||||
// TODO: this is kind of ugly :/ we should probably create a universal load/store address calculation
|
||||
// function that handles all these weird cases, e.g. how non-fastmem loadstores clobber addresses.
|
||||
bool storeAddress = (update && js.memcheck) || !SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem;
|
||||
bool storeAddress = (update && jo.memcheck) || !jo.fastmem;
|
||||
if (storeAddress)
|
||||
{
|
||||
addr = RSCRATCH2;
|
||||
@@ -118,7 +118,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
|
||||
ADD(32, R(RSCRATCH_EXTRA), Imm32((u32)offset));
|
||||
}
|
||||
// In memcheck mode, don't update the address until the exception check
|
||||
if (update && !js.memcheck)
|
||||
if (update && !jo.memcheck)
|
||||
MOV(32, gpr.R(a), R(RSCRATCH_EXTRA));
|
||||
// Some games (e.g. Dirt 2) incorrectly set the unused bits which breaks the lookup table code.
|
||||
// Hence, we need to mask out the unused bits. The layout of the GQR register is
|
||||
@@ -141,7 +141,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
|
||||
CALLptr(MScaled(RSCRATCH, SCALE_8, (u32)(u64)asm_routines.pairedStoreQuantized));
|
||||
}
|
||||
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
{
|
||||
MemoryExceptionCheck();
|
||||
if (indexed)
|
||||
@@ -174,7 +174,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||
s32 loadOffset = 0;
|
||||
gpr.BindToRegister(a, true, update);
|
||||
X64Reg addr = gpr.RX(a);
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
{
|
||||
addr = RSCRATCH2;
|
||||
MOV(32, R(addr), gpr.R(a));
|
||||
@@ -209,7 +209,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||
}
|
||||
|
||||
fpr.Lock(s);
|
||||
if (js.memcheck)
|
||||
if (jo.memcheck)
|
||||
{
|
||||
fpr.StoreFromRegister(s);
|
||||
js.revertFprLoad = s;
|
||||
@@ -217,7 +217,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||
fpr.BindToRegister(s, false);
|
||||
|
||||
// Let's mirror the JitAsmCommon code and assume all non-MMU loads go to RAM.
|
||||
if (!js.memcheck)
|
||||
if (!jo.memcheck)
|
||||
{
|
||||
if (w)
|
||||
{
|
||||
@@ -295,7 +295,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||
ADD(32, R(RSCRATCH_EXTRA), Imm32((u32)offset));
|
||||
}
|
||||
// In memcheck mode, don't update the address until the exception check
|
||||
if (update && !js.memcheck)
|
||||
if (update && !jo.memcheck)
|
||||
MOV(32, gpr.R(a), R(RSCRATCH_EXTRA));
|
||||
MOV(32, R(RSCRATCH2), Imm32(0x3F07));
|
||||
|
||||
@@ -310,7 +310,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
|
||||
|
||||
MemoryExceptionCheck();
|
||||
CVTPS2PD(fpr.RX(s), R(XMM0));
|
||||
if (update && js.memcheck)
|
||||
if (update && jo.memcheck)
|
||||
{
|
||||
if (indexed)
|
||||
ADD(32, gpr.R(a), gpr.R(b));
|
||||
|
||||
@@ -420,7 +420,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
// If we find something that actually does do this, maybe this should be changed. How
|
||||
// much of a performance hit would it be?
|
||||
const u8* loadPairedFloatTwo = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
{
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 64, 0, QUANTIZED_REGS_TO_SAVE, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
ROL(64, R(RSCRATCH_EXTRA), Imm8(32));
|
||||
@@ -440,7 +440,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedFloatOne = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
{
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 32, 0, QUANTIZED_REGS_TO_SAVE, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
MOVD_xmm(XMM0, R(RSCRATCH_EXTRA));
|
||||
@@ -461,7 +461,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedU8Two = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
{
|
||||
// TODO: Support not swapping in safeLoadToReg to avoid bswapping twice
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 16, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
@@ -489,7 +489,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedU8One = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 8, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToRegNoSwap(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 8, 0); // RSCRATCH_EXTRA = 0x000000xx
|
||||
@@ -500,7 +500,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedS8Two = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
{
|
||||
// TODO: Support not swapping in safeLoadToReg to avoid bswapping twice
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 16, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
@@ -528,7 +528,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedS8One = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 8, 0, QUANTIZED_REGS_TO_SAVE_LOAD, true, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToRegNoSwap(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 8, 0, true);
|
||||
@@ -540,7 +540,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
|
||||
const u8* loadPairedU16Two = AlignCode4();
|
||||
// TODO: Support not swapping in (un)safeLoadToReg to avoid bswapping twice
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 32, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToReg(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 32, 0, false);
|
||||
@@ -562,7 +562,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedU16One = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 16, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToReg(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 16, 0, false);
|
||||
@@ -573,7 +573,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedS16Two = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 32, 0, QUANTIZED_REGS_TO_SAVE_LOAD, false, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToReg(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 32, 0, false);
|
||||
@@ -595,7 +595,7 @@ void CommonAsmRoutines::GenQuantizedLoads()
|
||||
RET();
|
||||
|
||||
const u8* loadPairedS16One = AlignCode4();
|
||||
if (jit->js.memcheck)
|
||||
if (jit->jo.memcheck)
|
||||
SafeLoadToReg(RSCRATCH_EXTRA, R(RSCRATCH_EXTRA), 16, 0, QUANTIZED_REGS_TO_SAVE_LOAD, true, SAFE_LOADSTORE_NO_FASTMEM | SAFE_LOADSTORE_NO_PROLOG);
|
||||
else
|
||||
UnsafeLoadRegToReg(RSCRATCH_EXTRA, RSCRATCH_EXTRA, 16, 0, true);
|
||||
|
||||
@@ -246,14 +246,14 @@ void JitIL::Init()
|
||||
|
||||
jo.optimizeGatherPipe = true;
|
||||
jo.accurateSinglePrecision = false;
|
||||
js.memcheck = SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU;
|
||||
UpdateMemoryOptions();
|
||||
|
||||
trampolines.Init(js.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE);
|
||||
trampolines.Init(jo.memcheck ? TRAMPOLINE_CODE_SIZE_MMU : TRAMPOLINE_CODE_SIZE);
|
||||
AllocCodeSpace(CODE_SIZE);
|
||||
blocks.Init();
|
||||
asm_routines.Init(nullptr);
|
||||
|
||||
farcode.Init(js.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||
farcode.Init(jo.memcheck ? FARCODE_SIZE_MMU : FARCODE_SIZE);
|
||||
|
||||
code_block.m_stats = &js.st;
|
||||
code_block.m_gpa = &js.gpa;
|
||||
@@ -624,7 +624,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
|
||||
if (!ops[i].skip)
|
||||
{
|
||||
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
if (jo.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
{
|
||||
ibuild.EmitFPExceptionCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
@@ -644,7 +644,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
|
||||
JitILTables::CompileInstruction(ops[i]);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
if (jo.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
{
|
||||
ibuild.EmitDSIExceptionCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ void JitArm::Init()
|
||||
fpr.Init(this);
|
||||
jo.enableBlocklink = true;
|
||||
jo.optimizeGatherPipe = true;
|
||||
UpdateMemoryOptions();
|
||||
|
||||
code_block.m_stats = &js.st;
|
||||
code_block.m_gpa = &js.gpa;
|
||||
@@ -45,6 +46,7 @@ void JitArm::ClearCache()
|
||||
{
|
||||
ClearCodeSpace();
|
||||
blocks.Clear();
|
||||
UpdateMemoryOptions();
|
||||
}
|
||||
|
||||
void JitArm::Shutdown()
|
||||
@@ -467,7 +469,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
|
||||
|
||||
if (!ops[i].skip)
|
||||
{
|
||||
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
if (jo.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
{
|
||||
// Don't do this yet
|
||||
BKPT(0x7777);
|
||||
@@ -480,7 +482,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo
|
||||
for (int j : ~ops[i].fprInUse)
|
||||
fpr.StoreFromRegister(j);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
if (jo.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
{
|
||||
// Don't do this yet
|
||||
BKPT(0x666);
|
||||
|
||||
@@ -148,7 +148,7 @@ void JitArm::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, int accessSize
|
||||
else if (PowerPC::IsOptimizableRAMAddress(imm_addr))
|
||||
{
|
||||
MOVI2R(rA, imm_addr);
|
||||
EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, true, RS);
|
||||
EmitBackpatchRoutine(this, flags, jo.fastmem, true, RS);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -158,7 +158,7 @@ void JitArm::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, int accessSize
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, true, RS);
|
||||
EmitBackpatchRoutine(this, flags, jo.fastmem, true, RS);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -351,7 +351,7 @@ void JitArm::SafeLoadToReg(ARMReg dest, s32 addr, s32 offsetReg, int accessSize,
|
||||
flags |= BackPatchInfo::FLAG_EXTEND;
|
||||
|
||||
EmitBackpatchRoutine(this, flags,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
jo.fastmem,
|
||||
true, dest);
|
||||
|
||||
if (update)
|
||||
@@ -482,7 +482,7 @@ void JitArm::lmw(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITLoadStoreOff);
|
||||
FALLBACK_IF(!SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(!jo.fastmem);
|
||||
|
||||
u32 a = inst.RA;
|
||||
ARMReg rA = gpr.GetReg();
|
||||
@@ -506,7 +506,7 @@ void JitArm::stmw(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITLoadStoreOff);
|
||||
FALLBACK_IF(!SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(!jo.fastmem);
|
||||
|
||||
u32 a = inst.RA;
|
||||
ARMReg rA = gpr.GetReg();
|
||||
|
||||
@@ -182,7 +182,7 @@ void JitArm::lfXX(UGeckoInstruction inst)
|
||||
MOV(RA, addr);
|
||||
|
||||
EmitBackpatchRoutine(this, flags,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
jo.fastmem,
|
||||
!(is_immediate && PowerPC::IsOptimizableRAMAddress(imm_addr)), v0, v1);
|
||||
|
||||
SetJumpTarget(DoNotLoad);
|
||||
@@ -387,7 +387,7 @@ void JitArm::stfXX(UGeckoInstruction inst)
|
||||
else if (PowerPC::IsOptimizableRAMAddress(imm_addr))
|
||||
{
|
||||
MOVI2R(addr, imm_addr);
|
||||
EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, false, v0);
|
||||
EmitBackpatchRoutine(this, flags, jo.fastmem, false, v0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -397,7 +397,7 @@ void JitArm::stfXX(UGeckoInstruction inst)
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitBackpatchRoutine(this, flags, SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem, true, v0);
|
||||
EmitBackpatchRoutine(this, flags, jo.fastmem, true, v0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ void JitArm::psq_l(UGeckoInstruction inst)
|
||||
// R12 contains scale
|
||||
// R11 contains type
|
||||
// R10 is the ADDR
|
||||
FALLBACK_IF(js.memcheck || !SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(jo.memcheck || !jo.fastmem);
|
||||
|
||||
bool update = inst.OPCD == 57;
|
||||
s32 offset = inst.SIMM_12;
|
||||
@@ -76,7 +76,7 @@ void JitArm::psq_lx(UGeckoInstruction inst)
|
||||
// R12 contains scale
|
||||
// R11 contains type
|
||||
// R10 is the ADDR
|
||||
FALLBACK_IF(js.memcheck || !SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(jo.memcheck || !jo.fastmem);
|
||||
|
||||
bool update = inst.SUBOP10 == 38;
|
||||
|
||||
@@ -127,7 +127,7 @@ void JitArm::psq_st(UGeckoInstruction inst)
|
||||
// R12 contains scale
|
||||
// R11 contains type
|
||||
// R10 is the ADDR
|
||||
FALLBACK_IF(js.memcheck || !SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(jo.memcheck || !jo.fastmem);
|
||||
|
||||
bool update = inst.OPCD == 61;
|
||||
s32 offset = inst.SIMM_12;
|
||||
@@ -179,7 +179,7 @@ void JitArm::psq_stx(UGeckoInstruction inst)
|
||||
// R12 contains scale
|
||||
// R11 contains type
|
||||
// R10 is the ADDR
|
||||
FALLBACK_IF(js.memcheck || !SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem);
|
||||
FALLBACK_IF(jo.memcheck || !jo.fastmem);
|
||||
|
||||
bool update = inst.SUBOP10 == 39;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ void JitArm64::Init()
|
||||
AllocCodeSpace(CODE_SIZE);
|
||||
jo.enableBlocklink = true;
|
||||
jo.optimizeGatherPipe = true;
|
||||
UpdateMemoryOptions();
|
||||
gpr.Init(this);
|
||||
fpr.Init(this);
|
||||
|
||||
@@ -34,6 +35,7 @@ void JitArm64::ClearCache()
|
||||
{
|
||||
ClearCodeSpace();
|
||||
blocks.Clear();
|
||||
UpdateMemoryOptions();
|
||||
}
|
||||
|
||||
void JitArm64::Shutdown()
|
||||
@@ -295,7 +297,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
||||
|
||||
if (!ops[i].skip)
|
||||
{
|
||||
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
if (jo.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
{
|
||||
// Don't do this yet
|
||||
BRK(0x7777);
|
||||
@@ -309,7 +311,7 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
|
||||
for (int j : ~ops[i].fprInUse)
|
||||
fpr.StoreRegister(j);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
if (jo.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
{
|
||||
// Don't do this yet
|
||||
BRK(0x666);
|
||||
|
||||
@@ -172,8 +172,8 @@ void JitArm64::SafeLoadToReg(u32 dest, s32 addr, s32 offsetReg, u32 flags, s32 o
|
||||
ABI_PushRegisters(regs_in_use);
|
||||
m_float_emit.ABI_PushRegisters(fprs_in_use, X30);
|
||||
EmitBackpatchRoutine(this, flags,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
jo.fastmem,
|
||||
jo.fastmem,
|
||||
dest_reg, XA);
|
||||
m_float_emit.ABI_PopRegisters(fprs_in_use, X30);
|
||||
ABI_PopRegisters(regs_in_use);
|
||||
@@ -323,8 +323,8 @@ void JitArm64::SafeStoreFromReg(s32 dest, u32 value, s32 regOffset, u32 flags, s
|
||||
ABI_PushRegisters(regs_in_use);
|
||||
m_float_emit.ABI_PushRegisters(fprs_in_use, X30);
|
||||
EmitBackpatchRoutine(this, flags,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bFastmem,
|
||||
jo.fastmem,
|
||||
jo.fastmem,
|
||||
RS, XA);
|
||||
m_float_emit.ABI_PopRegisters(fprs_in_use, X30);
|
||||
ABI_PopRegisters(regs_in_use);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user