Start to look at x64 recompiler

This commit is contained in:
zilmar 2023-04-04 17:44:42 +09:30
parent fe35d950f3
commit 2c40d47a34
18 changed files with 382 additions and 327 deletions

View File

@ -53,6 +53,7 @@ add_library(Project64-core STATIC
N64System/Recompiler/JumpInfo.cpp N64System/Recompiler/JumpInfo.cpp
N64System/Recompiler/LoopAnalysis.cpp N64System/Recompiler/LoopAnalysis.cpp
N64System/Recompiler/Recompiler.cpp N64System/Recompiler/Recompiler.cpp
N64System/Recompiler/RecompilerOps.cpp
N64System/Recompiler/RecompilerMemory.cpp N64System/Recompiler/RecompilerMemory.cpp
N64System/Recompiler/RegBase.cpp N64System/Recompiler/RegBase.cpp
N64System/Recompiler/Aarch64/Aarch64ops.cpp N64System/Recompiler/Aarch64/Aarch64ops.cpp

View File

@ -246,7 +246,6 @@ protected:
static Func Jump_CoP1_L[64]; static Func Jump_CoP1_L[64];
static void GenerateAddressErrorException(uint64_t VAddr, bool FromRead); static void GenerateAddressErrorException(uint64_t VAddr, bool FromRead);
static void GenerateFloatingPointException(void);
static void GenerateOverflowException(void); static void GenerateOverflowException(void);
static void GenerateTLBReadException(uint64_t VAddr, const char * function); static void GenerateTLBReadException(uint64_t VAddr, const char * function);
static void GenerateTLBWriteException(uint64_t VAddr, const char * function); static void GenerateTLBWriteException(uint64_t VAddr, const char * function);

View File

@ -1482,29 +1482,25 @@ void CN64System::SyncCPU(CN64System * const SecondCPU)
if (bFastSP() && m_Recomp) if (bFastSP() && m_Recomp)
{ {
#if defined(__aarch64__) || defined(__amd64__) || defined(_M_X64)
g_Notify->BreakPoint(__FILE__, __LINE__);
#else
uint32_t StackPointer = (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF); uint32_t StackPointer = (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF);
uint32_t TargetStackPos = 0; uint8_t * TargetStackPos = nullptr;
if (StackPointer < m_MMU_VM.RdramSize()) if (StackPointer < m_MMU_VM.RdramSize())
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Rdram() + StackPointer); TargetStackPos = m_MMU_VM.Rdram() + StackPointer;
} }
else if (StackPointer > 0x04000000 && StackPointer < 0x04001000) else if (StackPointer > 0x04000000 && StackPointer < 0x04001000)
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Dmem() + StackPointer - 0x04000000); TargetStackPos = m_MMU_VM.Dmem() + StackPointer - 0x04000000;
} }
else if (StackPointer > 0x04001000 && StackPointer < 0x04002000) else if (StackPointer > 0x04001000 && StackPointer < 0x04002000)
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Imem() + StackPointer - 0x04001000); TargetStackPos = m_MMU_VM.Imem() + StackPointer - 0x04001000;
} }
if (m_Recomp->MemoryStackPos() != TargetStackPos) if (m_Recomp->MemoryStackPos() != TargetStackPos)
{ {
ErrorFound = true; ErrorFound = true;
} }
#endif
} }
if (m_SystemTimer != SecondCPU->m_SystemTimer) if (m_SystemTimer != SecondCPU->m_SystemTimer)
@ -1679,29 +1675,25 @@ void CN64System::DumpSyncErrors(CN64System * SecondCPU)
} }
if (bFastSP() && m_Recomp) if (bFastSP() && m_Recomp)
{ {
#if defined(__aarch64__) || defined(__amd64__) || defined(_M_X64)
g_Notify->BreakPoint(__FILE__, __LINE__);
#else
uint32_t StackPointer = (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF); uint32_t StackPointer = (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF);
uint32_t TargetStackPos = 0; uint8_t * TargetStackPos = nullptr;
if (StackPointer < m_MMU_VM.RdramSize()) if (StackPointer < m_MMU_VM.RdramSize())
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Rdram() + StackPointer); TargetStackPos = m_MMU_VM.Rdram() + StackPointer;
} }
else if (StackPointer > 0x04000000 && StackPointer < 0x04001000) else if (StackPointer > 0x04000000 && StackPointer < 0x04001000)
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Dmem() + StackPointer - 0x04000000); TargetStackPos = m_MMU_VM.Dmem() + StackPointer - 0x04000000;
} }
else if (StackPointer > 0x04001000 && StackPointer < 0x04002000) else if (StackPointer > 0x04001000 && StackPointer < 0x04002000)
{ {
TargetStackPos = (uint32_t)(m_MMU_VM.Imem() + StackPointer - 0x04001000); TargetStackPos = m_MMU_VM.Imem() + StackPointer - 0x04001000;
} }
if (m_Recomp->MemoryStackPos() != TargetStackPos) if (m_Recomp->MemoryStackPos() != TargetStackPos)
{ {
Error.LogF("MemoryStack = %X should be: %X\r\n", m_Recomp->MemoryStackPos(), (uint32_t)(m_MMU_VM.Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF))); Error.LogF("MemoryStack = %p should be: %p\r\n", m_Recomp->MemoryStackPos(), (uint32_t)(m_MMU_VM.Rdram() + (m_Reg.m_GPR[29].W[0] & 0x1FFFFFFF)));
} }
#endif
} }
uint32_t *Rdram = (uint32_t *)m_MMU_VM.Rdram(), *Rdram2 = (uint32_t *)SecondCPU->m_MMU_VM.Rdram(); uint32_t *Rdram = (uint32_t *)m_MMU_VM.Rdram(), *Rdram2 = (uint32_t *)SecondCPU->m_MMU_VM.Rdram();

