Core: Change recompiler to use asmjit
This commit is contained in:
parent
2a6d3cd519
commit
8e94b3086b
|
@ -38,6 +38,24 @@
|
|||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<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-end.h" />
|
||||
<ClInclude Include="src\asmjit\asmjit.h" />
|
||||
|
@ -63,6 +81,7 @@
|
|||
<ClInclude Include="src\asmjit\core\errorhandler.h" />
|
||||
<ClInclude Include="src\asmjit\core\features.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\funcargscontext_p.h" />
|
||||
<ClInclude Include="src\asmjit\core\globals.h" />
|
||||
|
@ -99,7 +118,6 @@
|
|||
<ClInclude Include="src\asmjit\x86\x86compiler.h" />
|
||||
<ClInclude Include="src\asmjit\x86\x86emithelper_p.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\x86func_p.h" />
|
||||
<ClInclude Include="src\asmjit\x86\x86globals.h" />
|
||||
|
@ -111,6 +129,17 @@
|
|||
<ClInclude Include="src\asmjit\x86\x86rapass_p.h" />
|
||||
</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\assembler.cpp" />
|
||||
<ClCompile Include="src\asmjit\core\builder.cpp" />
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
<Filter Include="Source Files\x86">
|
||||
<UniqueIdentifier>{6b84aaac-0a23-40c3-a433-b295187c29f6}</UniqueIdentifier>
|
||||
</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>
|
||||
<ClInclude Include="src\asmjit\asmjit.h">
|
||||
|
@ -210,9 +216,6 @@
|
|||
<ClInclude Include="src\asmjit\x86\x86emitter.h">
|
||||
<Filter>Header Files\x86</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\asmjit\x86\x86features.h">
|
||||
<Filter>Header Files\x86</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\asmjit\x86\x86formatter_p.h">
|
||||
<Filter>Header Files\x86</Filter>
|
||||
</ClInclude>
|
||||
|
@ -240,6 +243,63 @@
|
|||
<ClInclude Include="src\asmjit\x86\x86rapass_p.h">
|
||||
<Filter>Header Files\x86</Filter>
|
||||
</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>
|
||||
<ClCompile Include="src\asmjit\core\archtraits.cpp">
|
||||
|
@ -383,5 +443,38 @@
|
|||
<ClCompile Include="src\asmjit\x86\x86rapass.cpp">
|
||||
<Filter>Source Files\x86</Filter>
|
||||
</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>
|
||||
</Project>
|
|
@ -13,16 +13,19 @@
|
|||
extern "C" void __clear_cache_android(uint8_t * begin, uint8_t * end);
|
||||
#endif
|
||||
|
||||
CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * CompiledLocation) :
|
||||
CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter) :
|
||||
m_MMU(MMU),
|
||||
m_VAddrEnter(VAddrEnter),
|
||||
m_VAddrFirst(VAddrEnter),
|
||||
m_VAddrLast(VAddrEnter),
|
||||
m_CompiledLocation(CompiledLocation),
|
||||
m_CompiledLocation(nullptr),
|
||||
m_EnterSection(nullptr),
|
||||
m_RecompilerOps(nullptr),
|
||||
m_Test(1)
|
||||
{
|
||||
m_Environment = asmjit::Environment::host();
|
||||
m_CodeHolder.init(m_Environment);
|
||||
m_CodeHolder.setErrorHandler(this);
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
// 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)
|
||||
|
@ -50,7 +53,7 @@ CCodeBlock::CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * Compi
|
|||
|
||||
m_Sections.push_back(baseSection);
|
||||
baseSection->AddParent(nullptr);
|
||||
baseSection->m_CompiledLocation = (uint8_t *)-1;
|
||||
baseSection->m_EnterLabel = asmjit::Label(1);
|
||||
baseSection->m_Cont.JumpPC = VAddrEnter;
|
||||
baseSection->m_Cont.FallThrough = true;
|
||||
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()
|
||||
{
|
||||
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();
|
||||
if (g_System->bLinkBlocks())
|
||||
{
|
||||
|
@ -877,7 +874,6 @@ bool CCodeBlock::Compile()
|
|||
}
|
||||
}
|
||||
m_RecompilerOps->CompileExitCode();
|
||||
m_CompiledLocationEnd = *g_RecompPos;
|
||||
|
||||
uint32_t BlockSize = (VAddrLast() - VAddrFirst()) + 4;
|
||||
uint8_t * BlockPtr = m_MMU.MemoryPtr(VAddrFirst(), BlockSize, true);
|
||||
|
@ -887,12 +883,35 @@ bool CCodeBlock::Compile()
|
|||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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 next_test = m_Test;
|
||||
|
@ -923,3 +942,8 @@ void CCodeBlock::Log(_Printf_format_string_ const char * Text, ...)
|
|||
#pragma warning(pop)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void CCodeBlock::handleError(asmjit::Error /*err*/, const char * /*message*/, asmjit::BaseEmitter * /*origin*/)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
|
|
@ -9,14 +9,20 @@
|
|||
|
||||
class CMipsMemoryVM;
|
||||
|
||||
class CCodeBlock
|
||||
class CCodeBlock :
|
||||
public asmjit::ErrorHandler
|
||||
{
|
||||
public:
|
||||
CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter, uint8_t * CompiledLocation);
|
||||
CCodeBlock(CMipsMemoryVM & MMU, uint32_t VAddrEnter);
|
||||
~CCodeBlock();
|
||||
|
||||
bool Compile();
|
||||
uint32_t Finilize(uint8_t * CompiledLocation);
|
||||
|
||||
asmjit::CodeHolder & CodeHolder(void)
|
||||
{
|
||||
return m_CodeHolder;
|
||||
}
|
||||
uint32_t VAddrEnter() const
|
||||
{
|
||||
return m_VAddrEnter;
|
||||
|
@ -33,10 +39,6 @@ public:
|
|||
{
|
||||
return m_CompiledLocation;
|
||||
}
|
||||
uint8_t * CompiledLocationEnd() const
|
||||
{
|
||||
return m_CompiledLocationEnd;
|
||||
}
|
||||
int32_t NoOfSections() const
|
||||
{
|
||||
return (int32_t)m_Sections.size() - 1;
|
||||
|
@ -101,12 +103,14 @@ private:
|
|||
void LogSectionInfo();
|
||||
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);
|
||||
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_VAddrFirst;
|
||||
uint32_t m_VAddrLast;
|
||||
uint8_t * m_CompiledLocation;
|
||||
uint8_t * m_CompiledLocationEnd;
|
||||
|
||||
typedef std::map<uint32_t, CCodeSection *> SectionMap;
|
||||
typedef std::list<CCodeSection *> SectionList;
|
||||
|
|
|
@ -24,7 +24,6 @@ CCodeSection::CCodeSection(CCodeBlock & CodeBlock, uint32_t EnterPC, uint32_t ID
|
|||
m_LinkAllowed(LinkAllowed),
|
||||
m_Test(0),
|
||||
m_Test2(0),
|
||||
m_CompiledLocation(nullptr),
|
||||
m_InLoop(false),
|
||||
m_DelaySlot(false),
|
||||
m_RecompilerOps(CodeBlock.RecompilerOps()),
|
||||
|
@ -48,7 +47,7 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (JumpInfo[i]->LinkLocation == nullptr &&
|
||||
if (!JumpInfo[i]->LinkLocation.isValid() &&
|
||||
JumpInfo[i]->FallThrough == false)
|
||||
{
|
||||
JumpInfo[i]->TargetPC = (uint32_t)-1;
|
||||
|
@ -75,7 +74,7 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
{
|
||||
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])
|
||||
{
|
||||
|
@ -107,11 +106,11 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (m_Cont.LinkLocation == nullptr && m_Cont.FallThrough == false)
|
||||
if (!m_Cont.LinkLocation.isValid() && m_Cont.FallThrough == false)
|
||||
{
|
||||
m_ContinueSection = nullptr;
|
||||
}
|
||||
if (m_Jump.LinkLocation == nullptr && m_Jump.FallThrough == false)
|
||||
if (!m_Jump.LinkLocation.isValid() && m_Jump.FallThrough == false)
|
||||
{
|
||||
m_JumpSection = nullptr;
|
||||
}
|
||||
|
@ -135,7 +134,7 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (TargetSection[i]->m_CompiledLocation != nullptr)
|
||||
if (TargetSection[i]->m_EnterLabel.isValid())
|
||||
{
|
||||
JumpInfo[i]->FallThrough = false;
|
||||
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++)
|
||||
{
|
||||
CCodeSection * Parent = *iter;
|
||||
|
||||
if (Parent->m_CompiledLocation != nullptr)
|
||||
if (Parent->m_EnterLabel.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -224,10 +222,9 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
}
|
||||
}
|
||||
|
||||
//CodeLog("Section %d",m_SectionID);
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (JumpInfo[i]->LinkLocation == nullptr)
|
||||
if (!JumpInfo[i]->LinkLocation.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -242,7 +239,7 @@ void CCodeSection::GenerateSectionLinkage()
|
|||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
if (TargetSection[i]->m_CompiledLocation == nullptr)
|
||||
if (!TargetSection[i]->m_EnterLabel.isValid())
|
||||
{
|
||||
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++)
|
||||
{
|
||||
CCodeSection * Parent = *iter;
|
||||
if (Parent->m_CompiledLocation != nullptr)
|
||||
if (Parent->m_EnterLabel.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -325,7 +322,7 @@ bool CCodeSection::ParentContinue()
|
|||
|
||||
bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
||||
{
|
||||
if (m_CompiledLocation != nullptr)
|
||||
if (m_EnterLabel.isValid())
|
||||
{
|
||||
if (m_Test == Test)
|
||||
{
|
||||
|
@ -347,7 +344,8 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
|||
{
|
||||
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->SetCurrentPC(m_EnterPC);
|
||||
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;
|
||||
if (CodeSection->m_ContinueSection == this)
|
||||
{
|
||||
if (CodeSection->m_CompiledLocation)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
CodeSection->m_ContinueSection = nullptr;
|
||||
}
|
||||
|
||||
if (CodeSection->m_JumpSection == this)
|
||||
{
|
||||
if (CodeSection->m_CompiledLocation)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (IgnoreIfCompiled && Parent->m_CompiledLocation != nullptr)
|
||||
if (IgnoreIfCompiled && Parent->m_EnterLabel.isValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1103,7 +1093,6 @@ void CCodeSection::DisplaySectionInformation()
|
|||
{
|
||||
m_CodeBlock.Log("End PC: 0x%X", m_EndPC);
|
||||
}
|
||||
m_CodeBlock.Log("CompiledLocation: 0x%X", m_CompiledLocation);
|
||||
if (g_System->bLinkBlocks() && !m_ParentSection.empty())
|
||||
{
|
||||
stdstr ParentList;
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
bool m_LinkAllowed;
|
||||
uint32_t m_Test;
|
||||
uint32_t m_Test2;
|
||||
uint8_t * m_CompiledLocation;
|
||||
asmjit::Label m_EnterLabel;
|
||||
bool m_InLoop;
|
||||
bool m_DelaySlot;
|
||||
CRecompilerOps *& m_RecompilerOps;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
CExitInfo::CExitInfo(CCodeBlock & CodeBlock) :
|
||||
ID(0),
|
||||
TargetPC(0),
|
||||
JumpLoc(nullptr),
|
||||
ExitRegSet(CodeBlock, CodeBlock.RecompilerOps()->Assembler())
|
||||
{
|
||||
JumpLabel = CodeBlock.RecompilerOps()->Assembler().newLabel();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ struct CExitInfo
|
|||
CRegInfo ExitRegSet;
|
||||
ExitReason Reason;
|
||||
PIPELINE_STAGE PipelineStage;
|
||||
uint32_t * JumpLoc; // 32-bit jump
|
||||
asmjit::Label JumpLabel;
|
||||
};
|
||||
|
||||
typedef std::list<CExitInfo> EXIT_LIST;
|
||||
|
|
|
@ -7,7 +7,6 @@ CCompiledFunc::CCompiledFunc(const CCodeBlock & CodeBlock) :
|
|||
m_MaxPC(CodeBlock.VAddrLast()),
|
||||
m_Hash(CodeBlock.Hash()),
|
||||
m_Function((Func)CodeBlock.CompiledLocation()),
|
||||
m_FunctionEnd(CodeBlock.CompiledLocationEnd()),
|
||||
m_Next(nullptr)
|
||||
{
|
||||
m_MemContents[0] = CodeBlock.MemContents(0);
|
||||
|
|
|
@ -24,10 +24,6 @@ public:
|
|||
{
|
||||
return m_Function;
|
||||
}
|
||||
const uint8_t * FunctionEnd() const
|
||||
{
|
||||
return m_FunctionEnd;
|
||||
}
|
||||
const MD5Digest & Hash() const
|
||||
{
|
||||
return m_Hash;
|
||||
|
@ -59,7 +55,6 @@ private:
|
|||
uint32_t m_EnterPC;
|
||||
uint32_t m_MinPC;
|
||||
uint32_t m_MaxPC;
|
||||
uint8_t * m_FunctionEnd;
|
||||
|
||||
MD5Digest m_Hash;
|
||||
Func m_Function;
|
||||
|
|
|
@ -10,8 +10,6 @@ CJumpInfo::CJumpInfo(CCodeBlock & CodeBlock) :
|
|||
TargetPC = (uint32_t)-1;
|
||||
JumpPC = (uint32_t)-1;
|
||||
BranchLabel = "";
|
||||
LinkLocation = nullptr;
|
||||
LinkLocation2 = nullptr;
|
||||
FallThrough = false;
|
||||
PermLoop = false;
|
||||
DoneDelaySlot = false;
|
||||
|
|
|
@ -9,8 +9,8 @@ struct CJumpInfo
|
|||
uint32_t TargetPC;
|
||||
uint32_t JumpPC;
|
||||
std::string BranchLabel;
|
||||
uint32_t * LinkLocation;
|
||||
uint32_t * LinkLocation2;
|
||||
asmjit::Label LinkLocation;
|
||||
asmjit::Label LinkLocation2;
|
||||
bool FallThrough;
|
||||
bool PermLoop;
|
||||
bool DoneDelaySlot;
|
||||
|
|
|
@ -76,7 +76,7 @@ bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bo
|
|||
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;
|
||||
CRegInfo RegEnter(m_CodeBlock, m_CodeBlock.RecompilerOps()->Assembler());
|
||||
|
@ -84,10 +84,10 @@ bool LoopAnalysis::SetupEnterSection(CCodeSection * Section, bool & bChanged, bo
|
|||
{
|
||||
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);
|
||||
if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == nullptr) && Parent->m_InLoop)
|
||||
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_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;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ CCompiledFunc * CRecompiler::CompileCode()
|
|||
CheckRecompMem();
|
||||
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())
|
||||
{
|
||||
return nullptr;
|
||||
|
@ -385,6 +385,8 @@ CCompiledFunc * CRecompiler::CompileCode()
|
|||
ShowMemUsed();
|
||||
}
|
||||
|
||||
uint32_t CodeLen = CodeBlock.Finilize(*g_RecompPos);
|
||||
*g_RecompPos += CodeLen;
|
||||
LogCodeBlock(CodeBlock);
|
||||
|
||||
CCompiledFunc * Func = new CCompiledFunc(CodeBlock);
|
||||
|
@ -403,7 +405,7 @@ CCompiledFunc * CRecompiler::CompileCode()
|
|||
WriteTrace(TraceRecompiler, TraceDebug, "Info->Function() = %X", Func->Function());
|
||||
std::string dumpline;
|
||||
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())
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -350,7 +350,7 @@ public:
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ private:
|
|||
void LW_KnownAddress(const asmjit::x86::Gp & Reg, uint32_t VAddr);
|
||||
void LW(bool ResultSigned, bool bRecordLLBit);
|
||||
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();
|
||||
|
||||
EXIT_LIST m_ExitInfo;
|
||||
|
|
|
@ -45,6 +45,37 @@ asmjit::x86::Gp GetX86RegFromIndex(x86RegIndex Index)
|
|||
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) :
|
||||
m_CodeBlock(CodeBlock),
|
||||
m_Assembler(Assembler),
|
||||
|
@ -62,7 +93,7 @@ CX86RegInfo::CX86RegInfo(CCodeBlock & CodeBlock, CX86Ops & Assembler) :
|
|||
m_x86reg_Protected[i] = false;
|
||||
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_State[i] = FPU_Unknown;
|
||||
|
@ -137,7 +168,7 @@ bool CX86RegInfo::operator==(const CX86RegInfo & right) const
|
|||
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])
|
||||
{
|
||||
|
@ -181,7 +212,7 @@ void CX86RegInfo::BeforeCallDirect(void)
|
|||
}
|
||||
m_InBeforeCallDirect = true;
|
||||
UnMap_AllFPRs();
|
||||
m_Assembler.Pushad();
|
||||
m_Assembler.pushad();
|
||||
}
|
||||
|
||||
void CX86RegInfo::AfterCallDirect(void)
|
||||
|
@ -191,7 +222,7 @@ void CX86RegInfo::AfterCallDirect(void)
|
|||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
m_InBeforeCallDirect = false;
|
||||
m_Assembler.Popad();
|
||||
m_Assembler.popad();
|
||||
SetRoundingModel(CRegInfo::RoundUnknown);
|
||||
}
|
||||
|
||||
|
@ -207,7 +238,7 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
|
|||
m_Assembler.fpuStoreControl(&m_fpuControl, "m_fpuControl");
|
||||
asmjit::x86::Gp reg = Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
m_Assembler.MoveVariableToX86reg(reg, &m_fpuControl, "m_fpuControl");
|
||||
m_Assembler.AndConstToX86Reg(reg, 0xF3FF);
|
||||
m_Assembler.and_(reg, 0xF3FF);
|
||||
|
||||
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.MoveVariableDispToX86Reg(RoundReg, (void *)&msRound[0], "msRound", RoundReg, CX86Ops::Multip_x4);
|
||||
|
||||
m_Assembler.ShiftLeftSignImmed(RoundReg, 2);
|
||||
m_Assembler.OrX86RegToX86Reg(reg, RoundReg);
|
||||
m_Assembler.shl(RoundReg, 2);
|
||||
m_Assembler.or_(reg, RoundReg);
|
||||
#else
|
||||
asmjit::x86::Gp RoundReg = Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
m_Assembler.MoveVariableToX86reg(RoundReg, _RoundingModel, "_RoundingModel");
|
||||
m_Assembler.OrX86RegToX86Reg(reg, RoundReg);
|
||||
m_Assembler.or_(reg, RoundReg);
|
||||
#endif
|
||||
SetX86Protected(GetIndexFromX86Reg(RoundReg), false);
|
||||
}
|
||||
|
@ -237,10 +268,10 @@ void CX86RegInfo::FixRoundModel(FPU_ROUND RoundMethod)
|
|||
{
|
||||
switch (RoundMethod)
|
||||
{
|
||||
case RoundTruncate: m_Assembler.OrConstToX86Reg(reg, 0x0C00); break;
|
||||
case RoundNearest: m_Assembler.OrConstToX86Reg(reg, 0x0000); break;
|
||||
case RoundDown: m_Assembler.OrConstToX86Reg(reg, 0x0400); break;
|
||||
case RoundUp: m_Assembler.OrConstToX86Reg(reg, 0x0800); break;
|
||||
case RoundTruncate: m_Assembler.or_(reg, 0x0C00); break;
|
||||
case RoundNearest: m_Assembler.or_(reg, 0x0000); break;
|
||||
case RoundDown: m_Assembler.or_(reg, 0x0400); break;
|
||||
case RoundUp: m_Assembler.or_(reg, 0x0800); break;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
for (uint32_t i = 0; i < x86RegFpuIndex_Size; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
for (int32_t i = 0; i < 8; i++)
|
||||
for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
for (int32_t i = 0; i < 8; i++)
|
||||
for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
|
@ -355,7 +386,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
|
|||
else
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -388,14 +419,14 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
|
|||
}
|
||||
else
|
||||
{
|
||||
CX86Ops::x86FpuValues RegPos = CX86Ops::x86_ST_Unknown;
|
||||
for (uint32_t z = 0; z < 8; z++)
|
||||
int32_t RegPos = -1;
|
||||
for (uint32_t z = 0; z < x86RegFpuIndex_Size; z++)
|
||||
{
|
||||
if (m_x86fpu_MappedTo[z] != Reg)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
RegPos = (CX86Ops::x86FpuValues)z;
|
||||
RegPos = z;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -403,7 +434,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
|
|||
{
|
||||
return;
|
||||
}
|
||||
CX86Ops::x86FpuValues StackPos = StackPosition(Reg);
|
||||
asmjit::x86::St StackPos = StackPosition(Reg);
|
||||
|
||||
FpuRoundingModel(RegPos) = FpuRoundingModel(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(0) to %s", CRegName::FPR[Reg]);
|
||||
|
||||
m_Assembler.fpuExchange(StackPos);
|
||||
m_Assembler.fxch(StackPos);
|
||||
|
||||
FpuRoundingModel(StackTopPos()) = RoundDefault;
|
||||
m_x86fpu_MappedTo[StackTopPos()] = Reg;
|
||||
|
@ -423,7 +454,7 @@ void CX86RegInfo::Load_FPR_ToTop(int32_t Reg, int32_t RegToLoad, FPU_STATE Forma
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
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()
|
||||
|
@ -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));
|
||||
SetX86Mapped(GetIndexFromX86Reg(Reg), CX86RegInfo::Stack_Mapped);
|
||||
SetX86Mapped(GetIndexFromX86Reg(CurrentMap), CX86RegInfo::NotMapped);
|
||||
m_Assembler.MoveX86RegToX86Reg(Reg, CurrentMap);
|
||||
m_Assembler.mov(Reg, CurrentMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -769,7 +811,7 @@ void CX86RegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
|
|||
{
|
||||
if (MipsReg != MipsRegToLoad)
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsRegToLoad));
|
||||
m_Assembler.mov(Reg, GetMipsRegMapLo(MipsRegToLoad));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -779,7 +821,7 @@ void CX86RegInfo::Map_GPR_32bit(int32_t MipsReg, bool SignValue, int32_t MipsReg
|
|||
}
|
||||
else if (MipsRegToLoad == 0)
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(Reg, Reg);
|
||||
m_Assembler.xor_(Reg, Reg);
|
||||
}
|
||||
SetX86Mapped(RegIndex, GPR_Mapped);
|
||||
SetX86Protected(RegIndex, true);
|
||||
|
@ -870,24 +912,24 @@ void CX86RegInfo::Map_GPR_64bit(int32_t MipsReg, int32_t MipsRegToLoad)
|
|||
{
|
||||
if (IsSigned(MipsRegToLoad))
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(x86Hi, GetMipsRegMapLo(MipsRegToLoad));
|
||||
m_Assembler.ShiftRightSignImmed(x86Hi, 31);
|
||||
m_Assembler.mov(x86Hi, GetMipsRegMapLo(MipsRegToLoad));
|
||||
m_Assembler.sar(x86Hi, 31);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(x86Hi, x86Hi);
|
||||
m_Assembler.xor_(x86Hi, x86Hi);
|
||||
}
|
||||
if (MipsReg != MipsRegToLoad)
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(x86lo, GetMipsRegMapLo(MipsRegToLoad));
|
||||
m_Assembler.mov(x86lo, GetMipsRegMapLo(MipsRegToLoad));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MipsReg != MipsRegToLoad)
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(x86Hi, GetMipsRegMapHi(MipsRegToLoad));
|
||||
m_Assembler.MoveX86RegToX86Reg(x86lo, GetMipsRegMapLo(MipsRegToLoad));
|
||||
m_Assembler.mov(x86Hi, GetMipsRegMapHi(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)
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(x86Hi, x86Hi);
|
||||
m_Assembler.XorX86RegToX86Reg(x86lo, x86lo);
|
||||
m_Assembler.xor_(x86Hi, x86Hi);
|
||||
m_Assembler.xor_(x86lo, x86lo);
|
||||
}
|
||||
SetX86Mapped(GetIndexFromX86Reg(x86Hi), 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);
|
||||
SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg)));
|
||||
SetMipsRegMapLo(i, NewReg);
|
||||
m_Assembler.MoveX86RegToX86Reg(NewReg, Reg);
|
||||
m_Assembler.mov(NewReg, Reg);
|
||||
if (MipsReg == (int32_t)i && !LoadHiWord)
|
||||
{
|
||||
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);
|
||||
SetX86MapOrder(GetIndexFromX86Reg(NewReg), GetX86MapOrder(GetIndexFromX86Reg(Reg)));
|
||||
SetMipsRegMapHi(i, NewReg);
|
||||
m_Assembler.MoveX86RegToX86Reg(NewReg, Reg);
|
||||
m_Assembler.mov(NewReg, Reg);
|
||||
if (MipsReg == (int32_t)i && LoadHiWord)
|
||||
{
|
||||
MipsReg = -1;
|
||||
|
@ -1075,12 +1117,12 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
|
|||
{
|
||||
if (Is64Bit(MipsReg))
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapHi(MipsReg));
|
||||
m_Assembler.mov(Reg, GetMipsRegMapHi(MipsReg));
|
||||
}
|
||||
else if (IsSigned(MipsReg))
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsReg));
|
||||
m_Assembler.ShiftRightSignImmed(Reg, 31);
|
||||
m_Assembler.mov(Reg, GetMipsRegMapLo(MipsReg));
|
||||
m_Assembler.sar(Reg, 31);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1107,7 +1149,7 @@ asmjit::x86::Gp CX86RegInfo::Map_TempReg(asmjit::x86::Gp Reg, int32_t MipsReg, b
|
|||
}
|
||||
else if (IsMapped(MipsReg))
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(Reg, GetMipsRegMapLo(MipsReg));
|
||||
m_Assembler.mov(Reg, GetMipsRegMapLo(MipsReg));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1166,7 +1208,7 @@ void CX86RegInfo::ResetX86Protection()
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -1192,7 +1234,7 @@ void CX86RegInfo::UnMap_AllFPRs()
|
|||
}
|
||||
// See if any more registers mapped
|
||||
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)
|
||||
{
|
||||
|
@ -1213,7 +1255,7 @@ void CX86RegInfo::UnMap_FPR(int32_t Reg, bool WriteBackValue)
|
|||
{
|
||||
return;
|
||||
}
|
||||
for (int32_t i = 0; i < 8; i++)
|
||||
for (int32_t i = 0; i < x86RegFpuIndex_Size; i++)
|
||||
{
|
||||
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_State[i] = RegState;
|
||||
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
|
||||
{
|
||||
m_Assembler.fpuFree((CX86Ops::x86FpuValues)((i - StackTopPos()) & 7));
|
||||
m_Assembler.ffree(GetX86FpuRegFromIndex((x86RegFpuIndex)((i - StackTopPos()) & 7)));
|
||||
FpuRoundingModel(i) = RoundDefault;
|
||||
m_x86fpu_MappedTo[i] = -1;
|
||||
m_x86fpu_State[i] = FPU_Unknown;
|
||||
|
@ -1364,7 +1406,7 @@ void CX86RegInfo::UnMap_GPR(uint32_t Reg, bool WriteBackValue)
|
|||
{
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -1510,7 +1552,7 @@ void CX86RegInfo::WriteBackRegisters()
|
|||
{
|
||||
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;
|
||||
}
|
||||
if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000))
|
||||
|
@ -1534,7 +1576,7 @@ void CX86RegInfo::WriteBackRegisters()
|
|||
{
|
||||
if (!bEdiZero)
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi);
|
||||
m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
|
||||
bEdiZero = true;
|
||||
}
|
||||
}
|
||||
|
@ -1564,7 +1606,7 @@ void CX86RegInfo::WriteBackRegisters()
|
|||
{
|
||||
if (!bEdiZero)
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi);
|
||||
m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
|
||||
bEdiZero = true;
|
||||
}
|
||||
m_Assembler.MoveX86regToVariable(&_GPR[count].UW[1], CRegName::GPR_Hi[count], asmjit::x86::edi);
|
||||
|
@ -1576,7 +1618,7 @@ void CX86RegInfo::WriteBackRegisters()
|
|||
{
|
||||
if (!bEdiZero)
|
||||
{
|
||||
m_Assembler.XorX86RegToX86Reg(asmjit::x86::edi, asmjit::x86::edi);
|
||||
m_Assembler.xor_(asmjit::x86::edi, asmjit::x86::edi);
|
||||
bEdiZero = true;
|
||||
}
|
||||
}
|
||||
|
@ -1591,7 +1633,7 @@ void CX86RegInfo::WriteBackRegisters()
|
|||
case CX86RegInfo::STATE_CONST_64:
|
||||
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;
|
||||
}
|
||||
if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF)
|
||||
|
|
|
@ -23,6 +23,22 @@ enum x86RegIndex
|
|||
x86RegIndex GetIndexFromX86Reg(const asmjit::x86::Gp & Reg);
|
||||
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 :
|
||||
public CRegBase,
|
||||
private CDebugSettings,
|
||||
|
@ -68,7 +84,7 @@ public:
|
|||
bool RegInStack(int32_t Reg, FPU_STATE Format);
|
||||
void UnMap_AllFPRs();
|
||||
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 Free8BitX86Reg();
|
||||
|
@ -163,10 +179,10 @@ private:
|
|||
|
||||
// FPU
|
||||
int32_t m_Stack_TopPos;
|
||||
int32_t m_x86fpu_MappedTo[8];
|
||||
FPU_STATE m_x86fpu_State[8];
|
||||
bool m_x86fpu_StateChanged[8];
|
||||
FPU_ROUND m_x86fpu_RoundingModel[8];
|
||||
int32_t m_x86fpu_MappedTo[x86RegFpuIndex_Size];
|
||||
FPU_STATE m_x86fpu_State[x86RegFpuIndex_Size];
|
||||
bool m_x86fpu_StateChanged[x86RegFpuIndex_Size];
|
||||
FPU_ROUND m_x86fpu_RoundingModel[x86RegFpuIndex_Size];
|
||||
|
||||
static uint32_t m_fpuControl;
|
||||
bool m_InBeforeCallDirect;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#if defined(__i386__) || defined(_M_IX86)
|
||||
#include <Project64-core/N64System/Recompiler/asmjit.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(_Printf_format_string_)
|
||||
#define _Printf_format_string_
|
||||
|
@ -10,21 +12,11 @@ class CCodeBlock;
|
|||
|
||||
static constexpr asmjit::x86::Gp x86Reg_Unknown = asmjit::x86::Gp();
|
||||
|
||||
class CX86Ops
|
||||
class CX86Ops :
|
||||
public asmjit::x86::Assembler,
|
||||
public asmjit::Logger
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -35,231 +27,82 @@ public:
|
|||
};
|
||||
|
||||
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);
|
||||
|
||||
// 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 AdcX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
|
||||
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 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 AndConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
|
||||
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 AndX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
|
||||
void X86HardBreakPoint();
|
||||
void X86BreakPoint(const char * FileName, int32_t LineNumber);
|
||||
void CallFunc(uint32_t FunctPtr, const char * FunctName);
|
||||
void CallThis(uint32_t ThisPtr, uint32_t FunctPtr, char * FunctName, uint32_t StackSize);
|
||||
void CompConstToVariable(void * Variable, const char * VariableName, 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 CompX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
|
||||
void DecX86reg(const asmjit::x86::Gp & Reg);
|
||||
void DivX86reg(const asmjit::x86::Gp & Reg);
|
||||
void idivX86reg(const asmjit::x86::Gp & Reg);
|
||||
void imulX86reg(const asmjit::x86::Gp & Reg);
|
||||
void IncX86reg(const asmjit::x86::Gp & Reg);
|
||||
void JaeLabel8(const char * Label, uint8_t Value);
|
||||
void JaeLabel32(const char * Label, uint32_t Value);
|
||||
void JaLabel8(const char * Label, uint8_t Value);
|
||||
void JaLabel32(const char * Label, uint32_t Value);
|
||||
void JbLabel8(const char * Label, uint8_t Value);
|
||||
void JbLabel32(const char * Label, uint32_t Value);
|
||||
void JecxzLabel8(const char * Label, uint8_t Value);
|
||||
void JeLabel8(const char * Label, uint8_t Value);
|
||||
void JeLabel32(const char * Label, uint32_t Value);
|
||||
void JgeLabel8(const char * Label, uint8_t Value);
|
||||
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 JaeLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JaLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JbLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JeLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JgLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JleLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JlLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JmpLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JneLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JnsLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JnzLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JoLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JsLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
void JzLabel(const char * LabelName, asmjit::Label & JumpLabel);
|
||||
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 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 MoveConstToX86Pointer(const asmjit::x86::Gp & X86Pointer, 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 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 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 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 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 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 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 OrConstToX86Reg(const asmjit::x86::Gp & Reg, uint32_t Const);
|
||||
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 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 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 Setb(const asmjit::x86::Gp & Reg);
|
||||
void SetbVariable(void * Variable, const char * VariableName);
|
||||
void Setg(const asmjit::x86::Gp & Reg);
|
||||
void SetgVariable(void * Variable, const char * VariableName);
|
||||
void Setl(const asmjit::x86::Gp & Reg);
|
||||
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 SbbX86RegToX86Reg(const asmjit::x86::Gp & Destination, const asmjit::x86::Gp & Source);
|
||||
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 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 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 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 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 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 fpuLoadIntegerQword(int32_t & StackPos, void * Variable, const char * VariableName);
|
||||
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 fpuLoadQwordFromN64Mem(int32_t & StackPos, const asmjit::x86::Gp & 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 fpuLoadReg(int32_t & StackPos, const asmjit::x86::St & Reg);
|
||||
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 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 fpuStoreIntegerQword(int32_t & StackPos, void * Variable, const char * VariableName, 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 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 uint8_t CalcMultiplyCode(Multipler Multiply);
|
||||
static uint32_t GetAddressOf(int32_t value, ...);
|
||||
|
||||
void SetJump32(uint32_t * Loc, uint32_t * JumpLoc);
|
||||
void SetJump8(uint8_t * Loc, uint8_t * JumpLoc);
|
||||
|
||||
private:
|
||||
CX86Ops(void);
|
||||
CX86Ops(const CX86Ops &);
|
||||
|
@ -287,14 +130,16 @@ private:
|
|||
};
|
||||
|
||||
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 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -288,6 +288,9 @@
|
|||
<ClInclude Include="TraceModulesProject64.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\3rdParty\asmjit\asmjit.vcxproj">
|
||||
<Project>{a72c9f08-ebb4-443d-9982-da21ae8b367d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj">
|
||||
<Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project>
|
||||
</ProjectReference>
|
||||
|
|
Loading…
Reference in New Issue