Core: Change recompiler to use asmjit

This commit is contained in:
zilmar 2022-11-23 14:46:55 +10:30
parent 2a6d3cd519
commit 8e94b3086b
21 changed files with 2143 additions and 5123 deletions

View File

@ -38,6 +38,24 @@
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\asmjit\arm\a64archtraits_p.h" />
<ClInclude Include="src\asmjit\arm\a64assembler.h" />
<ClInclude Include="src\asmjit\arm\a64builder.h" />
<ClInclude Include="src\asmjit\arm\a64compiler.h" />
<ClInclude Include="src\asmjit\arm\a64emithelper_p.h" />
<ClInclude Include="src\asmjit\arm\a64emitter.h" />
<ClInclude Include="src\asmjit\arm\a64formatter_p.h" />
<ClInclude Include="src\asmjit\arm\a64func_p.h" />
<ClInclude Include="src\asmjit\arm\a64globals.h" />
<ClInclude Include="src\asmjit\arm\a64instapi_p.h" />
<ClInclude Include="src\asmjit\arm\a64instdb.h" />
<ClInclude Include="src\asmjit\arm\a64instdb_p.h" />
<ClInclude Include="src\asmjit\arm\a64operand.h" />
<ClInclude Include="src\asmjit\arm\a64rapass_p.h" />
<ClInclude Include="src\asmjit\arm\a64utils.h" />
<ClInclude Include="src\asmjit\arm\armformatter_p.h" />
<ClInclude Include="src\asmjit\arm\armglobals.h" />
<ClInclude Include="src\asmjit\arm\armoperand.h" />
<ClInclude Include="src\asmjit\asmjit-scope-begin.h" /> <ClInclude Include="src\asmjit\asmjit-scope-begin.h" />
<ClInclude Include="src\asmjit\asmjit-scope-end.h" /> <ClInclude Include="src\asmjit\asmjit-scope-end.h" />
<ClInclude Include="src\asmjit\asmjit.h" /> <ClInclude Include="src\asmjit\asmjit.h" />
@ -63,6 +81,7 @@
<ClInclude Include="src\asmjit\core\errorhandler.h" /> <ClInclude Include="src\asmjit\core\errorhandler.h" />
<ClInclude Include="src\asmjit\core\features.h" /> <ClInclude Include="src\asmjit\core\features.h" />
<ClInclude Include="src\asmjit\core\formatter.h" /> <ClInclude Include="src\asmjit\core\formatter.h" />
<ClInclude Include="src\asmjit\core\formatter_p.h" />
<ClInclude Include="src\asmjit\core\func.h" /> <ClInclude Include="src\asmjit\core\func.h" />
<ClInclude Include="src\asmjit\core\funcargscontext_p.h" /> <ClInclude Include="src\asmjit\core\funcargscontext_p.h" />
<ClInclude Include="src\asmjit\core\globals.h" /> <ClInclude Include="src\asmjit\core\globals.h" />
@ -99,7 +118,6 @@
<ClInclude Include="src\asmjit\x86\x86compiler.h" /> <ClInclude Include="src\asmjit\x86\x86compiler.h" />
<ClInclude Include="src\asmjit\x86\x86emithelper_p.h" /> <ClInclude Include="src\asmjit\x86\x86emithelper_p.h" />
<ClInclude Include="src\asmjit\x86\x86emitter.h" /> <ClInclude Include="src\asmjit\x86\x86emitter.h" />
<ClInclude Include="src\asmjit\x86\x86features.h" />
<ClInclude Include="src\asmjit\x86\x86formatter_p.h" /> <ClInclude Include="src\asmjit\x86\x86formatter_p.h" />
<ClInclude Include="src\asmjit\x86\x86func_p.h" /> <ClInclude Include="src\asmjit\x86\x86func_p.h" />
<ClInclude Include="src\asmjit\x86\x86globals.h" /> <ClInclude Include="src\asmjit\x86\x86globals.h" />
@ -111,6 +129,17 @@
<ClInclude Include="src\asmjit\x86\x86rapass_p.h" /> <ClInclude Include="src\asmjit\x86\x86rapass_p.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\asmjit\arm\a64assembler.cpp" />
<ClCompile Include="src\asmjit\arm\a64builder.cpp" />
<ClCompile Include="src\asmjit\arm\a64compiler.cpp" />
<ClCompile Include="src\asmjit\arm\a64emithelper.cpp" />
<ClCompile Include="src\asmjit\arm\a64formatter.cpp" />
<ClCompile Include="src\asmjit\arm\a64func.cpp" />
<ClCompile Include="src\asmjit\arm\a64instapi.cpp" />
<ClCompile Include="src\asmjit\arm\a64instdb.cpp" />
<ClCompile Include="src\asmjit\arm\a64operand.cpp" />
<ClCompile Include="src\asmjit\arm\a64rapass.cpp" />
<ClCompile Include="src\asmjit\arm\armformatter.cpp" />
<ClCompile Include="src\asmjit\core\archtraits.cpp" /> <ClCompile Include="src\asmjit\core\archtraits.cpp" />
<ClCompile Include="src\asmjit\core\assembler.cpp" /> <ClCompile Include="src\asmjit\core\assembler.cpp" />
<ClCompile Include="src\asmjit\core\builder.cpp" /> <ClCompile Include="src\asmjit\core\builder.cpp" />

View File

@ -25,6 +25,12 @@
<Filter Include="Source Files\x86"> <Filter Include="Source Files\x86">
<UniqueIdentifier>{6b84aaac-0a23-40c3-a433-b295187c29f6}</UniqueIdentifier> <UniqueIdentifier>{6b84aaac-0a23-40c3-a433-b295187c29f6}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Header Files\arm">
<UniqueIdentifier>{c917aef2-cca5-40a8-96ce-44c52b0be104}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\arm">
<UniqueIdentifier>{1887f342-a4a7-4afc-a943-f43721792e81}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\asmjit\asmjit.h"> <ClInclude Include="src\asmjit\asmjit.h">
@ -210,9 +216,6 @@
<ClInclude Include="src\asmjit\x86\x86emitter.h"> <ClInclude Include="src\asmjit\x86\x86emitter.h">
<Filter>Header Files\x86</Filter> <Filter>Header Files\x86</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\asmjit\x86\x86features.h">
<Filter>Header Files\x86</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\x86\x86formatter_p.h"> <ClInclude Include="src\asmjit\x86\x86formatter_p.h">
<Filter>Header Files\x86</Filter> <Filter>Header Files\x86</Filter>
</ClInclude> </ClInclude>
@ -240,6 +243,63 @@
<ClInclude Include="src\asmjit\x86\x86rapass_p.h"> <ClInclude Include="src\asmjit\x86\x86rapass_p.h">
<Filter>Header Files\x86</Filter> <Filter>Header Files\x86</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\asmjit\core\formatter_p.h">
<Filter>Header Files\core</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64archtraits_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64assembler.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64builder.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64compiler.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64emithelper_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64emitter.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64formatter_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64func_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64globals.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64instapi_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64instdb.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64instdb_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64operand.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64rapass_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\a64utils.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\armformatter_p.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\armglobals.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
<ClInclude Include="src\asmjit\arm\armoperand.h">
<Filter>Header Files\arm</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\asmjit\core\archtraits.cpp"> <ClCompile Include="src\asmjit\core\archtraits.cpp">
@ -383,5 +443,38 @@
<ClCompile Include="src\asmjit\x86\x86rapass.cpp"> <ClCompile Include="src\asmjit\x86\x86rapass.cpp">
<Filter>Source Files\x86</Filter> <Filter>Source Files\x86</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\asmjit\arm\a64assembler.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64builder.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64compiler.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64emithelper.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64formatter.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64func.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64instapi.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64instdb.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64operand.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\a64rapass.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
<ClCompile Include="src\asmjit\arm\armformatter.cpp">
<Filter>Source Files\arm</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -13,16 +13,19 @@
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, uint8_t * CompiledLocation) : CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter) :
m_MMU(MMU), m_MMU(MMU),
m_VAddrEnter(VAddrEnter), m_VAddrEnter(VAddrEnter),
m_VAddrFirst(VAddrEnter), m_VAddrFirst(VAddrEnter),
m_VAddrLast(VAddrEnter), m_VAddrLast(VAddrEnter),
m_CompiledLocation(CompiledLocation), m_CompiledLocation(nullptr),
m_EnterSection(nullptr), m_EnterSection(nullptr),
m_RecompilerOps(nullptr), m_RecompilerOps(nullptr),
m_Test(1) m_Test(1)
{ {
m_Environment = asmjit::Environment::host();
m_CodeHolder.init(m_Environment);
m_CodeHolder.setErrorHandler(this);
#if defined(__arm__) || defined(_M_ARM) #if defined(__arm__) || defined(_M_ARM)
// Make sure function starts at an odd address so that the system knows it is in thumb mode // Make sure function starts at an odd address so that the system knows it is in thumb mode
if (((uint32_t)m_CompiledLocation % 2) == 0) if (((uint32_t)m_CompiledLocation % 2) == 0)
@ -50,7 +53,7 @@ CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * Compi
m_Sections.push_back(baseSection); m_Sections.push_back(baseSection);
baseSection->AddParent(nullptr); baseSection->AddParent(nullptr);
baseSection->m_CompiledLocation = (uint8_t *)-1; baseSection->m_EnterLabel = asmjit::Label(1);
baseSection->m_Cont.JumpPC = VAddrEnter; baseSection->m_Cont.JumpPC = VAddrEnter;
baseSection->m_Cont.FallThrough = true; baseSection->m_Cont.FallThrough = true;
baseSection->m_Cont.RegSet = baseSection->m_RegEnter; baseSection->m_Cont.RegSet = baseSection->m_RegEnter;
@ -857,12 +860,6 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
bool CCodeBlock::Compile() bool CCodeBlock::Compile()
{ {
Log("====== Code block ======");
Log("Native entry point: %X", CompiledLocation());
Log("Start of block: %X", VAddrEnter());
Log("Number of sections: %d", NoOfSections());
Log("====== Recompiled code ======");
m_RecompilerOps->EnterCodeBlock(); m_RecompilerOps->EnterCodeBlock();
if (g_System->bLinkBlocks()) if (g_System->bLinkBlocks())
{ {
@ -877,7 +874,6 @@ bool CCodeBlock::Compile()
} }
} }
m_RecompilerOps->CompileExitCode(); m_RecompilerOps->CompileExitCode();
m_CompiledLocationEnd = *g_RecompPos;
uint32_t BlockSize = (VAddrLast() - VAddrFirst()) + 4; uint32_t BlockSize = (VAddrLast() - VAddrFirst()) + 4;
uint8_t * BlockPtr = m_MMU.MemoryPtr(VAddrFirst(), BlockSize, true); uint8_t * BlockPtr = m_MMU.MemoryPtr(VAddrFirst(), BlockSize, true);
@ -887,12 +883,35 @@ bool CCodeBlock::Compile()
return false; return false;
} }
MD5(BlockPtr, BlockSize).get_digest(m_Hash); MD5(BlockPtr, BlockSize).get_digest(m_Hash);
#if defined(ANDROID) && (defined(__arm__) || defined(_M_ARM))
__clear_cache((uint8_t *)((uint32_t)m_CompiledLocation & ~1), m_CompiledLocationEnd);
#endif
return true; return true;
} }
uint32_t CCodeBlock::Finilize(uint8_t * CompiledLocation)
{
if (CDebugSettings::bRecordRecompilerAsm())
{
std::string CodeLog = m_CodeLog;
m_CodeLog.clear();
Log("====== Code block ======");
Log("Native entry point: %X", CompiledLocation);
Log("Start of block: %X", VAddrEnter());
Log("Number of sections: %d", NoOfSections());
Log("====== Recompiled code ======");
m_CodeLog += CodeLog;
}
m_CompiledLocation = CompiledLocation;
m_CodeHolder.relocateToBase((uint64_t)m_CompiledLocation);
size_t codeSize = m_CodeHolder.codeSize();
m_CodeHolder.copyFlattenedData(m_CompiledLocation, codeSize, asmjit::CopySectionFlags::kPadSectionBuffer);
*g_RecompPos += codeSize;
#if defined(ANDROID) && (defined(__arm__) || defined(_M_ARM))
__clear_cache((uint8_t *)((uint32_t)m_CompiledLocation & ~1), m_CompiledLocation + codeSize);
#endif
return codeSize;
}
uint32_t CCodeBlock::NextTest() uint32_t CCodeBlock::NextTest()
{ {
uint32_t next_test = m_Test; uint32_t next_test = m_Test;
@ -923,3 +942,8 @@ void CCodeBlock::Log(_Printf_format_string_ const char * Text, ...)
#pragma warning(pop) #pragma warning(pop)
va_end(args); va_end(args);
} }
void CCodeBlock::handleError(asmjit::Error /*err*/, const char * /*message*/, asmjit::BaseEmitter * /*origin*/)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}