View File

@ -13,7 +13,7 @@
extern "C" void __clear_cache_android(uint8_t * begin, uint8_t * end); extern "C" void __clear_cache_android(uint8_t * begin, uint8_t * end);
#endif #endif
CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter) : CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, CRegisters & Reg, uint32_t VAddrEnter) :
m_MMU(MMU), m_MMU(MMU),
m_VAddrEnter(VAddrEnter), m_VAddrEnter(VAddrEnter),
m_VAddrFirst(VAddrEnter), m_VAddrFirst(VAddrEnter),
@ -34,7 +34,9 @@ CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter) :
} }
#endif #endif
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86)
m_RecompilerOps = new CX86RecompilerOps(MMU, *this); m_RecompilerOps = new CX86RecompilerOps(MMU, Reg, *this);
#elif defined(__amd64__) || defined(_M_X64)
m_RecompilerOps = new CX64RecompilerOps(MMU, Reg, *this);
#elif defined(__arm__) || defined(_M_ARM) #elif defined(__arm__) || defined(_M_ARM)
m_RecompilerOps = new CArmRecompilerOps(MMU, *this); m_RecompilerOps = new CArmRecompilerOps(MMU, *this);
#else #else

View File

@ -13,7 +13,7 @@ class CCodeBlock :
public asmjit::ErrorHandler public asmjit::ErrorHandler
{ {
public: public:
CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter); CCodeBlock(CMipsMemoryVM & MMU, CRegisters & Reg, uint32_t VAddrEnter);
~CCodeBlock(); ~CCodeBlock();
bool Compile(); bool Compile();

View File

@ -357,7 +357,6 @@ bool CCodeSection::ParentContinue()
bool CCodeSection::GenerateNativeCode(uint32_t Test) bool CCodeSection::GenerateNativeCode(uint32_t Test)
{ {
#if defined(__i386__) || defined(_M_IX86)
if (m_EnterLabel.isValid()) if (m_EnterLabel.isValid())
{ {
if (m_Test == Test) if (m_Test == Test)
@ -785,10 +784,6 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_END_BLOCK); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_END_BLOCK);
} }
} while (m_RecompilerOps->GetNextStepType() != PIPELINE_STAGE_END_BLOCK); } while (m_RecompilerOps->GetNextStepType() != PIPELINE_STAGE_END_BLOCK);
#else
Test = Test;
g_Notify->BreakPoint(__FILE__, __LINE__);
#endif
return true; return true;
} }

View File

