Core: Handle bgezal ra in the recompiler

This commit is contained in:
zilmar 2022-12-05 14:09:03 +10:30
parent d35d2e6abe
commit 6b04b908bf
4 changed files with 52 additions and 3 deletions

View File

@ -85,6 +85,13 @@ void CCodeSection::GenerateSectionLinkage()
else if (TargetSection[i] == nullptr && JumpInfo[i]->FallThrough) else if (TargetSection[i] == nullptr && JumpInfo[i]->FallThrough)
{ {
m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1);
if (JumpInfo[i]->LinkAddress != (uint32_t)-1)
{
JumpInfo[i]->RegSet.UnMap_GPR(31, false);
JumpInfo[i]->RegSet.SetMipsRegLo(31, JumpInfo[i]->LinkAddress);
JumpInfo[i]->RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
JumpInfo[i]->LinkAddress = (uint32_t)-1;
}
m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason); m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason);
JumpInfo[i]->FallThrough = false; JumpInfo[i]->FallThrough = false;
} }
@ -99,6 +106,13 @@ void CCodeSection::GenerateSectionLinkage()
continue; continue;
} }
m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1);
if (JumpInfo[i]->LinkAddress != (uint32_t)-1)
{
JumpInfo[i]->RegSet.UnMap_GPR(31, false);
JumpInfo[i]->RegSet.SetMipsRegLo(31, JumpInfo[i]->LinkAddress);
JumpInfo[i]->RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
JumpInfo[i]->LinkAddress = (uint32_t)-1;
}
m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason); m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason);
//FreeSection(TargetSection[i],Section); //FreeSection(TargetSection[i],Section);
} }
@ -138,6 +152,13 @@ void CCodeSection::GenerateSectionLinkage()
{ {
JumpInfo[i]->FallThrough = false; JumpInfo[i]->FallThrough = false;
m_RecompilerOps->LinkJump(*JumpInfo[i], TargetSection[i]->m_SectionID); m_RecompilerOps->LinkJump(*JumpInfo[i], TargetSection[i]->m_SectionID);
if (JumpInfo[i]->LinkAddress != (uint32_t)-1)
{
JumpInfo[i]->RegSet.UnMap_GPR(31, false);
JumpInfo[i]->RegSet.SetMipsRegLo(31, JumpInfo[i]->LinkAddress);
JumpInfo[i]->RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
JumpInfo[i]->LinkAddress = (uint32_t)-1;
}
if (JumpInfo[i]->TargetPC <= m_RecompilerOps->GetCurrentPC()) if (JumpInfo[i]->TargetPC <= m_RecompilerOps->GetCurrentPC())
{ {
if (JumpInfo[i]->PermLoop) if (JumpInfo[i]->PermLoop)
@ -232,6 +253,13 @@ void CCodeSection::GenerateSectionLinkage()
{ {
m_CodeBlock.Log("ExitBlock (from %d):", m_SectionID); m_CodeBlock.Log("ExitBlock (from %d):", m_SectionID);
m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1);
if (JumpInfo[i]->LinkAddress != (uint32_t)-1)
{
JumpInfo[i]->RegSet.UnMap_GPR(31, false);
JumpInfo[i]->RegSet.SetMipsRegLo(31, JumpInfo[i]->LinkAddress);
JumpInfo[i]->RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
JumpInfo[i]->LinkAddress = (uint32_t)-1;
}
m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason); m_RecompilerOps->CompileExit(JumpInfo[i]->JumpPC, JumpInfo[i]->TargetPC, JumpInfo[i]->RegSet, JumpInfo[i]->Reason);
continue; continue;
} }
@ -249,6 +277,13 @@ void CCodeSection::GenerateSectionLinkage()
m_CodeBlock.Log(Label.c_str()); m_CodeBlock.Log(Label.c_str());
m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1); m_RecompilerOps->LinkJump(*JumpInfo[i], (uint32_t)-1);
if (JumpInfo[i]->LinkAddress != (uint32_t)-1)
{
JumpInfo[i]->RegSet.UnMap_GPR(31, false);
JumpInfo[i]->RegSet.SetMipsRegLo(31, JumpInfo[i]->LinkAddress);
JumpInfo[i]->RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
JumpInfo[i]->LinkAddress = (uint32_t)-1;
}
m_RecompilerOps->SetRegWorkingSet(JumpInfo[i]->RegSet); m_RecompilerOps->SetRegWorkingSet(JumpInfo[i]->RegSet);
if (JumpInfo[i]->TargetPC <= JumpInfo[i]->JumpPC) if (JumpInfo[i]->TargetPC <= JumpInfo[i]->JumpPC)
{ {

View File

@ -9,6 +9,7 @@ CJumpInfo::CJumpInfo(CCodeBlock & CodeBlock) :
{ {
TargetPC = (uint32_t)-1; TargetPC = (uint32_t)-1;
JumpPC = (uint32_t)-1; JumpPC = (uint32_t)-1;
LinkAddress = (uint32_t)-1;
BranchLabel = ""; BranchLabel = "";
FallThrough = false; FallThrough = false;
PermLoop = false; PermLoop = false;

View File

@ -8,6 +8,7 @@ struct CJumpInfo
uint32_t TargetPC; uint32_t TargetPC;
uint32_t JumpPC; uint32_t JumpPC;
uint32_t LinkAddress;
std::string BranchLabel; std::string BranchLabel;
asmjit::Label LinkLocation; asmjit::Label LinkLocation;
asmjit::Label LinkLocation2; asmjit::Label LinkLocation2;

View File

@ -529,9 +529,21 @@ void CX86RecompilerOps::Compile_Branch(RecompilerBranchCompare CompareType, bool
if (Link) if (Link)
{ {
UnMap_GPR(31, false); R4300iInstruction Instruction(m_CompilePC, m_Opcode.Value);
m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); uint32_t ReadReg1, ReadReg2;
m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); Instruction.ReadsGPR(ReadReg1, ReadReg2);
if (ReadReg1 != 31 && ReadReg2 != 31)
{
UnMap_GPR(31, false);
m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8);
m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN);
}
else
{
m_Section->m_Cont.LinkAddress = m_CompilePC + 8;
m_Section->m_Jump.LinkAddress = m_CompilePC + 8;
}
} }
if (m_EffectDelaySlot) if (m_EffectDelaySlot)
{ {