View File

@ -9,14 +9,20 @@
class CMipsMemoryVM; class CMipsMemoryVM;
class CCodeBlock class CCodeBlock :
public asmjit::ErrorHandler
{ {
public: public:
CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * CompiledLocation); CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter);
~CCodeBlock(); ~CCodeBlock();
bool Compile(); bool Compile();
uint32_t Finilize(uint8_t * CompiledLocation);
asmjit::CodeHolder & CodeHolder(void)
{
return m_CodeHolder;
}
uint32_t VAddrEnter() const uint32_t VAddrEnter() const
{ {
return m_VAddrEnter; return m_VAddrEnter;
@ -33,10 +39,6 @@ public:
{ {
return m_CompiledLocation; return m_CompiledLocation;
} }
uint8_t * CompiledLocationEnd() const
{
return m_CompiledLocationEnd;
}
int32_t NoOfSections() const int32_t NoOfSections() const
{ {
return (int32_t)m_Sections.size() - 1; return (int32_t)m_Sections.size() - 1;
@ -101,12 +103,14 @@ private:
void LogSectionInfo(); void LogSectionInfo();
bool SetSection(CCodeSection *& Section, CCodeSection * CurrentSection, uint32_t TargetPC, bool LinkAllowed, uint32_t CurrentPC); bool SetSection(CCodeSection *& Section, CCodeSection * CurrentSection, uint32_t TargetPC, bool LinkAllowed, uint32_t CurrentPC);
bool AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock, bool & PermLoop); bool AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock, bool & PermLoop);
void handleError(asmjit::Error err, const char* message, asmjit::BaseEmitter* origin);
asmjit::Environment m_Environment;
asmjit::CodeHolder m_CodeHolder;
uint32_t m_VAddrEnter; uint32_t m_VAddrEnter;
uint32_t m_VAddrFirst; uint32_t m_VAddrFirst;
uint32_t m_VAddrLast; uint32_t m_VAddrLast;
uint8_t * m_CompiledLocation; uint8_t * m_CompiledLocation;
uint8_t * m_CompiledLocationEnd;
typedef std::map<uint32_t, CCodeSection *> SectionMap; typedef std::map<uint32_t, CCodeSection *> SectionMap;
typedef std::list<CCodeSection *> SectionList; typedef std::list<CCodeSection *> SectionList;

View File

@ -24,7 +24,6 @@ CCodeSection::CCodeSection(CCodeBlock & CodeBlock, uint32_t EnterPC, uint32_t ID
m_LinkAllowed(LinkAllowed), m_LinkAllowed(LinkAllowed),
m_Test(0), m_Test(0),
m_Test2(0), m_Test2(0),
m_CompiledLocation(nullptr),
m_InLoop(false), m_InLoop(false),
m_DelaySlot(false), m_DelaySlot(false),
m_RecompilerOps(CodeBlock.RecompilerOps()), m_RecompilerOps(CodeBlock.RecompilerOps()),
@ -48,7 +47,7 @@ void CCodeSection::GenerateSectionLinkage()
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (JumpInfo[i]->LinkLocation == nullptr && if (!JumpInfo[i]->LinkLocation.isValid() &&
JumpInfo[i]->FallThrough == false) JumpInfo[i]->FallThrough == false)
{ {
JumpInfo[i]->TargetPC = (uint32_t)-1; JumpInfo[i]->TargetPC = (uint32_t)-1;
@ -75,7 +74,7 @@ void CCodeSection::GenerateSectionLinkage()
{ {
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (JumpInfo[i]->LinkLocation == nullptr && JumpInfo[i]->FallThrough == false) if (!JumpInfo[i]->LinkLocation.isValid() && JumpInfo[i]->FallThrough == false)
{ {
if (TargetSection[i]) if (TargetSection[i])
{ {
@ -107,11 +106,11 @@ void CCodeSection::GenerateSectionLinkage()
} }
else else
{ {
if (m_Cont.LinkLocation == nullptr && m_Cont.FallThrough == false) if (!m_Cont.LinkLocation.isValid() && m_Cont.FallThrough == false)
{ {
m_ContinueSection = nullptr; m_ContinueSection = nullptr;
} }
if (m_Jump.LinkLocation == nullptr && m_Jump.FallThrough == false) if (!m_Jump.LinkLocation.isValid() && m_Jump.FallThrough == false)
{ {
m_JumpSection = nullptr; m_JumpSection = nullptr;
} }
@ -135,7 +134,7 @@ void CCodeSection::GenerateSectionLinkage()
continue; continue;
} }
if (TargetSection[i]->m_CompiledLocation != nullptr) if (TargetSection[i]->m_EnterLabel.isValid())
{ {
JumpInfo[i]->FallThrough = false; JumpInfo[i]->FallThrough = false;
m_RecompilerOps->LinkJump(*JumpInfo[i], TargetSection[i]->m_SectionID); m_RecompilerOps->LinkJump(*JumpInfo[i], TargetSection[i]->m_SectionID);
@ -178,8 +177,7 @@ void CCodeSection::GenerateSectionLinkage()
for (SECTION_LIST::iterator iter = TargetSection[i]->m_ParentSection.begin(); iter != TargetSection[i]->m_ParentSection.end(); iter++) for (SECTION_LIST::iterator iter = TargetSection[i]->m_ParentSection.begin(); iter != TargetSection[i]->m_ParentSection.end(); iter++)
{ {
CCodeSection * Parent = *iter; CCodeSection * Parent = *iter;
if (Parent->m_EnterLabel.isValid())
if (Parent->m_CompiledLocation != nullptr)
{ {
continue; continue;
} }
@ -224,10 +222,9 @@ void CCodeSection::GenerateSectionLinkage()
} }
} }
//CodeLog("Section %d",m_SectionID);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if (JumpInfo[i]->LinkLocation == nullptr) if (!JumpInfo[i]->LinkLocation.isValid())
{ {
continue; continue;
} }
@ -242,7 +239,7 @@ void CCodeSection::GenerateSectionLinkage()
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
if (TargetSection[i]->m_CompiledLocation == nullptr) if (!TargetSection[i]->m_EnterLabel.isValid())
{ {
TargetSection[i]->GenerateNativeCode(m_CodeBlock.NextTest()); TargetSection[i]->GenerateNativeCode(m_CodeBlock.NextTest());
} }
@ -304,7 +301,7 @@ bool CCodeSection::ParentContinue()
for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++) for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++)
{ {
CCodeSection * Parent = *iter; CCodeSection * Parent = *iter;
if (Parent->m_CompiledLocation != nullptr) if (Parent->m_EnterLabel.isValid())
{ {
continue; continue;
} }
@ -325,7 +322,7 @@ bool CCodeSection::ParentContinue()
bool CCodeSection::GenerateNativeCode(uint32_t Test) bool CCodeSection::GenerateNativeCode(uint32_t Test)
{ {
if (m_CompiledLocation != nullptr) if (m_EnterLabel.isValid())
{ {
if (m_Test == Test) if (m_Test == Test)
{ {
@ -347,7 +344,8 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
{ {
return false; return false;
} }
m_CompiledLocation = *g_RecompPos; m_EnterLabel = m_RecompilerOps->Assembler().newLabel();
m_RecompilerOps->Assembler().bind(m_EnterLabel);
m_RecompilerOps->SetRegWorkingSet(m_RegEnter); m_RecompilerOps->SetRegWorkingSet(m_RegEnter);
m_RecompilerOps->SetCurrentPC(m_EnterPC); m_RecompilerOps->SetCurrentPC(m_EnterPC);
m_RecompilerOps->SetNextStepType(m_DelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL); m_RecompilerOps->SetNextStepType(m_DelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
@ -988,19 +986,11 @@ void CCodeSection::UnlinkParent(CCodeSection * Parent, bool ContinueSection)
CCodeSection * CodeSection = *iter; CCodeSection * CodeSection = *iter;
if (CodeSection->m_ContinueSection == this) if (CodeSection->m_ContinueSection == this)
{ {
if (CodeSection->m_CompiledLocation)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
CodeSection->m_ContinueSection = nullptr; CodeSection->m_ContinueSection = nullptr;
} }
if (CodeSection->m_JumpSection == this) if (CodeSection->m_JumpSection == this)
{ {
if (CodeSection->m_CompiledLocation)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
CodeSection->m_JumpSection = nullptr; CodeSection->m_JumpSection = nullptr;
} }
} }
@ -1026,7 +1016,7 @@ void CCodeSection::UnlinkParent(CCodeSection * Parent, bool ContinueSection)
bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, uint32_t Test) bool CCodeSection::IsAllParentLoops(CCodeSection * Parent, bool IgnoreIfCompiled, uint32_t Test)
{ {
if (IgnoreIfCompiled && Parent->m_CompiledLocation != nullptr) if (IgnoreIfCompiled && Parent->m_EnterLabel.isValid())
{ {
return true; return true;
} }
@ -1103,7 +1093,6 @@ void CCodeSection::DisplaySectionInformation()
{ {
m_CodeBlock.Log("End PC: 0x%X", m_EndPC); m_CodeBlock.Log("End PC: 0x%X", m_EndPC);
} }
m_CodeBlock.Log("CompiledLocation: 0x%X", m_CompiledLocation);
if (g_System->bLinkBlocks() && !m_ParentSection.empty()) if (g_System->bLinkBlocks() && !m_ParentSection.empty())
{ {
stdstr ParentList; stdstr ParentList;

View File

@ -39,7 +39,7 @@ public:
bool m_LinkAllowed; bool m_LinkAllowed;
uint32_t m_Test; uint32_t m_Test;
uint32_t m_Test2; uint32_t m_Test2;
uint8_t * m_CompiledLocation; asmjit::Label m_EnterLabel;
bool m_InLoop; bool m_InLoop;
bool m_DelaySlot; bool m_DelaySlot;
CRecompilerOps *& m_RecompilerOps; CRecompilerOps *& m_RecompilerOps;

View File

@ -6,7 +6,7 @@
CExitInfo::CExitInfo(CCodeBlock & CodeBlock) : CExitInfo::CExitInfo(CCodeBlock & CodeBlock) :
ID(0), ID(0),
TargetPC(0), TargetPC(0),
JumpLoc(nullptr),
ExitRegSet(CodeBlock, CodeBlock.RecompilerOps()->Assembler()) ExitRegSet(CodeBlock, CodeBlock.RecompilerOps()->Assembler())
{ {
JumpLabel = CodeBlock.RecompilerOps()->Assembler().newLabel();
} }

View File

@ -32,7 +32,7 @@ struct CExitInfo
CRegInfo ExitRegSet; CRegInfo ExitRegSet;
ExitReason Reason; ExitReason Reason;
PIPELINE_STAGE PipelineStage; PIPELINE_STAGE PipelineStage;
uint32_t * JumpLoc; // 32-bit jump asmjit::Label JumpLabel;
}; };
typedef std::list<CExitInfo> EXIT_LIST; typedef std::list<CExitInfo> EXIT_LIST;

View File

@ -7,7 +7,6 @@ CCompiledFunc::CCompiledFunc(const CCodeBlock & CodeBlock) :
m_MaxPC(CodeBlock.VAddrLast()), m_MaxPC(CodeBlock.VAddrLast()),
m_Hash(CodeBlock.Hash()), m_Hash(CodeBlock.Hash()),
m_Function((Func)CodeBlock.CompiledLocation()), m_Function((Func)CodeBlock.CompiledLocation()),
m_FunctionEnd(CodeBlock.CompiledLocationEnd()),
m_Next(nullptr) m_Next(nullptr)
{ {
m_MemContents[0] = CodeBlock.MemContents(0); m_MemContents[0] = CodeBlock.MemContents(0);

View File

@ -24,10 +24,6 @@ public:
{ {
return m_Function; return m_Function;
} }
const uint8_t * FunctionEnd() const
{
return m_FunctionEnd;
}
const MD5Digest & Hash() const const MD5Digest & Hash() const
{ {
return m_Hash; return m_Hash;
@ -59,7 +55,6 @@ private:
uint32_t m_EnterPC; uint32_t m_EnterPC;
uint32_t m_MinPC; uint32_t m_MinPC;
uint32_t m_MaxPC; uint32_t m_MaxPC;
uint8_t * m_FunctionEnd;
MD5Digest m_Hash; MD5Digest m_Hash;
Func m_Function; Func m_Function;

View File

@ -10,8 +10,6 @@ CJumpInfo::CJumpInfo(CCodeBlock & CodeBlock) :
TargetPC = (uint32_t)-1; TargetPC = (uint32_t)-1;
JumpPC = (uint32_t)-1; JumpPC = (uint32_t)-1;
BranchLabel = ""; BranchLabel = "";
LinkLocation = nullptr;
LinkLocation2 = nullptr;
FallThrough = false; FallThrough = false;
PermLoop = false; PermLoop = false;
DoneDelaySlot = false; DoneDelaySlot = false;

View File

@ -9,8 +9,8 @@ struct CJumpInfo
uint32_t TargetPC; uint32_t TargetPC;
uint32_t JumpPC; uint32_t JumpPC;
std::string BranchLabel; std::string BranchLabel;
uint32_t * LinkLocation; asmjit::Label LinkLocation;
uint32_t * LinkLocation2; asmjit::Label LinkLocation2;
bool FallThrough; bool FallThrough;
bool PermLoop; bool PermLoop;
bool DoneDelaySlot; bool DoneDelaySlot;

View File

@ -76,7 +76,7 @@ bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bo
return true; return true;
} }
m_CodeBlock.Log("%s: Block EnterPC: %X Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, m_CodeBlock.VAddrEnter(), Section->m_SectionID, m_Test, Section->m_Test, Section->m_CompiledLocation); m_CodeBlock.Log("%s: Block EnterPC: %X Section ID %d Test: %X Section Test: %X ", __FUNCTION__, m_CodeBlock.VAddrEnter(), Section->m_SectionID, m_Test, Section->m_Test);
bool bFirstParent = true; bool bFirstParent = true;
CRegInfo RegEnter(m_CodeBlock, m_CodeBlock.RecompilerOps()->Assembler()); CRegInfo RegEnter(m_CodeBlock, m_CodeBlock.RecompilerOps()->Assembler());
@ -84,10 +84,10 @@ bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bo
{ {
CCodeSection * Parent = *iter; CCodeSection * Parent = *iter;
m_CodeBlock.Log("%s: Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); m_CodeBlock.Log("%s: Parent Section ID %d Test: %X Section Test: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test);
if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == nullptr) && Parent->m_InLoop) if (Parent->m_Test != m_Test && (m_EnterSection != Section || !Parent->m_EnterLabel.isValid()) && Parent->m_InLoop)
{ {
m_CodeBlock.Log("%s: Ignore Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test, Parent->m_CompiledLocation); m_CodeBlock.Log("%s: Ignore Parent Section ID %d Test: %X Section Test: %X", __FUNCTION__, Parent->m_SectionID, m_Test, Parent->m_Test);
bSkipedSection = true; bSkipedSection = true;
continue; continue;
} }

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, *g_RecompPos); CCodeBlock CodeBlock(m_MMU, PROGRAM_COUNTER);
if (!CodeBlock.Compile()) if (!CodeBlock.Compile())
{ {
return nullptr; return nullptr;
@ -385,6 +385,8 @@ CCompiledFunc * CRecompiler::CompileCode()
ShowMemUsed(); ShowMemUsed();
} }
uint32_t CodeLen = CodeBlock.Finilize(*g_RecompPos);
*g_RecompPos += CodeLen;
LogCodeBlock(CodeBlock); LogCodeBlock(CodeBlock);
CCompiledFunc * Func = new CCompiledFunc(CodeBlock); CCompiledFunc * Func = new CCompiledFunc(CodeBlock);
@ -403,7 +405,7 @@ CCompiledFunc * CRecompiler::CompileCode()
WriteTrace(TraceRecompiler, TraceDebug, "Info->Function() = %X", Func->Function()); WriteTrace(TraceRecompiler, TraceDebug, "Info->Function() = %X", Func->Function());
std::string dumpline; std::string dumpline;
uint32_t start_address = (uint32_t)(Func->Function()) & ~1; uint32_t start_address = (uint32_t)(Func->Function()) & ~1;
for (uint8_t * ptr = (uint8_t *)start_address; ptr < CodeBlock.CompiledLocationEnd(); ptr++) for (uint8_t * ptr = (uint8_t *)start_address, * ptr_end = ((uint8_t *)start_address) + CodeLen; ptr < ptr_end; ptr++)
{ {
if (dumpline.empty()) if (dumpline.empty())
{ {

View File

@ -350,7 +350,7 @@ public:
{ {
return m_RegWorkingSet.RegInStack(Reg, Format); return m_RegWorkingSet.RegInStack(Reg, Format);
} }
CX86Ops::x86FpuValues StackPosition(int32_t Reg) const asmjit::x86::St & StackPosition(int32_t Reg)
{ {
return m_RegWorkingSet.StackPosition(Reg); return m_RegWorkingSet.StackPosition(Reg);
} }
@ -441,7 +441,7 @@ private:
void LW_KnownAddress(const asmjit::x86::Gp & Reg, uint32_t VAddr); void LW_KnownAddress(const asmjit::x86::Gp & Reg, uint32_t VAddr);
void LW(bool ResultSigned, bool bRecordLLBit); void LW(bool ResultSigned, bool bRecordLLBit);
void SW(bool bCheckLLbit); void SW(bool bCheckLLbit);
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo & ExitRegSet, ExitReason Reason, bool CompileNow, void (CX86Ops::*x86Jmp)(const char * Label, uint32_t Value)); void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo & ExitRegSet, ExitReason Reason, bool CompileNow, void (CX86Ops::*x86Jmp)(const char * LabelName, asmjit::Label & JumpLabel));
void ResetMemoryStack(); void ResetMemoryStack();
EXIT_LIST m_ExitInfo; EXIT_LIST m_ExitInfo;

View File

@ -45,6 +45,37 @@ asmjit::x86::Gp GetX86RegFromIndex(x86RegIndex Index)
return x86Reg_Unknown; return x86Reg_Unknown;
} }
x86RegFpuIndex GetIndexFromX86FpuReg(const asmjit::x86::St & Reg)
{
if (Reg == asmjit::x86::st0) { return x86RegFpuIndex_ST0; }
if (Reg == asmjit::x86::st1) { return x86RegFpuIndex_ST1; }
if (Reg == asmjit::x86::st2) { return x86RegFpuIndex_ST2; }
if (Reg == asmjit::x86::st3) { return x86RegFpuIndex_ST3; }
if (Reg == asmjit::x86::st4) { return x86RegFpuIndex_ST4; }
if (Reg == asmjit::x86::st5) { return x86RegFpuIndex_ST5; }
if (Reg == asmjit::x86::st6) { return x86RegFpuIndex_ST6; }
if (Reg == asmjit::x86::st7) { return x86RegFpuIndex_ST7; }
g_Notify->BreakPoint(__FILE__, __LINE__);
return x86RegFpuIndex_ST0;
}
asmjit::x86::St GetX86FpuRegFromIndex(x86RegFpuIndex Index)
{
switch (Index)
{
case x86RegFpuIndex_ST0: return asmjit::x86::st0;
case x86RegFpuIndex_ST1: return asmjit::x86::st1;
case x86RegFpuIndex_ST2: return asmjit::x86::st2;
case x86RegFpuIndex_ST3: return asmjit::x86::st3;
case x86RegFpuIndex_ST4: return asmjit::x86::st4;
case x86RegFpuIndex_ST5: return asmjit::x86::st5;
case x86RegFpuIndex_ST6: return asmjit::x86::st6;
case x86RegFpuIndex_ST7: return asmjit::x86::st7;
}
g_Notify->BreakPoint(__FILE__, __LINE__);
return asmjit::x86::St();
}
CX86RegInfo::CX86RegInfo(CCodeBlock & CodeBlock, CX86Ops & Assembler) : CX86RegInfo::CX86RegInfo(CCodeBlock & CodeBlock, CX86Ops & Assembler) :
m_CodeBlock(CodeBlock), m_CodeBlock(CodeBlock),
m_Assembler(Assembler), m_Assembler(Assembler),
@ -62,7 +93,7 @@ CX86RegInfo::CX86RegInfo(CCodeBlock & CodeBlock, CX86Ops & Assembler) :
m_x86reg_Protected[i] = false; m_x86reg_Protected[i] = false;
m_x86reg_MapOrder[i] = 0; m_x86reg_MapOrder[i] = 0;
} }
for (int32_t i = 0, n = sizeof(m_x86fpu_MappedTo) / sizeof(m_x86fpu_MappedTo[0]); i < n; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
m_x86fpu_MappedTo[i] = -1; m_x86fpu_MappedTo[i] = -1;
m_x86fpu_State[i] = FPU_Unknown; m_x86fpu_State[i] = FPU_Unknown;
@ -137,7 +168,7 @@ bool CX86RegInfo::operator==(const CX86RegInfo & right) const
return false; return false;
} }
for (count = 0; count < 8; count++) for (count = 0; count < x86RegFpuIndex_Size; count++)
{ {
if (m_x86fpu_MappedTo[count] != right.m_x86fpu_MappedTo[count]) if (m_x86fpu_MappedTo[count] != right.m_x86fpu_MappedTo[count])
{ {
@ -181,7 +212,7 @@ void CX86RegInfo::BeforeCallDirect(void)
} }
m_InBeforeCallDirect = true; m_InBeforeCallDirect = true;
UnMap_AllFPRs(); UnMap_AllFPRs();
m_Assembler.Pushad(); m_Assembler.pushad();
} }
void CX86RegInfo::AfterCallDirect(void) void CX86RegInfo::AfterCallDirect(void)
@ -191,7 +222,7 @@ void CX86RegInfo::AfterCallDirect(void)
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
m_InBeforeCallDirect = false; m_InBeforeCallDirect = false;
m_Assembler.Popad(); m_Assembler.popad();
SetRoundingModel(CRegInfo::RoundUnknown); SetRoundingModel(CRegInfo::RoundUnknown);
} }
@ -207,7 +238,7 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
m_Assembler.fpuStoreControl(&m_fpuControl, "m_fpuControl"); m_Assembler.fpuStoreControl(&m_fpuControl, "m_fpuControl");
asmjit::x86::Gp reg = Map_TempReg(x86Reg_Unknown, -1, false, false); asmjit::x86::Gp reg = Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(reg, &m_fpuControl, "m_fpuControl"); m_Assembler.MoveVariableToX86reg(reg, &m_fpuControl, "m_fpuControl");
m_Assembler.AndConstToX86Reg(reg, 0xF3FF); m_Assembler.and_(reg, 0xF3FF);
if (RoundMethod == RoundDefault) if (RoundMethod == RoundDefault)
{ {
@ -224,12 +255,12 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
m_Assembler.MoveVariableToX86reg(RoundReg, &g_Reg->m_RoundingModel, "m_RoundingModel"); m_Assembler.MoveVariableToX86reg(RoundReg, &g_Reg->m_RoundingModel, "m_RoundingModel");
m_Assembler.MoveVariableDispToX86Reg(RoundReg, (void *)&msRound[0], "msRound", RoundReg, CX86Ops::Multip_x4); m_Assembler.MoveVariableDispToX86Reg(RoundReg, (void *)&msRound[0], "msRound", RoundReg, CX86Ops::Multip_x4);
m_Assembler.ShiftLeftSignImmed(RoundReg, 2); m_Assembler.shl(RoundReg, 2);
m_Assembler.OrX86RegToX86Reg(reg, RoundReg); m_Assembler.or_(reg, RoundReg);
#else #else
asmjit::x86::Gp RoundReg = Map_TempReg(x86Reg_Unknown, -1, false, false); asmjit::x86::Gp RoundReg = Map_TempReg(x86Reg_Unknown, -1, false, false);
m_Assembler.MoveVariableToX86reg(RoundReg, _RoundingModel, "_RoundingModel"); m_Assembler.MoveVariableToX86reg(RoundReg, _RoundingModel, "_RoundingModel");
m_Assembler.OrX86RegToX86Reg(reg, RoundReg); m_Assembler.or_(reg, RoundReg);
#endif #endif
SetX86Protected(GetIndexFromX86Reg(RoundReg), false); SetX86Protected(GetIndexFromX86Reg(RoundReg), false);
} }
@ -237,10 +268,10 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
{ {
switch (RoundMethod) switch (RoundMethod)
{ {
case RoundTruncate: m_Assembler.OrConstToX86Reg(reg, 0x0C00); break; case RoundTruncate: m_Assembler.or_(reg, 0x0C00); break;
case RoundNearest: m_Assembler.OrConstToX86Reg(reg, 0x0000); break; case RoundNearest: m_Assembler.or_(reg, 0x0000); break;
case RoundDown: m_Assembler.OrConstToX86Reg(reg, 0x0400); break; case RoundDown: m_Assembler.or_(reg, 0x0400); break;
case RoundUp: m_Assembler.OrConstToX86Reg(reg, 0x0800); break; case RoundUp: m_Assembler.or_(reg, 0x0800); break;
default: default:
g_Notify->DisplayError("Unknown rounding model"); g_Notify->DisplayError("Unknown rounding model");
} }
@ -253,7 +284,7 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
void CX86RegInfo::ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel) void CX86RegInfo::ChangeFPURegFormat(int32_t Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel)
{ {
for (uint32_t i = 0; i < 8; i++) for (uint32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] != Reg) if (m_x86fpu_MappedTo[i] != Reg)
{ {
@ -308,7 +339,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
{ {
if ((Reg & 1) != 0) if ((Reg & 1) != 0)
{ {
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] == (Reg - 1)) if (m_x86fpu_MappedTo[i] == (Reg - 1))
{ {
@ -322,7 +353,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
} }
if ((RegToLoad & 1) != 0) if ((RegToLoad & 1) != 0)
{ {
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] == (RegToLoad - 1)) if (m_x86fpu_MappedTo[i] == (RegToLoad - 1))
{ {
@ -339,7 +370,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
if (Reg == RegToLoad) if (Reg == RegToLoad)
{ {
// If different format then unmap original register from stack // If different format then unmap original register from stack
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] != Reg) if (m_x86fpu_MappedTo[i] != Reg)
{ {
@ -355,7 +386,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
else else
{ {
// If different format then unmap original register from stack // If different format then unmap original register from stack
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] != Reg) if (m_x86fpu_MappedTo[i] != Reg)
{ {
@ -388,14 +419,14 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
} }
else else
{ {
CX86Ops::x86FpuValues RegPos = CX86Ops::x86_ST_Unknown; int32_t RegPos = -1;
for (uint32_t z = 0; z < 8; z++) for (uint32_t z = 0; z < x86RegFpuIndex_Size; z++)
{ {
if (m_x86fpu_MappedTo[z] != Reg) if (m_x86fpu_MappedTo[z] != Reg)
{ {
continue; continue;
} }
RegPos = (CX86Ops::x86FpuValues)z; RegPos = z;
break; break;
} }
@ -403,7 +434,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
{ {
return; return;
} }
CX86Ops::x86FpuValues StackPos = StackPosition(Reg); asmjit::x86::St StackPos = StackPosition(Reg);
FpuRoundingModel(RegPos) = FpuRoundingModel(StackTopPos()); FpuRoundingModel(RegPos) = FpuRoundingModel(StackTopPos());
m_x86fpu_MappedTo[RegPos] = m_x86fpu_MappedTo[StackTopPos()]; m_x86fpu_MappedTo[RegPos] = m_x86fpu_MappedTo[StackTopPos()];
@ -412,7 +443,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
m_CodeBlock.Log(" regcache: allocate ST(%d) to %s", StackPos, CRegName::FPR[m_x86fpu_MappedTo[RegPos]]); m_CodeBlock.Log(" regcache: allocate ST(%d) to %s", StackPos, CRegName::FPR[m_x86fpu_MappedTo[RegPos]]);
m_CodeBlock.Log(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]); m_CodeBlock.Log(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]);
m_Assembler.fpuExchange(StackPos); m_Assembler.fxch(StackPos);
FpuRoundingModel(StackTopPos()) = RoundDefault; FpuRoundingModel(StackTopPos()) = RoundDefault;
m_x86fpu_MappedTo[StackTopPos()] = Reg; m_x86fpu_MappedTo[StackTopPos()] = Reg;
@ -423,7 +454,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
else else
{ {
UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true); UnMap_FPR(m_x86fpu_MappedTo[(StackTopPos() - 1) & 7], true);
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] == RegToLoad) if (m_x86fpu_MappedTo[i] == RegToLoad)
{ {
@ -465,16 +496,27 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
} }
} }
CX86Ops::x86FpuValues CX86RegInfo::StackPosition(int32_t Reg) const asmjit::x86::St & CX86RegInfo::StackPosition(int32_t Reg)
{ {
for (int32_t i = 0; i < 8; i++) static const asmjit::x86::St StRegs[] =
{
asmjit::x86::st0,
asmjit::x86::st1,
asmjit::x86::st2,
asmjit::x86::st3,
asmjit::x86::st4,
asmjit::x86::st5,
asmjit::x86::st6,
asmjit::x86::st7,
};
for (int32_t i = 0, n = sizeof(StRegs) / sizeof(StRegs[0]); i < n; i++)
{ {
if (m_x86fpu_MappedTo[i] == Reg) if (m_x86fpu_MappedTo[i] == Reg)
{ {
return (CX86Ops::x86FpuValues)((i - StackTopPos()) & 7); return StRegs[((i - StackTopPos()) & 7)];
} }
} }
return CX86Ops::x86_ST_Unknown; return asmjit::x86::St();
} }
asmjit::x86::Gp CX86RegInfo::FreeX86Reg() asmjit::x86::Gp CX86RegInfo::FreeX86Reg()
@ -699,7 +741,7 @@ asmjit::x86::Gp CX86RegInfo::Map_MemoryStack(asmjit::x86::Gp Reg, bool bMapRegis
m_CodeBlock.Log(" regcache: change allocation of memory stack from %s to %s", CX86Ops::x86_Name(CurrentMap), CX86Ops::x86_Name(Reg)); m_CodeBlock.Log(" regcache: change allocation of memory stack from %s to %s", CX86Ops::x86_Name(CurrentMap), CX86Ops::x86_Name(Reg));
SetX86Mapped(GetIndexFromX86Reg(Reg), CX86RegInfo::Stack_Mapped); SetX86Mapped(GetIndexFromX86Reg(Reg), CX86RegInfo::Stack_Mapped);
SetX86Mapped(GetIndexFromX86Reg(CurrentMap), CX86RegInfo::NotMapped); SetX86Mapped(GetIndexFromX86Reg(CurrentMap), CX86RegInfo::NotMapped);
m_Assembler.MoveX86RegToX86Reg(Reg, CurrentMap); m_Assembler.mov(Reg, CurrentMap);
} }
else else
{ {
@ -769,7 +811,7 @@ void CX86RegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
{ {
if (MipsReg != MipsRegToLoad) if (MipsReg != MipsRegToLoad)
{ {
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsRegToLoad)); m_Assembler.mov(Reg, GetMipsRegMapLo(MipsRegToLoad));
} }
} }
else else
@ -779,7 +821,7 @@ void CX86RegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
} }
else if (MipsRegToLoad == 0) else if (MipsRegToLoad == 0)
{ {
m_Assembler.XorX86RegToX86Reg(Reg, Reg); m_Assembler.xor_(Reg, Reg);
} }
SetX86Mapped(RegIndex, GPR_Mapped); SetX86Mapped(RegIndex, GPR_Mapped);
SetX86Protected(RegIndex, true); SetX86Protected(RegIndex, true);
@ -870,24 +912,24 @@ void CX86RegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
{ {
if (IsSigned(MipsRegToLoad)) if (IsSigned(MipsRegToLoad))
{ {
m_Assembler.MoveX86RegToX86Reg(x86Hi, GetMipsRegMapLo(MipsRegToLoad)); m_Assembler.mov(x86Hi, GetMipsRegMapLo(MipsRegToLoad));
m_Assembler.ShiftRightSignImmed(x86Hi, 31); m_Assembler.sar(x86Hi, 31);
} }
else else
{ {
m_Assembler.XorX86RegToX86Reg(x86Hi, x86Hi); m_Assembler.xor_(x86Hi, x86Hi);
} }
if (MipsReg != MipsRegToLoad) if (MipsReg != MipsRegToLoad)
{ {
m_Assembler.MoveX86RegToX86Reg(x86lo, GetMipsRegMapLo(MipsRegToLoad)); m_Assembler.mov(x86lo, GetMipsRegMapLo(MipsRegToLoad));
} }
} }
else else
{ {
if (MipsReg != MipsRegToLoad) if (MipsReg != MipsRegToLoad)
{ {
m_Assembler.MoveX86RegToX86Reg(x86Hi, GetMipsRegMapHi(MipsRegToLoad)); m_Assembler.mov(x86Hi, GetMipsRegMapHi(MipsRegToLoad));
m_Assembler.MoveX86RegToX86Reg(x86lo, GetMipsRegMapLo(MipsRegToLoad)); m_Assembler.mov(x86lo, GetMipsRegMapLo(MipsRegToLoad));
} }
} }
} }
@ -914,8 +956,8 @@ void CX86RegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
} }
else if (MipsRegToLoad == 0) else if (MipsRegToLoad == 0)
{ {
m_Assembler.XorX86RegToX86Reg(x86Hi, x86Hi); m_Assembler.xor_(x86Hi, x86Hi);
m_Assembler.XorX86RegToX86Reg(x86lo, x86lo); m_Assembler.xor_(x86lo, x86lo);
} }
SetX86Mapped(GetIndexFromX86Reg(x86Hi), GPR_Mapped); SetX86Mapped(GetIndexFromX86Reg(x86Hi), GPR_Mapped);
SetX86Mapped(GetIndexFromX86Reg(x86lo), GPR_Mapped); SetX86Mapped(GetIndexFromX86Reg(x86lo), GPR_Mapped);
@ -1030,7 +1072,7 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
SetX86Mapped(GetIndexFromX86Reg(NewReg), GPR_Mapped); SetX86Mapped(GetIndexFromX86Reg(NewReg), GPR_Mapped);
SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg))); SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg)));
SetMipsRegMapLo(i, NewReg); SetMipsRegMapLo(i, NewReg);
m_Assembler.MoveX86RegToX86Reg(NewReg, Reg); m_Assembler.mov(NewReg, Reg);
if (MipsReg == (int32_t)i && !LoadHiWord) if (MipsReg == (int32_t)i && !LoadHiWord)
{ {
MipsReg = -1; MipsReg = -1;
@ -1048,7 +1090,7 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
SetX86Mapped(GetIndexFromX86Reg(NewReg), GPR_Mapped); SetX86Mapped(GetIndexFromX86Reg(NewReg), GPR_Mapped);
SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg))); SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg)));
SetMipsRegMapHi(i, NewReg); SetMipsRegMapHi(i, NewReg);
m_Assembler.MoveX86RegToX86Reg(NewReg, Reg); m_Assembler.mov(NewReg, Reg);
if (MipsReg == (int32_t)i && LoadHiWord) if (MipsReg == (int32_t)i && LoadHiWord)
{ {
MipsReg = -1; MipsReg = -1;
@ -1075,12 +1117,12 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
{ {
if (Is64Bit(MipsReg)) if (Is64Bit(MipsReg))
{ {
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapHi(MipsReg)); m_Assembler.mov(Reg, GetMipsRegMapHi(MipsReg));
} }
else if (IsSigned(MipsReg)) else if (IsSigned(MipsReg))
{ {
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsReg)); m_Assembler.mov(Reg, GetMipsRegMapLo(MipsReg));
m_Assembler.ShiftRightSignImmed(Reg, 31); m_Assembler.sar(Reg, 31);
} }
else else
{ {
@ -1107,7 +1149,7 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
} }
else if (IsMapped(MipsReg)) else if (IsMapped(MipsReg))
{ {
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsReg)); m_Assembler.mov(Reg, GetMipsRegMapLo(MipsReg));
} }
else else
{ {
@ -1166,7 +1208,7 @@ void CX86RegInfo::ResetX86Protection()
bool CX86RegInfo::RegInStack(int32_t Reg, FPU_STATE Format) bool CX86RegInfo::RegInStack(int32_t Reg, FPU_STATE Format)
{ {
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] == Reg) if (m_x86fpu_MappedTo[i] == Reg)
{ {
@ -1192,7 +1234,7 @@ void CX86RegInfo::UnMap_AllFPRs()
} }
// See if any more registers mapped // See if any more registers mapped
int32_t StartPos = StackTopPos(); int32_t StartPos = StackTopPos();
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[(StartPos + i) & 7] != -1) if (m_x86fpu_MappedTo[(StartPos + i) & 7] != -1)
{ {
@ -1213,7 +1255,7 @@ void CX86RegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue)
{ {
return; return;
} }
for (int32_t i = 0; i < 8; i++) for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
{ {
if (m_x86fpu_MappedTo[i] != Reg) if (m_x86fpu_MappedTo[i] != Reg)
{ {
@ -1244,7 +1286,7 @@ void CX86RegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue)
m_x86fpu_MappedTo[i] = MappedTo; m_x86fpu_MappedTo[i] = MappedTo;
m_x86fpu_State[i] = RegState; m_x86fpu_State[i] = RegState;
m_x86fpu_StateChanged[i] = Changed; m_x86fpu_StateChanged[i] = Changed;
m_Assembler.fpuExchange((CX86Ops::x86FpuValues)((i - StackTopPos()) & 7)); m_Assembler.fxch(GetX86FpuRegFromIndex((x86RegFpuIndex)((i - StackTopPos()) & 7)));
} }
} }
@ -1284,7 +1326,7 @@ void CX86RegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue)
} }
else else
{ {
m_Assembler.fpuFree((CX86Ops::x86FpuValues)((i - StackTopPos()) & 7)); m_Assembler.ffree(GetX86FpuRegFromIndex((x86RegFpuIndex)((i - StackTopPos()) & 7)));
FpuRoundingModel(i) = RoundDefault; FpuRoundingModel(i) = RoundDefault;
m_x86fpu_MappedTo[i] = -1; m_x86fpu_MappedTo[i] = -1;
m_x86fpu_State[i] = FPU_Unknown; m_x86fpu_State[i] = FPU_Unknown;
@ -1364,7 +1406,7 @@ void CX86RegInfo::UnMap_GPR(uint32_t Reg, bool WriteBackValue)
{ {
if (IsSigned(Reg)) if (IsSigned(Reg))
{ {
m_Assembler.ShiftRightSignImmed(GetMipsRegMapLo(Reg), 31); m_Assembler.sar(GetMipsRegMapLo(Reg), 31);
m_Assembler.MoveX86regToVariable(&_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg], GetMipsRegMapLo(Reg)); m_Assembler.MoveX86regToVariable(&_GPR[Reg].UW[1], CRegName::GPR_Hi[Reg], GetMipsRegMapLo(Reg));
} }
else else
@ -1510,7 +1552,7 @@ void CX86RegInfo::WriteBackRegisters()
{ {
if (!bEdiZero && (!GetMipsRegLo(count) || !(GetMipsRegLo(count) & 0x80000000))) if (!bEdiZero && (!GetMipsRegLo(count) || !(GetMipsRegLo(count) & 0x80000000)))
{ {
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi); m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
bEdiZero = true; bEdiZero = true;
} }
if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000)) if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000))
@ -1534,7 +1576,7 @@ void CX86RegInfo::WriteBackRegisters()
{ {
if (!bEdiZero) if (!bEdiZero)
{ {
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi); m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
bEdiZero = true; bEdiZero = true;
} }
} }
@ -1564,7 +1606,7 @@ void CX86RegInfo::WriteBackRegisters()
{ {
if (!bEdiZero) if (!bEdiZero)
{ {
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi); m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
bEdiZero = true; bEdiZero = true;
} }
m_Assembler.MoveX86regToVariable(&_GPR[count].UW[1], CRegName::GPR_Hi[count], asmjit::x86::edi); m_Assembler.MoveX86regToVariable(&_GPR[count].UW[1], CRegName::GPR_Hi[count], asmjit::x86::edi);
@ -1576,7 +1618,7 @@ void CX86RegInfo::WriteBackRegisters()
{ {
if (!bEdiZero) if (!bEdiZero)
{ {
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi); m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
bEdiZero = true; bEdiZero = true;
} }
} }
@ -1591,7 +1633,7 @@ void CX86RegInfo::WriteBackRegisters()
case CX86RegInfo::STATE_CONST_64: case CX86RegInfo::STATE_CONST_64:
if (GetMipsRegLo(count) == 0 || GetMipsRegHi(count) == 0) if (GetMipsRegLo(count) == 0 || GetMipsRegHi(count) == 0)
{ {
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi); m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
bEdiZero = true; bEdiZero = true;
} }
if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF) if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF)