@ -374,7 +374,7 @@ CCompiledFunc * CRecompiler::CompileCode()
CheckRecompMem(); CheckRecompMem();
WriteTrace(TraceRecompiler, TraceDebug, "Compile Block-Start: Program Counter: %X pAddr: %X", PROGRAM_COUNTER, pAddr); WriteTrace(TraceRecompiler, TraceDebug, "Compile Block-Start: Program Counter: %X pAddr: %X", PROGRAM_COUNTER, pAddr);
CCodeBlock CodeBlock(m_MMU, PROGRAM_COUNTER); CCodeBlock CodeBlock(m_MMU, m_Registers, PROGRAM_COUNTER);
if (!CodeBlock.Compile()) if (!CodeBlock.Compile())
{ {
return nullptr; return nullptr;

View File

@ -0,0 +1,15 @@
#include "stdafx.h"
#include "RecompilerOps.h"
CRecompilerOpsBase::CRecompilerOpsBase(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock) :
m_Reg(Reg),
m_MMU(MMU),
m_CodeBlock(CodeBlock),
m_Section(nullptr)
{
}
CRecompilerOpsBase::~CRecompilerOpsBase()
{
}

View File

@ -1,4 +1,6 @@
#pragma once #pragma once
#include <Project64-core\N64System\Mips\R4300iOpcode.h>
#include <Project64-core\Settings\DebugSettings.h>
enum RecompilerBranchType enum RecompilerBranchType
{ {
@ -35,6 +37,29 @@ enum RecompilerTrapCompare
RecompilerTrapCompare_TLTIU, RecompilerTrapCompare_TLTIU,
}; };
class CCodeBlock;
class CCodeSection;
class CMipsMemoryVM;
class CRegisters;
class CRecompilerOpsBase :
protected CDebugSettings
{
protected:
CRecompilerOpsBase(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock);
~CRecompilerOpsBase();
CMipsMemoryVM & m_MMU;
CRegisters & m_Reg;
CCodeBlock & m_CodeBlock;
R4300iOpcode m_Opcode;
CCodeSection * m_Section;
private:
CRecompilerOpsBase(const CRecompilerOpsBase &);
CRecompilerOpsBase & operator=(const CRecompilerOpsBase &);
};
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86)
#include <Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h> #include <Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h>

View File

@ -1,9 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#if defined(__amd64__) || defined(_M_X64) #if defined(__amd64__) || defined(_M_X64)
#include <Project64-core/N64System/Recompiler/x64-86/x64RecompilerOps.h> #include <Project64-core\N64System\Recompiler\CodeBlock.h>
#include <Project64-core\N64System\Recompiler\CodeSection.h>
#include <Project64-core\N64System\Recompiler\x64-86\x64RecompilerOps.h>
CX64RecompilerOps::CX64RecompilerOps(CMipsMemoryVM & /*MMU*/, CCodeBlock & CodeBlock) : CX64RecompilerOps::CX64RecompilerOps(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock) :
CRecompilerOpsBase(MMU, Reg, CodeBlock),
m_Assembler(CodeBlock), m_Assembler(CodeBlock),
m_RegWorkingSet(CodeBlock, m_Assembler) m_RegWorkingSet(CodeBlock, m_Assembler)
{ {
@ -795,12 +798,10 @@ void CX64RecompilerOps::UnknownOpcode()
void CX64RecompilerOps::EnterCodeBlock() void CX64RecompilerOps::EnterCodeBlock()
{ {
g_Notify->BreakPoint(__FILE__, __LINE__);
} }
void CX64RecompilerOps::CompileExitCode() void CX64RecompilerOps::CompileExitCode()
{ {
g_Notify->BreakPoint(__FILE__, __LINE__);
} }
void CX64RecompilerOps::CompileInPermLoop(CRegInfo & /*RegSet*/, uint32_t /*ProgramCounter*/) void CX64RecompilerOps::CompileInPermLoop(CRegInfo & /*RegSet*/, uint32_t /*ProgramCounter*/)
@ -813,14 +814,14 @@ void CX64RecompilerOps::SyncRegState(const CRegInfo & /*SyncTo*/)
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
CRegInfo & CX64RecompilerOps::GetRegWorkingSet(void) CX64RegInfo & CX64RecompilerOps::GetRegWorkingSet(void)
{ {
return m_RegWorkingSet; return m_RegWorkingSet;
} }
void CX64RecompilerOps::SetRegWorkingSet(const CRegInfo & /*RegInfo*/) void CX64RecompilerOps::SetRegWorkingSet(const CX64RegInfo & RegInfo)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); m_RegWorkingSet = RegInfo;
} }
bool CX64RecompilerOps::InheritParentInfo() bool CX64RecompilerOps::InheritParentInfo()

View File

