diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index d9a229e52..fe7093475 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -85,6 +85,13 @@ void CCodeSection::GenerateSectionLinkage() else if (TargetSection[i] == nullptr && JumpInfo[i]->FallThrough) { 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); JumpInfo[i]->FallThrough = false; } @@ -99,6 +106,13 @@ void CCodeSection::GenerateSectionLinkage() continue; } 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); //FreeSection(TargetSection[i],Section); } @@ -138,6 +152,13 @@ void CCodeSection::GenerateSectionLinkage() { JumpInfo[i]->FallThrough = false; 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]->PermLoop) @@ -232,6 +253,13 @@ void CCodeSection::GenerateSectionLinkage() { m_CodeBlock.Log("ExitBlock (from %d):", m_SectionID); 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); continue; } @@ -249,6 +277,13 @@ void CCodeSection::GenerateSectionLinkage() m_CodeBlock.Log(Label.c_str()); 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); if (JumpInfo[i]->TargetPC <= JumpInfo[i]->JumpPC) { diff --git a/Source/Project64-core/N64System/Recompiler/JumpInfo.cpp b/Source/Project64-core/N64System/Recompiler/JumpInfo.cpp index eb764fa89..b430ce1a3 100644 --- a/Source/Project64-core/N64System/Recompiler/JumpInfo.cpp +++ b/Source/Project64-core/N64System/Recompiler/JumpInfo.cpp @@ -9,6 +9,7 @@ CJumpInfo::CJumpInfo(CCodeBlock & CodeBlock) : { TargetPC = (uint32_t)-1; JumpPC = (uint32_t)-1; + LinkAddress = (uint32_t)-1; BranchLabel = ""; FallThrough = false; PermLoop = false; diff --git a/Source/Project64-core/N64System/Recompiler/JumpInfo.h b/Source/Project64-core/N64System/Recompiler/JumpInfo.h index 6d9990e1a..d7b69c77d 100644 --- a/Source/Project64-core/N64System/Recompiler/JumpInfo.h +++ b/Source/Project64-core/N64System/Recompiler/JumpInfo.h @@ -8,6 +8,7 @@ struct CJumpInfo uint32_t TargetPC; uint32_t JumpPC; + uint32_t LinkAddress; std::string BranchLabel; asmjit::Label LinkLocation; asmjit::Label LinkLocation2; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index d6ed073a4..78ad719b9 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -529,9 +529,21 @@ void CX86RecompilerOps::Compile_Branch(RecompilerBranchCompare CompareType, bool if (Link) { - UnMap_GPR(31, false); - m_RegWorkingSet.SetMipsRegLo(31, m_CompilePC + 8); - m_RegWorkingSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + R4300iInstruction Instruction(m_CompilePC, m_Opcode.Value); + uint32_t ReadReg1, ReadReg2; + 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) {