View File

@ -23,6 +23,22 @@ enum x86RegIndex
x86RegIndex GetIndexFromX86Reg(const asmjit::x86::Gp & Reg); x86RegIndex GetIndexFromX86Reg(const asmjit::x86::Gp & Reg);
asmjit::x86::Gp GetX86RegFromIndex(x86RegIndex Index); asmjit::x86::Gp GetX86RegFromIndex(x86RegIndex Index);
enum x86RegFpuIndex
{
x86RegFpuIndex_ST0,
x86RegFpuIndex_ST1,
x86RegFpuIndex_ST2,
x86RegFpuIndex_ST3,
x86RegFpuIndex_ST4,
x86RegFpuIndex_ST5,
x86RegFpuIndex_ST6,
x86RegFpuIndex_ST7,
x86RegFpuIndex_Size,
};
x86RegFpuIndex GetIndexFromX86FpuReg(const asmjit::x86::St & Reg);
asmjit::x86::St GetX86FpuRegFromIndex(x86RegFpuIndex Index);
class CX86RegInfo : class CX86RegInfo :
public CRegBase, public CRegBase,
private CDebugSettings, private CDebugSettings,
@ -68,7 +84,7 @@ public:
bool RegInStack(int32_t Reg, FPU_STATE Format); bool RegInStack(int32_t Reg, FPU_STATE Format);
void UnMap_AllFPRs(); void UnMap_AllFPRs();
void UnMap_FPR(int32_t Reg, bool WriteBackValue); void UnMap_FPR(int32_t Reg, bool WriteBackValue);
CX86Ops::x86FpuValues StackPosition(int32_t Reg); const asmjit::x86::St & StackPosition(int32_t Reg);
asmjit::x86::Gp FreeX86Reg(); asmjit::x86::Gp FreeX86Reg();
asmjit::x86::Gp Free8BitX86Reg(); asmjit::x86::Gp Free8BitX86Reg();
@ -163,10 +179,10 @@ private:
// FPU // FPU
int32_t m_Stack_TopPos; int32_t m_Stack_TopPos;
int32_t m_x86fpu_MappedTo[8]; int32_t m_x86fpu_MappedTo[x86RegFpuIndex_Size];
FPU_STATE m_x86fpu_State[8]; FPU_STATE m_x86fpu_State[x86RegFpuIndex_Size];
bool m_x86fpu_StateChanged[8]; bool m_x86fpu_StateChanged[x86RegFpuIndex_Size];
FPU_ROUND m_x86fpu_RoundingModel[8]; FPU_ROUND m_x86fpu_RoundingModel[x86RegFpuIndex_Size];
static uint32_t m_fpuControl; static uint32_t m_fpuControl;
bool m_InBeforeCallDirect; bool m_InBeforeCallDirect;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86)
#include <Project64-core/N64System/Recompiler/asmjit.h> #include <Project64-core/N64System/Recompiler/asmjit.h>
#include <map>
#include <string>
#if !defined(_MSC_VER) && !defined(_Printf_format_string_) #if !defined(_MSC_VER) && !defined(_Printf_format_string_)
#define _Printf_format_string_ #define _Printf_format_string_
@ -10,21 +12,11 @@ class CCodeBlock;
static constexpr asmjit::x86::Gp x86Reg_Unknown = asmjit::x86::Gp(); static constexpr asmjit::x86::Gp x86Reg_Unknown = asmjit::x86::Gp();
class CX86Ops class CX86Ops :
public asmjit::x86::Assembler,
public asmjit::Logger
{ {
public: public:
enum x86FpuValues
{
x86_ST_Unknown = -1,
x86_ST0 = 0,
x86_ST1 = 1,
x86_ST2 = 2,
x86_ST3 = 3,
x86_ST4 = 4,
x86_ST5 = 5,
x86_ST6 = 6,
x86_ST7 = 7
};
enum Multipler enum Multipler
{ {
@ -35,231 +27,82 @@ public:
}; };
static const char * x86_Name(const asmjit::x86::Gp & Reg); static const char * x86_Name(const asmjit::x86::Gp & Reg);
static const char * x86_ByteName(const asmjit::x86::Gp & Reg);
static const char * x86_HalfName(const asmjit::x86::Gp & Reg);
static const char * fpu_Name(x86FpuValues Reg);
CX86Ops(CCodeBlock & CodeBlock); CX86Ops(CCodeBlock & CodeBlock);
// Logging functions
void WriteX86Comment(const char * Comment);
void WriteX86Label(const char * Label);
void AdcConstToVariable(void * Variable, const char * VariableName, uint8_t Constant);
void AdcConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void AdcVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void AdcVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void AdcX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void AddConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void AddConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void AddConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const, bool NeedCarry = false); void AddConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void AddVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void AddVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void AddX86regToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg);
void AddX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void AndConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void AndConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void AndConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void AndVariableToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void AndVariableToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void AndVariableDispToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName, const asmjit::x86::Gp & AddrReg, Multipler Multiply); void AndVariableDispToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName, const asmjit::x86::Gp & AddrReg, Multipler Multiply);
void AndX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void X86HardBreakPoint(); void X86HardBreakPoint();
void X86BreakPoint(const char * FileName, int32_t LineNumber); void X86BreakPoint(const char * FileName, int32_t LineNumber);
void CallFunc(uint32_t FunctPtr, const char * FunctName); void CallFunc(uint32_t FunctPtr, const char * FunctName);
void CallThis(uint32_t ThisPtr, uint32_t FunctPtr, char * FunctName, uint32_t StackSize); void CallThis(uint32_t ThisPtr, uint32_t FunctPtr, char * FunctName, uint32_t StackSize);
void CompConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void CompConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void CompConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const); void CompConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void CompConstToX86regPointer(const asmjit::x86::Gp & Reg, uint32_t Const);
void CompX86regToVariable(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void CompX86regToVariable(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void CompX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source); void JaeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void DecX86reg(const asmjit::x86::Gp & Reg); void JaLabel(const char * LabelName, asmjit::Label & JumpLabel);
void DivX86reg(const asmjit::x86::Gp & Reg); void JbLabel(const char * LabelName, asmjit::Label & JumpLabel);
void idivX86reg(const asmjit::x86::Gp & Reg); void JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel);
void imulX86reg(const asmjit::x86::Gp & Reg); void JeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void IncX86reg(const asmjit::x86::Gp & Reg); void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaeLabel8(const char * Label, uint8_t Value); void JgLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaeLabel32(const char * Label, uint32_t Value); void JleLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaLabel8(const char * Label, uint8_t Value); void JlLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaLabel32(const char * Label, uint32_t Value); void JmpLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JbLabel8(const char * Label, uint8_t Value); void JneLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JbLabel32(const char * Label, uint32_t Value); void JnsLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JecxzLabel8(const char * Label, uint8_t Value); void JnzLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JeLabel8(const char * Label, uint8_t Value); void JoLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JeLabel32(const char * Label, uint32_t Value); void JsLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JgeLabel8(const char * Label, uint8_t Value); void JzLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JgeLabel32(const char * Label, uint32_t Value);
void JgLabel8(const char * Label, uint8_t Value);
void JgLabel32(const char * Label, uint32_t Value);
void JleLabel8(const char * Label, uint8_t Value);
void JleLabel32(const char * Label, uint32_t Value);
void JlLabel8(const char * Label, uint8_t Value);
void JlLabel32(const char * Label, uint32_t Value);
void JmpDirectReg(const asmjit::x86::Gp & Reg);
void JmpIndirectLabel32(const char * Label, uint32_t location);
void JmpIndirectReg(const asmjit::x86::Gp & Reg);
void JmpLabel8(const char * Label, uint8_t Value);
void JmpLabel32(const char * Label, uint32_t Value);
void JneLabel8(const char * Label, uint8_t Value);
void JneLabel32(const char * Label, uint32_t Value);
void JnsLabel8(const char * Label, uint8_t Value);
void JnsLabel32(const char * Label, uint32_t Value);
void JnzLabel8(const char * Label, uint8_t Value);
void JnzLabel32(const char * Label, uint32_t Value);
void JoLabel32(const char * Label, uint32_t Value);
void JsLabel32(const char * Label, uint32_t Value);
void JzLabel8(const char * Label, uint8_t Value);
void JzLabel32(const char * Label, uint32_t Value);
void LeaRegReg(const asmjit::x86::Gp & RegDest, const asmjit::x86::Gp & RegSrc, uint32_t Const, Multipler multiplier);
void LeaRegReg2(const asmjit::x86::Gp & RegDest, const asmjit::x86::Gp & RegSrc, const asmjit::x86::Gp & RegSrc2, Multipler multiplier);
void LeaSourceAndOffset(const asmjit::x86::Gp & x86DestReg, const asmjit::x86::Gp & x86SourceReg, int32_t offset);
void MoveConstByteToVariable(void * Variable, const char * VariableName, uint8_t Const); void MoveConstByteToVariable(void * Variable, const char * VariableName, uint8_t Const);
void MoveConstByteToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, uint8_t Const);
void MoveConstHalfToVariable(void * Variable, const char * VariableName, uint16_t Const); void MoveConstHalfToVariable(void * Variable, const char * VariableName, uint16_t Const);
void MoveConstHalfToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, uint16_t Const);
void MoveConstToMemoryDisp(const asmjit::x86::Gp & AddrReg, uint32_t Disp, uint32_t Const);
void MoveConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void MoveConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void MoveConstToX86Pointer(const asmjit::x86::Gp & X86Pointer, uint32_t Const);
void MoveConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const); void MoveConstToX86reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void MoveConstToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, uint32_t Const);
void MoveSxByteX86regPointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2);
void MoveSxHalfX86regPointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2);
void MoveSxVariableToX86regByte(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void MoveSxVariableToX86regByte(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void MoveSxVariableToX86regHalf(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void MoveSxVariableToX86regHalf(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void MoveVariableDispToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName, const asmjit::x86::Gp & AddrReg, Multipler Multiplier); void MoveVariableDispToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName, const asmjit::x86::Gp & AddrReg, Multipler Multiplier);
void MoveVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void MoveVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void MoveX86PointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & X86Pointer);
void MoveX86PointerToX86regDisp(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & X86Pointer, uint8_t Disp);
void MoveX86regByteToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg); void MoveX86regByteToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg);
void MoveX86regByteToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, const asmjit::x86::Gp & Reg);
void MoveX86regHalfToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg); void MoveX86regHalfToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg);
void MoveX86regHalfToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, const asmjit::x86::Gp & Reg);
void MoveX86regPointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2);
void MoveX86regPointerToX86regDisp8(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, uint8_t offset);
void MoveX86regToMemory(const asmjit::x86::Gp & AddrReg, uint32_t Disp, const asmjit::x86::Gp & Reg);
void MoveX86regToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg); void MoveX86regToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg);
void MoveX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void MoveX86regToX86Pointer(const asmjit::x86::Gp & X86Pointer, const asmjit::x86::Gp & Reg);
void MoveX86regToX86regPointer(const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2, const asmjit::x86::Gp & Reg);
void MoveZxByteX86regPointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2);
void MoveZxHalfX86regPointerToX86reg(const asmjit::x86::Gp & Reg, const asmjit::x86::Gp & AddrReg1, const asmjit::x86::Gp & AddrReg2);
void MoveZxVariableToX86regByte(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void MoveZxVariableToX86regByte(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void MoveZxVariableToX86regHalf(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void MoveZxVariableToX86regHalf(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void MulX86reg(const asmjit::x86::Gp & Reg);
void NotX86Reg(const asmjit::x86::Gp & Reg);
void OrConstToVariable(void * Variable, const char * VariableName, uint32_t Const); void OrConstToVariable(void * Variable, const char * VariableName, uint32_t Const);
void OrConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void OrVariableToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void OrVariableToX86Reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void OrX86RegToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg); void OrX86RegToVariable(void * Variable, const char * VariableName, const asmjit::x86::Gp & Reg);
void OrX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void Push(const asmjit::x86::Gp & Reg);
void Pushad();
void PushImm32(uint32_t Value);
void PushImm32(const char * String, uint32_t Value); void PushImm32(const char * String, uint32_t Value);
void Pop(const asmjit::x86::Gp & Reg);
void Popad();
void Ret();
void Seta(const asmjit::x86::Gp & Reg);
void Setae(const asmjit::x86::Gp & Reg);
void SetaVariable(void * Variable, const char * VariableName); void SetaVariable(void * Variable, const char * VariableName);
void Setb(const asmjit::x86::Gp & Reg);
void SetbVariable(void * Variable, const char * VariableName); void SetbVariable(void * Variable, const char * VariableName);
void Setg(const asmjit::x86::Gp & Reg);
void SetgVariable(void * Variable, const char * VariableName); void SetgVariable(void * Variable, const char * VariableName);
void Setl(const asmjit::x86::Gp & Reg);
void SetlVariable(void * Variable, const char * VariableName); void SetlVariable(void * Variable, const char * VariableName);
void Setz(const asmjit::x86::Gp & Reg);
void Setnz(const asmjit::x86::Gp & Reg);
void ShiftLeftDouble(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void ShiftLeftDoubleImmed(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source, uint8_t Immediate);
void ShiftLeftSign(const asmjit::x86::Gp & Reg);
void ShiftLeftSignImmed(const asmjit::x86::Gp & Reg, uint8_t Immediate);
void ShiftRightDouble(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void ShiftRightDoubleImmed(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source, uint8_t Immediate);
void ShiftRightSign(const asmjit::x86::Gp & Reg);
void ShiftRightSignImmed(const asmjit::x86::Gp & Reg, uint8_t Immediate);
void ShiftRightUnsign(const asmjit::x86::Gp & Reg);
void ShiftRightUnsignImmed(const asmjit::x86::Gp & Reg, uint8_t Immediate);
void SbbConstFromX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void SbbVariableFromX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void SbbVariableFromX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void SbbX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName); void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName);
void SubConstFromX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void SubVariableFromX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void SubVariableFromX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void SubX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void TestConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void TestVariable(void * Variable, const char * VariableName, uint32_t Const); void TestVariable(void * Variable, const char * VariableName, uint32_t Const);
void TestX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void TestX86ByteRegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
void XorConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
void XorX86RegToX86Reg(const asmjit::x86::Gp & Source, const asmjit::x86::Gp & Destination);
void XorVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); void XorVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName);
void fpuAbs();
void fpuAddDword(void * Variable, const char * VariableName);
void fpuAddDwordRegPointer(const asmjit::x86::Gp & x86Pointer);
void fpuAddQword(void * Variable, const char * VariableName);
void fpuAddQwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuAddReg(x86FpuValues Reg);
void fpuAddRegPop(int32_t & StackPos, x86FpuValues Reg);
void fpuComDword(void * Variable, const char * VariableName, bool Pop);
void fpuComDwordRegPointer(const asmjit::x86::Gp & X86Pointer, bool Pop);
void fpuComQword(void * Variable, const char * VariableName, bool Pop);
void fpuComQwordRegPointer(const asmjit::x86::Gp & X86Pointer, bool Pop);
void fpuComReg(x86FpuValues Reg, bool Pop);
void fpuDivDword(void * Variable, const char * VariableName);
void fpuDivDwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuDivQword(void * Variable, const char * VariableName);
void fpuDivQwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuDivReg(x86FpuValues Reg);
void fpuDivRegPop(x86FpuValues Reg);
void fpuExchange(x86FpuValues Reg);
void fpuFree(x86FpuValues Reg);
void fpuDecStack(int32_t & StackPos);
void fpuIncStack(int32_t & StackPos); void fpuIncStack(int32_t & StackPos);
void fpuLoadControl(void * Variable, const char * VariableName); void fpuLoadControl(void * Variable, const char * VariableName);
void fpuLoadDword(int32_t & StackPos, void * Variable, const char * VariableName);
void fpuLoadDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadDwordFromN64Mem(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadInt32bFromN64Mem(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadIntegerDword(int32_t & StackPos, void * Variable, const char * VariableName);
void fpuLoadIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadIntegerQword(int32_t & StackPos, void * Variable, const char * VariableName);
void fpuLoadIntegerQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadIntegerQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadQword(int32_t & StackPos, void * Variable, const char * VariableName);
void fpuLoadQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg);
void fpuLoadQwordFromN64Mem(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadReg(int32_t & StackPos, const asmjit::x86::St & Reg);
void fpuLoadReg(int32_t & StackPos, x86FpuValues Reg);
void fpuMulDword(void * Variable, const char * VariableName);
void fpuMulDwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuMulQword(void * Variable, const char * VariableName);
void fpuMulQwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuMulReg(x86FpuValues Reg);
void fpuMulRegPop(x86FpuValues Reg);
void fpuNeg();
void fpuRound();
void fpuSqrt();
void fpuStoreControl(void * Variable, const char * VariableName); void fpuStoreControl(void * Variable, const char * VariableName);
void fpuStoreDword(int32_t & StackPos, void * Variable, const char * VariableName, bool pop);
void fpuStoreDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop); void fpuStoreDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop);
void fpuStoreDwordToN64Mem(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool Pop);
void fpuStoreIntegerDword(int32_t & StackPos, void * Variable, const char * VariableName, bool pop);
void fpuStoreIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop); void fpuStoreIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop);
void fpuStoreIntegerQword(int32_t & StackPos, void * Variable, const char * VariableName, bool pop);
void fpuStoreIntegerQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop); void fpuStoreIntegerQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop);
void fpuStoreQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop); void fpuStoreQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg, bool pop);
void fpuStoreStatus();
void fpuSubDword(void * Variable, const char * VariableName);
void fpuSubDwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuSubDwordReverse(void * Variable, const char * VariableName);
void fpuSubQword(void * Variable, const char * VariableName);
void fpuSubQwordRegPointer(const asmjit::x86::Gp & X86Pointer);
void fpuSubQwordReverse(void * Variable, const char * VariableName);
void fpuSubReg(x86FpuValues Reg);
void fpuSubRegPop(x86FpuValues Reg);
static bool Is8BitReg(const asmjit::x86::Gp & Reg); static bool Is8BitReg(const asmjit::x86::Gp & Reg);
static uint8_t CalcMultiplyCode(Multipler Multiply);
static uint32_t GetAddressOf(int32_t value, ...); static uint32_t GetAddressOf(int32_t value, ...);
void SetJump32(uint32_t * Loc, uint32_t * JumpLoc);
void SetJump8(uint8_t * Loc, uint8_t * JumpLoc);
private: private:
CX86Ops(void); CX86Ops(void);
CX86Ops(const CX86Ops &); CX86Ops(const CX86Ops &);
@ -287,14 +130,16 @@ private:
}; };
static x86Reg RegValue(const asmjit::x86::Gp & Reg); static x86Reg RegValue(const asmjit::x86::Gp & Reg);
void CodeLog(_Printf_format_string_ const char * Text, ...); asmjit::Error _log(const char* data, size_t size) noexcept;
void AddSymbol(const char * SymbolKey, const char * SymbolValue);
void RemoveSymbol(const char * SymbolKey);
std::string VariableSymbol(void * Variable) const;
static void BreakPointNotification(const char * FileName, int32_t LineNumber); static void BreakPointNotification(const char * FileName, int32_t LineNumber);
static char m_fpupop[2][2];
void AddCode8(uint8_t value);
void AddCode16(uint16_t value);
void AddCode32(uint32_t value);
typedef std::map<std::string, std::string> SymbolMap;
SymbolMap m_Symbols;
CCodeBlock & m_CodeBlock; CCodeBlock & m_CodeBlock;
}; };

View File

@ -288,6 +288,9 @@
<ClInclude Include="TraceModulesProject64.h" /> <ClInclude Include="TraceModulesProject64.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\3rdParty\asmjit\asmjit.vcxproj">
<Project>{a72c9f08-ebb4-443d-9982-da21ae8b367d}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj"> <ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj">
<Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project> <Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project>
</ProjectReference> </ProjectReference>