@ -1,22 +1,19 @@
#pragma once #pragma once
#if defined(__amd64__) || defined(_M_X64) #if defined(__amd64__) || defined(_M_X64)
#include <Project64-core/N64System/Mips/R4300iOpcode.h>
#include <Project64-core/N64System/Recompiler/ExitInfo.h> #include <Project64-core/N64System/Recompiler/ExitInfo.h>
#include <Project64-core/N64System/Recompiler/RecompilerOps.h> #include <Project64-core/N64System/Recompiler/RecompilerOps.h>
#include <Project64-core/N64System/Recompiler/RegInfo.h> #include <Project64-core/N64System/Recompiler/RegInfo.h>
#include <Project64-core/N64System/Recompiler/x64-86/x64ops.h> #include <Project64-core/N64System/Recompiler/x64-86/x64ops.h>
class CMipsMemoryVM;
class CCodeBlock;
class CCodeSection;
class CX64Ops; class CX64Ops;
struct CJumpInfo; struct CJumpInfo;
class CX64RecompilerOps class CX64RecompilerOps :
public CRecompilerOpsBase
{ {
public: public:
CX64RecompilerOps(CMipsMemoryVM & MMU, CCodeBlock & CodeBlock); CX64RecompilerOps(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock);
~CX64RecompilerOps(); ~CX64RecompilerOps();
// Trap functions // Trap functions
@ -203,8 +200,8 @@ public:
void CompileExitCode(); void CompileExitCode();
void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter); void CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCounter);
void SyncRegState(const CRegInfo & SyncTo); void SyncRegState(const CRegInfo & SyncTo);
CRegInfo & GetRegWorkingSet(void); CX64RegInfo & GetRegWorkingSet(void);
void SetRegWorkingSet(const CRegInfo & RegInfo); void SetRegWorkingSet(const CX64RegInfo & RegInfo);
bool InheritParentInfo(); bool InheritParentInfo();
void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1); void LinkJump(CJumpInfo & JumpInfo, uint32_t SectionID = -1, uint32_t FromSectionID = -1);
void JumpToSection(CCodeSection * Section); void JumpToSection(CCodeSection * Section);
@ -235,7 +232,6 @@ private:
CX64RegInfo m_RegWorkingSet; CX64RegInfo m_RegWorkingSet;
CX64Ops m_Assembler; CX64Ops m_Assembler;
R4300iOpcode m_Opcode;
}; };
typedef CX64RecompilerOps CRecompilerOps; typedef CX64RecompilerOps CRecompilerOps;

View File

@ -19,20 +19,28 @@ CX64RegInfo::~CX64RegInfo()
CX64RegInfo & CX64RegInfo::operator=(const CX64RegInfo & right) CX64RegInfo & CX64RegInfo::operator=(const CX64RegInfo & right)
{ {
CRegBase::operator=(right); CRegBase::operator=(right);
g_Notify->BreakPoint(__FILE__, __LINE__); #ifdef _DEBUG
if (*this != right)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
#endif
return *this; return *this;
} }
bool CX64RegInfo::operator==(const CX64RegInfo & /*right*/) const bool CX64RegInfo::operator==(const CX64RegInfo & Right) const
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); if (!CRegBase::operator==(Right))
return false; {
return false;
}
return true;
} }
bool CX64RegInfo::operator!=(const CX64RegInfo & /*right*/) const bool CX64RegInfo::operator!=(const CX64RegInfo & Right) const
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); return !(Right == *this);
return false;
} }
void CX64RegInfo::UnMap_GPR(uint32_t /*Reg*/, bool /*WriteBackValue*/) void CX64RegInfo::UnMap_GPR(uint32_t /*Reg*/, bool /*WriteBackValue*/)

View File

@ -1,6 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#if defined(__amd64__) || defined(_M_X64) #if defined(__amd64__) || defined(_M_X64)
#include <Project64-core/N64System/Recompiler/CodeBlock.h>
#include <Project64-core/N64System/Recompiler/x64-86/x64ops.h> #include <Project64-core/N64System/Recompiler/x64-86/x64ops.h>
CX64Ops::CX64Ops(CCodeBlock & CodeBlock) : CX64Ops::CX64Ops(CCodeBlock & CodeBlock) :
@ -8,4 +9,16 @@ CX64Ops::CX64Ops(CCodeBlock & CodeBlock) :
{ {
} }
asmjit::Error CX64Ops::_log(const char * data, size_t size) noexcept
{
stdstr AsmjitLog(std::string(data, size));
AsmjitLog.Trim("\n");
for (SymbolMap::const_iterator itr = m_Symbols.begin(); itr != m_Symbols.end(); itr++)
{
AsmjitLog.Replace(itr->first, itr->second);
}
m_CodeBlock.Log(" %s", AsmjitLog.c_str());
return asmjit::kErrorOk;
}
#endif #endif

View File

