mirror of https://github.com/PCSX2/pcsx2.git
EERec: Add block dumping
This commit is contained in:
parent
741ddaf384
commit
d17ceec14b
|
@ -125,6 +125,9 @@
|
||||||
<ProjectReference Include="..\3rdparty\lzma\lzma.vcxproj">
|
<ProjectReference Include="..\3rdparty\lzma\lzma.vcxproj">
|
||||||
<Project>{a4323327-3f2b-4271-83d9-7f9a3c66b6b2}</Project>
|
<Project>{a4323327-3f2b-4271-83d9-7f9a3c66b6b2}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\3rdparty\zydis\zydis.vcxproj">
|
||||||
|
<Project>{67d0160c-0fe4-44b9-ac2e-82bbcf4104df}</Project>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest" />
|
<Manifest Include="..\pcsx2\windows\PCSX2.manifest" />
|
||||||
|
|
|
@ -1659,6 +1659,7 @@ target_link_libraries(PCSX2_FLAGS INTERFACE
|
||||||
chdr-static
|
chdr-static
|
||||||
libzip::zip
|
libzip::zip
|
||||||
cpuinfo
|
cpuinfo
|
||||||
|
zydis
|
||||||
ZLIB::ZLIB
|
ZLIB::ZLIB
|
||||||
PkgConfig::SOUNDTOUCH
|
PkgConfig::SOUNDTOUCH
|
||||||
PNG::PNG
|
PNG::PNG
|
||||||
|
|
|
@ -380,10 +380,6 @@ struct Pcsx2Config
|
||||||
fpuExtraOverflow : 1,
|
fpuExtraOverflow : 1,
|
||||||
fpuFullMode : 1;
|
fpuFullMode : 1;
|
||||||
|
|
||||||
bool
|
|
||||||
StackFrameChecks : 1,
|
|
||||||
PreBlockCheckEE : 1,
|
|
||||||
PreBlockCheckIOP : 1;
|
|
||||||
bool
|
bool
|
||||||
EnableEECache : 1;
|
EnableEECache : 1;
|
||||||
BITFIELD_END
|
BITFIELD_END
|
||||||
|
|
|
@ -220,10 +220,6 @@ void Pcsx2Config::RecompilerOptions::LoadSave(SettingsWrapper& wrap)
|
||||||
SettingsWrapBitBool(fpuOverflow);
|
SettingsWrapBitBool(fpuOverflow);
|
||||||
SettingsWrapBitBool(fpuExtraOverflow);
|
SettingsWrapBitBool(fpuExtraOverflow);
|
||||||
SettingsWrapBitBool(fpuFullMode);
|
SettingsWrapBitBool(fpuFullMode);
|
||||||
|
|
||||||
SettingsWrapBitBool(StackFrameChecks);
|
|
||||||
SettingsWrapBitBool(PreBlockCheckEE);
|
|
||||||
SettingsWrapBitBool(PreBlockCheckIOP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pcsx2Config::CpuOptions::CpusChanged(const CpuOptions& right) const
|
bool Pcsx2Config::CpuOptions::CpusChanged(const CpuOptions& right) const
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rapidyaml\rapidyaml\ext\c4core\src\c4\ext\fast_float\include</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rcheevos\rcheevos\include;$(SolutionDir)3rdparty\rainterface</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\rcheevos\rcheevos\include;$(SolutionDir)3rdparty\rainterface</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\discord-rpc\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\discord-rpc\include</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(SolutionDir)3rdparty\zydis\include;$(SolutionDir)3rdparty\zydis\dependencies\zycore\include</AdditionalIncludeDirectories>
|
||||||
<ExceptionHandling>Async</ExceptionHandling>
|
<ExceptionHandling>Async</ExceptionHandling>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
|
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
|
||||||
|
@ -65,6 +66,7 @@
|
||||||
<PreprocessorDefinitions Condition="'$(CI)'=='true'">PCSX2_CI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(CI)'=='true'">PCSX2_CI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">ZYCORE_STATIC_DEFINE;ZYDIS_STATIC_DEFINE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2))">NotSet</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet Condition="!$(Configuration.Contains(AVX2))">NotSet</EnableEnhancedInstructionSet>
|
||||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
@ -835,4 +837,4 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets" />
|
<ImportGroup Label="ExtensionTargets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -51,6 +51,19 @@
|
||||||
|
|
||||||
#include "fmt/core.h"
|
#include "fmt/core.h"
|
||||||
|
|
||||||
|
// #define DUMP_BLOCKS 1
|
||||||
|
// #define TRACE_BLOCKS 1
|
||||||
|
|
||||||
|
#ifdef DUMP_BLOCKS
|
||||||
|
#include "Zydis/Zydis.h"
|
||||||
|
#include "Zycore/Format.h"
|
||||||
|
#include "Zycore/Status.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACE_BLOCKS
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
extern void psxBREAK();
|
extern void psxBREAK();
|
||||||
|
@ -1266,7 +1279,7 @@ void psxRecompileNextInstruction(int delayslot)
|
||||||
|
|
||||||
static void PreBlockCheck(u32 blockpc)
|
static void PreBlockCheck(u32 blockpc)
|
||||||
{
|
{
|
||||||
#ifdef PCSX2_DEBUG
|
#if 0
|
||||||
extern void iDumpPsxRegisters(u32 startpc, u32 temp);
|
extern void iDumpPsxRegisters(u32 startpc, u32 temp);
|
||||||
|
|
||||||
static u32 lastrec = 0;
|
static u32 lastrec = 0;
|
||||||
|
@ -1289,6 +1302,37 @@ static void PreBlockCheck(u32 blockpc)
|
||||||
lastrec = blockpc;
|
lastrec = blockpc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TRACE_BLOCKS
|
||||||
|
#if 1
|
||||||
|
static FILE* fp = nullptr;
|
||||||
|
static bool fp_opened = false;
|
||||||
|
if (!fp_opened && psxRegs.cycle >= 0)
|
||||||
|
{
|
||||||
|
fp = std::fopen("C:\\Dumps\\comp\\ioplog.txt", "wb");
|
||||||
|
fp_opened = true;
|
||||||
|
}
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
u32 hash = crc32(0, (Bytef*)&psxRegs, offsetof(psxRegisters, pc));
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
std::fprintf(fp, "%08X (%u; %08X):", psxRegs.pc, psxRegs.cycle, hash);
|
||||||
|
for (int i = 0; i < 34; i++)
|
||||||
|
{
|
||||||
|
std::fprintf(fp, " %s: %08X", R3000A::disRNameGPR[i], psxRegs.GPR.r[i]);
|
||||||
|
}
|
||||||
|
std::fprintf(fp, "\n");
|
||||||
|
#else
|
||||||
|
std::fprintf(fp, "%08X (%u): %08X\n", psxRegs.pc, psxRegs.cycle, hash);
|
||||||
|
#endif
|
||||||
|
// std::fflush(fp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
if (psxRegs.cycle == 0)
|
||||||
|
__debugbreak();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iopRecRecompile(const u32 startpc)
|
static void iopRecRecompile(const u32 startpc)
|
||||||
|
@ -1352,10 +1396,9 @@ static void iopRecRecompile(const u32 startpc)
|
||||||
xJNZ(iopDispatcherReg);
|
xJNZ(iopDispatcherReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDebugBuild)
|
#ifdef TRACE_BLOCKS
|
||||||
{
|
xFastCall((void*)PreBlockCheck, psxpc);
|
||||||
xFastCall((void*)PreBlockCheck, psxpc);
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// go until the next branch
|
// go until the next branch
|
||||||
i = startpc;
|
i = startpc;
|
||||||
|
|
|
@ -50,6 +50,19 @@
|
||||||
// Only for MOVQ workaround.
|
// Only for MOVQ workaround.
|
||||||
#include "common/emitter/internal.h"
|
#include "common/emitter/internal.h"
|
||||||
|
|
||||||
|
//#define DUMP_BLOCKS 1
|
||||||
|
//#define TRACE_BLOCKS 1
|
||||||
|
|
||||||
|
#ifdef DUMP_BLOCKS
|
||||||
|
#include "Zydis/Zydis.h"
|
||||||
|
#include "Zycore/Format.h"
|
||||||
|
#include "Zycore/Status.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TRACE_BLOCKS
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
|
@ -128,6 +141,124 @@ static void ClearRecLUT(BASEBLOCK* base, int count);
|
||||||
static u32 scaleblockcycles();
|
static u32 scaleblockcycles();
|
||||||
static void recExitExecution();
|
static void recExitExecution();
|
||||||
|
|
||||||
|
#ifdef TRACE_BLOCKS
|
||||||
|
static void pauseAAA()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "\nPaused\n");
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__debugbreak();
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DUMP_BLOCKS
|
||||||
|
static ZydisFormatterFunc s_old_print_address;
|
||||||
|
|
||||||
|
static ZyanStatus ZydisFormatterPrintAddressAbsolute(const ZydisFormatter* formatter,
|
||||||
|
ZydisFormatterBuffer* buffer, ZydisFormatterContext* context)
|
||||||
|
{
|
||||||
|
ZyanU64 address;
|
||||||
|
ZYAN_CHECK(ZydisCalcAbsoluteAddress(context->instruction, context->operand,
|
||||||
|
context->runtime_address, &address));
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
u32 len = 0;
|
||||||
|
|
||||||
|
#define A(x) ((u64)(x))
|
||||||
|
|
||||||
|
if (address >= A(eeMem->Main) && address < A(eeMem->Scratch))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "eeMem+0x%08X", static_cast<u32>(address - A(eeMem->Main)));
|
||||||
|
}
|
||||||
|
else if (address >= A(eeMem->Scratch) && address < A(eeMem->ROM))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "eeScratchpad+0x%08X", static_cast<u32>(address - A(eeMem->Scratch)));
|
||||||
|
}
|
||||||
|
else if (address >= A(&cpuRegs.GPR) && address < A(&cpuRegs.HI))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&cpuRegs)) % 16u;
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.GPR.%s+%u", GPR_REG[static_cast<u32>(address - A(&cpuRegs)) / 16u], offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.GPR.%s", GPR_REG[static_cast<u32>(address - A(&cpuRegs)) / 16u]);
|
||||||
|
}
|
||||||
|
else if (address >= A(&cpuRegs.HI) && address < A(&cpuRegs.CP0))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&cpuRegs.HI)) % 16u;
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.%s+%u", (address >= A(&cpuRegs.LO) ? "LO" : "HI"), offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.%s", (address >= A(&cpuRegs.LO) ? "LO" : "HI"));
|
||||||
|
}
|
||||||
|
else if (address == A(&cpuRegs.pc))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.pc");
|
||||||
|
}
|
||||||
|
else if (address == A(&cpuRegs.cycle))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "cpuRegs.cycle");
|
||||||
|
}
|
||||||
|
else if (address == A(&g_nextEventCycle))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "g_nextEventCycle");
|
||||||
|
}
|
||||||
|
else if (address >= A(fpuRegs.fpr) && address < A(fpuRegs.fprc))
|
||||||
|
{
|
||||||
|
len = snprintf(buf, sizeof(buf), "fpuRegs.f%02u", static_cast<u32>(address - A(fpuRegs.fpr)) / 4u);
|
||||||
|
}
|
||||||
|
else if (address >= A(&VU0.VF[0]) && address < A(&VU0.VI[0]))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&VU0.VF[0])) % 16u;
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.VF[%02u]+%u", static_cast<u32>(address - A(&VU0.VF[0])) / 16u, offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.VF[%02u]", static_cast<u32>(address - A(&VU0.VF[0])) / 16u);
|
||||||
|
}
|
||||||
|
else if (address >= A(&VU0.VI[0]) && address < A(&VU0.ACC))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&VU0.VI[0])) % 16u;
|
||||||
|
const u32 vi = static_cast<u32>(address - A(&VU0.VI[0])) / 16u;
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.%s+%u", COP2_REG_CTL[vi], offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.%s", COP2_REG_CTL[vi]);
|
||||||
|
}
|
||||||
|
else if (address >= A(&VU0.ACC) && address < A(&VU0.q))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&VU0.ACC));
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.ACC+%u", offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.ACC");
|
||||||
|
}
|
||||||
|
else if (address >= A(&VU0.q) && address < A(&VU0.idx))
|
||||||
|
{
|
||||||
|
const u32 offset = static_cast<u32>(address - A(&VU0.q)) % 16u;
|
||||||
|
const char* reg = (address >= A(&VU0.p)) ? "p" : "q";
|
||||||
|
if (offset != 0)
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.%s+%u", reg, offset);
|
||||||
|
else
|
||||||
|
len = snprintf(buf, sizeof(buf), "VU0.%s", reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef A
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
ZYAN_CHECK(ZydisFormatterBufferAppend(buffer, ZYDIS_TOKEN_SYMBOL));
|
||||||
|
ZyanString* string;
|
||||||
|
ZYAN_CHECK(ZydisFormatterBufferGetString(buffer, &string));
|
||||||
|
return ZyanStringAppendFormat(string, "<%s>", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_old_print_address(formatter, buffer, context);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void _eeFlushAllUnused()
|
void _eeFlushAllUnused()
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
|
@ -1653,6 +1784,57 @@ static void PreBlockCheck(u32 blockpc)
|
||||||
|
|
||||||
lastrec = blockpc;
|
lastrec = blockpc;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
#ifdef TRACE_BLOCKS
|
||||||
|
#if 0
|
||||||
|
static FILE* fp = nullptr;
|
||||||
|
static bool fp_opened = false;
|
||||||
|
if (!fp_opened && cpuRegs.cycle >= 0)
|
||||||
|
{
|
||||||
|
fp = std::fopen("C:\\Dumps\\comp\\reglog.txt", "wb");
|
||||||
|
fp_opened = true;
|
||||||
|
}
|
||||||
|
if (fp)
|
||||||
|
{
|
||||||
|
u32 hash = crc32(0, (Bytef*)&cpuRegs, offsetof(cpuRegisters, pc));
|
||||||
|
u32 hashf = crc32(0, (Bytef*)&fpuRegs, sizeof(fpuRegisters));
|
||||||
|
u32 hashi = crc32(0, (Bytef*)&VU0, offsetof(VURegs, idx));
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
std::fprintf(fp, "%08X (%u; %08X; %08X; %08X):", cpuRegs.pc, cpuRegs.cycle, hash, hashf, hashi);
|
||||||
|
for (int i = 0; i < 34; i++)
|
||||||
|
{
|
||||||
|
std::fprintf(fp, " %s: %08X%08X%08X%08X", R3000A::disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]);
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
std::fprintf(fp, "\nFPR: CR: %08X ACC: %08X", fpuRegs.fprc[31], fpuRegs.ACC.UL);
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
std::fprintf(fp, " %08X", fpuRegs.fpr[i].UL);
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
std::fprintf(fp, "\nVF: ");
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
std::fprintf(fp, " %u: %08X %08X %08X %08X", i, VU0.VF[i].UL[0], VU0.VF[i].UL[1], VU0.VF[i].UL[2], VU0.VF[i].UL[3]);
|
||||||
|
std::fprintf(fp, "\nVI: ");
|
||||||
|
for (int i = 0; i < 32; i++)
|
||||||
|
std::fprintf(fp, " %u: %08X", i, VU0.VI[i].UL);
|
||||||
|
std::fprintf(fp, "\nACC: %08X %08X %08X %08X Q: %08X P: %08X", VU0.ACC.UL[0], VU0.ACC.UL[1], VU0.ACC.UL[2], VU0.ACC.UL[3], VU0.q.UL, VU0.p.UL);
|
||||||
|
std::fprintf(fp, " MAC %08X %08X %08X %08X", VU0.micro_macflags[3], VU0.micro_macflags[2], VU0.micro_macflags[1], VU0.micro_macflags[0]);
|
||||||
|
std::fprintf(fp, " CLIP %08X %08X %08X %08X", VU0.micro_clipflags[3], VU0.micro_clipflags[2], VU0.micro_clipflags[1], VU0.micro_clipflags[0]);
|
||||||
|
std::fprintf(fp, " STATUS %08X %08X %08X %08X", VU0.micro_statusflags[3], VU0.micro_statusflags[2], VU0.micro_statusflags[1], VU0.micro_statusflags[0]);
|
||||||
|
#endif
|
||||||
|
std::fprintf(fp, "\n");
|
||||||
|
#else
|
||||||
|
std::fprintf(fp, "%08X (%u): %08X %08X %08X\n", cpuRegs.pc, cpuRegs.cycle, hash, hashf, hashi);
|
||||||
|
#endif
|
||||||
|
// std::fflush(fp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
if (cpuRegs.cycle == 0)
|
||||||
|
pauseAAA();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PCSX2_DEBUG
|
#ifdef PCSX2_DEBUG
|
||||||
|
@ -1917,14 +2099,9 @@ static void recRecompile(const u32 startpc)
|
||||||
_initX86regs();
|
_initX86regs();
|
||||||
_initXMMregs();
|
_initXMMregs();
|
||||||
|
|
||||||
if (EmuConfig.Cpu.Recompiler.PreBlockCheckEE)
|
#ifdef TRACE_BLOCKS
|
||||||
{
|
xFastCall((void*)PreBlockCheck, pc);
|
||||||
// per-block dump checks, for debugging purposes.
|
#endif
|
||||||
// [TODO] : These must be enabled from the GUI or INI to be used, otherwise the
|
|
||||||
// code that calls PreBlockCheck will not be generated.
|
|
||||||
|
|
||||||
xFastCall((void*)PreBlockCheck, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EmuConfig.Gamefixes.GoemonTlbHack)
|
if (EmuConfig.Gamefixes.GoemonTlbHack)
|
||||||
{
|
{
|
||||||
|
@ -2247,6 +2424,26 @@ StartRecomp:
|
||||||
iDumpBlock(startpc, recPtr);
|
iDumpBlock(startpc, recPtr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DUMP_BLOCKS
|
||||||
|
ZydisDecoder disas_decoder;
|
||||||
|
ZydisDecoderInit(&disas_decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
|
||||||
|
|
||||||
|
ZydisFormatter disas_formatter;
|
||||||
|
ZydisFormatterInit(&disas_formatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||||
|
|
||||||
|
s_old_print_address = (ZydisFormatterFunc)&ZydisFormatterPrintAddressAbsolute;
|
||||||
|
ZydisFormatterSetHook(&disas_formatter, ZYDIS_FORMATTER_FUNC_PRINT_ADDRESS_ABS, (const void**)&s_old_print_address);
|
||||||
|
|
||||||
|
ZydisDecodedInstruction disas_instruction;
|
||||||
|
#if 0
|
||||||
|
const bool dump_block = (startpc == 0x00000000);
|
||||||
|
#elif 1
|
||||||
|
const bool dump_block = true;
|
||||||
|
#else
|
||||||
|
const bool dump_block = false;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Detect and handle self-modified code
|
// Detect and handle self-modified code
|
||||||
memory_protect_recompiled_code(startpc, (s_nEndBlock - startpc) >> 2);
|
memory_protect_recompiled_code(startpc, (s_nEndBlock - startpc) >> 2);
|
||||||
|
|
||||||
|
@ -2259,7 +2456,35 @@ StartRecomp:
|
||||||
g_pCurInstInfo = s_pInstCache;
|
g_pCurInstInfo = s_pInstCache;
|
||||||
while (!g_branch && pc < s_nEndBlock)
|
while (!g_branch && pc < s_nEndBlock)
|
||||||
{
|
{
|
||||||
|
#ifdef DUMP_BLOCKS
|
||||||
|
if (dump_block)
|
||||||
|
{
|
||||||
|
std::string disasm;
|
||||||
|
disR5900Fasm(disasm, *(u32*)PSM(pc), pc, false);
|
||||||
|
fprintf(stderr, "Compiling %08X %s\n", pc, disasm.c_str());
|
||||||
|
|
||||||
|
const u8* instStart = x86Ptr;
|
||||||
|
recompileNextInstruction(0);
|
||||||
|
|
||||||
|
const u8* instPtr = instStart;
|
||||||
|
ZyanUSize instLength = static_cast<ZyanUSize>(x86Ptr - instStart);
|
||||||
|
while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&disas_decoder, instPtr, instLength, &disas_instruction)))
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
if (ZYAN_SUCCESS(ZydisFormatterFormatInstruction(&disas_formatter, &disas_instruction, buffer, sizeof(buffer), (ZyanU64)instPtr)))
|
||||||
|
std::fprintf(stderr, " %016" PRIX64 " %s\n", (u64)instPtr, buffer);
|
||||||
|
|
||||||
|
instPtr += disas_instruction.length;
|
||||||
|
instLength -= disas_instruction.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recompileNextInstruction(0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
recompileNextInstruction(0); // For the love of recursion, batman!
|
recompileNextInstruction(0); // For the love of recursion, batman!
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "iR5900.h"
|
#include "iR5900.h"
|
||||||
#include "common/Perf.h"
|
#include "common/Perf.h"
|
||||||
|
|
||||||
|
//#define LOG_STORES
|
||||||
|
|
||||||
using namespace vtlb_private;
|
using namespace vtlb_private;
|
||||||
using namespace x86Emitter;
|
using namespace x86Emitter;
|
||||||
|
|
||||||
|
@ -76,6 +78,34 @@ using namespace x86Emitter;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef LOG_STORES
|
||||||
|
static std::FILE* logfile;
|
||||||
|
static bool CheckLogFile()
|
||||||
|
{
|
||||||
|
if (!logfile)
|
||||||
|
logfile = std::fopen("C:\\Dumps\\comp\\memlog.bad.txt", "wb");
|
||||||
|
return (logfile != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LogWrite(u32 addr, u64 val)
|
||||||
|
{
|
||||||
|
if (!CheckLogFile())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::fprintf(logfile, "%08X @ %u: %llx\n", addr, cpuRegs.cycle, val);
|
||||||
|
std::fflush(logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __vectorcall LogWriteQuad(u32 addr, __m128i val)
|
||||||
|
{
|
||||||
|
if (!CheckLogFile())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::fprintf(logfile, "%08X @ %u: %llx %llx\n", addr, cpuRegs.cycle, val.m128i_u64[0], val.m128i_u64[1]);
|
||||||
|
std::fflush(logfile);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace vtlb_private
|
namespace vtlb_private
|
||||||
{
|
{
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -471,6 +501,38 @@ void vtlb_DynGenReadNonQuad_Const(u32 bits, bool sign, u32 addr_const)
|
||||||
|
|
||||||
void vtlb_DynGenWrite(u32 sz)
|
void vtlb_DynGenWrite(u32 sz)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG_STORES
|
||||||
|
//if (sz != 128)
|
||||||
|
{
|
||||||
|
iFlushCall(FLUSH_FULLVTLB);
|
||||||
|
|
||||||
|
xPUSH(arg1reg);
|
||||||
|
xPUSH(arg2reg);
|
||||||
|
if (sz == 128)
|
||||||
|
{
|
||||||
|
xSUB(rsp, 32 + 32);
|
||||||
|
xMOVAPS(ptr[rsp + 32], xRegisterSSE::GetArgRegister(1, 0));
|
||||||
|
xFastCall((void*)LogWriteQuad);
|
||||||
|
xMOVAPS(xRegisterSSE::GetArgRegister(1, 0), ptr[rsp + 32]);
|
||||||
|
xADD(rsp, 32 + 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sz == 8)
|
||||||
|
xAND(arg2regd, 0xFF);
|
||||||
|
else if (sz == 16)
|
||||||
|
xAND(arg2regd, 0xFFFF);
|
||||||
|
else if (sz == 32)
|
||||||
|
xAND(arg2regd, -1);
|
||||||
|
xSUB(rsp, 32);
|
||||||
|
xFastCall((void*)LogWrite);
|
||||||
|
xADD(rsp, 32);
|
||||||
|
}
|
||||||
|
xPOP(arg2reg);
|
||||||
|
xPOP(arg1reg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
u32* writeback = DynGen_PrepRegs();
|
u32* writeback = DynGen_PrepRegs();
|
||||||
|
|
||||||
DynGen_IndirectDispatch(1, sz);
|
DynGen_IndirectDispatch(1, sz);
|
||||||
|
@ -488,6 +550,39 @@ void vtlb_DynGenWrite_Const(u32 bits, u32 addr_const)
|
||||||
{
|
{
|
||||||
EE::Profiler.EmitConstMem(addr_const);
|
EE::Profiler.EmitConstMem(addr_const);
|
||||||
|
|
||||||
|
#ifdef LOG_STORES
|
||||||
|
iFlushCall(FLUSH_FULLVTLB);
|
||||||
|
|
||||||
|
//if (bits != 128)
|
||||||
|
{
|
||||||
|
xPUSH(arg1reg);
|
||||||
|
xPUSH(arg2reg);
|
||||||
|
xMOV(arg1reg, addr_const);
|
||||||
|
if (bits == 128)
|
||||||
|
{
|
||||||
|
xSUB(rsp, 32 + 32);
|
||||||
|
xMOVAPS(ptr[rsp + 32], xRegisterSSE::GetArgRegister(1, 0));
|
||||||
|
xFastCall((void*)LogWriteQuad);
|
||||||
|
xMOVAPS(xRegisterSSE::GetArgRegister(1, 0), ptr[rsp + 32]);
|
||||||
|
xADD(rsp, 32 + 32);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bits == 8)
|
||||||
|
xAND(arg2regd, 0xFF);
|
||||||
|
else if (bits == 16)
|
||||||
|
xAND(arg2regd, 0xFFFF);
|
||||||
|
else if (bits == 32)
|
||||||
|
xAND(arg2regd, -1);
|
||||||
|
xSUB(rsp, 32);
|
||||||
|
xFastCall((void*)LogWrite);
|
||||||
|
xADD(rsp, 32);
|
||||||
|
}
|
||||||
|
xPOP(arg2reg);
|
||||||
|
xPOP(arg1reg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS];
|
auto vmv = vtlbdata.vmap[addr_const >> VTLB_PAGE_BITS];
|
||||||
if (!vmv.isHandler(addr_const))
|
if (!vmv.isHandler(addr_const))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue