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>
</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" />

View File

@ -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>

View File

@ -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__);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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())
{

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;
};

View File

@ -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>