@ -1,9 +1,14 @@
#pragma once #pragma once
#if defined(__amd64__) || defined(_M_X64) #if defined(__amd64__) || defined(_M_X64)
#include <Project64-core/N64System/Recompiler/asmjit.h>
#include <map>
#include <string>
class CCodeBlock; class CCodeBlock;
class CX64Ops class CX64Ops :
public asmjit::x86::Assembler,
public asmjit::Logger
{ {
public: public:
CX64Ops(CCodeBlock & CodeBlock); CX64Ops(CCodeBlock & CodeBlock);
@ -13,6 +18,11 @@ private:
CX64Ops(const CX64Ops &); CX64Ops(const CX64Ops &);
CX64Ops & operator=(const CX64Ops &); CX64Ops & operator=(const CX64Ops &);
asmjit::Error _log(const char * data, size_t size) noexcept;
typedef std::map<std::string, std::string> SymbolMap;
SymbolMap m_Symbols;
CCodeBlock & m_CodeBlock; CCodeBlock & m_CodeBlock;
}; };

View File

@ -2,7 +2,6 @@
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86)
#include <Project64-core/N64System/Interpreter/InterpreterOps.h> #include <Project64-core/N64System/Interpreter/InterpreterOps.h>
#include <Project64-core/N64System/Mips/R4300iOpcode.h>
#include <Project64-core/N64System/Mips/Register.h> #include <Project64-core/N64System/Mips/Register.h>
#include <Project64-core/N64System/Recompiler/ExitInfo.h> #include <Project64-core/N64System/Recompiler/ExitInfo.h>
#include <Project64-core/N64System/Recompiler/JumpInfo.h> #include <Project64-core/N64System/Recompiler/JumpInfo.h>
@ -18,13 +17,14 @@ class CCodeBlock;
class CCodeSection; class CCodeSection;
class CX86RecompilerOps : class CX86RecompilerOps :
protected R4300iOp, public CRecompilerOpsBase,
protected CN64SystemSettings, protected CN64SystemSettings,
protected CRecompilerSettings, protected CRecompilerSettings,
protected CLogSettings,
private CGameSettings private CGameSettings
{ {
public: public:
CX86RecompilerOps(CMipsMemoryVM & MMU, CCodeBlock & CodeBlock); CX86RecompilerOps(CMipsMemoryVM & MMU, CRegisters & Reg, CCodeBlock & CodeBlock);
~CX86RecompilerOps(); ~CX86RecompilerOps();
// Trap functions // Trap functions
@ -445,14 +445,10 @@ private:
void ResetMemoryStack(); void ResetMemoryStack();
EXIT_LIST m_ExitInfo; EXIT_LIST m_ExitInfo;
CMipsMemoryVM & m_MMU;
CCodeBlock & m_CodeBlock;
CX86Ops m_Assembler; CX86Ops m_Assembler;
PIPELINE_STAGE m_PipelineStage; PIPELINE_STAGE m_PipelineStage;
uint32_t m_CompilePC; uint32_t m_CompilePC;
R4300iOpcode m_Opcode;
CX86RegInfo m_RegWorkingSet; CX86RegInfo m_RegWorkingSet;
CCodeSection * m_Section;
CRegInfo m_RegBeforeDelay; CRegInfo m_RegBeforeDelay;
bool m_EffectDelaySlot; bool m_EffectDelaySlot;
static uint32_t m_TempValue32; static uint32_t m_TempValue32;

View File

@ -104,6 +104,7 @@
<ClCompile Include="N64System\Recompiler\LoopAnalysis.cpp" /> <ClCompile Include="N64System\Recompiler\LoopAnalysis.cpp" />
<ClCompile Include="N64System\Recompiler\Recompiler.cpp" /> <ClCompile Include="N64System\Recompiler\Recompiler.cpp" />
<ClCompile Include="N64System\Recompiler\RecompilerMemory.cpp" /> <ClCompile Include="N64System\Recompiler\RecompilerMemory.cpp" />
<ClCompile Include="N64System\Recompiler\RecompilerOps.cpp" />
<ClCompile Include="N64System\Recompiler\RegBase.cpp" /> <ClCompile Include="N64System\Recompiler\RegBase.cpp" />
<ClCompile Include="N64System\Recompiler\x64-86\x64ops.cpp" /> <ClCompile Include="N64System\Recompiler\x64-86\x64ops.cpp" />
<ClCompile Include="N64System\Recompiler\x64-86\x64RecompilerOps.cpp" /> <ClCompile Include="N64System\Recompiler\x64-86\x64RecompilerOps.cpp" />

View File

@ -435,6 +435,9 @@
<ClCompile Include="Settings\SettingType\SettingsType-RDB.cpp"> <ClCompile Include="Settings\SettingType\SettingsType-RDB.cpp">
<Filter>Source Files\Settings\SettingType</Filter> <Filter>Source Files\Settings\SettingType</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="N64System\Recompiler\RecompilerOps.cpp">
<Filter>Source Files\N64 System\Recompiler</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="stdafx.h"> <ClInclude Include="stdafx.h">