diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index 87bea087a..f7ccbbc00 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -581,6 +581,7 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & break; case R4300i_REGIMM_BLTZL: case R4300i_REGIMM_BGEZL: + case R4300i_REGIMM_BGEZALL: TargetPC = PC + ((int16_t)Command.offset << 2) + 4; if (TargetPC == PC) { diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index ce0246081..17878a0b4 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -483,14 +483,15 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_REGIMM_BGEZ: m_RecompilerOps->Compile_Branch(RecompilerBranchCompare_BGEZ, false); break; case R4300i_REGIMM_BLTZL: m_RecompilerOps->Compile_BranchLikely(RecompilerBranchCompare_BLTZ, false); break; case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(RecompilerBranchCompare_BGEZ, false); break; - case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(RecompilerBranchCompare_BLTZ, true); break; - case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(RecompilerBranchCompare_BGEZ, true); break; - case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TEQI); break; - case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TNEI); break; case R4300i_REGIMM_TGEI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TGEI); break; case R4300i_REGIMM_TGEIU: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TGEIU); break; case R4300i_REGIMM_TLTI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TLTI); break; case R4300i_REGIMM_TLTIU: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TLTIU); break; + case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TEQI); break; + case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(RecompilerTrapCompare_TNEI); break; + case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(RecompilerBranchCompare_BLTZ, true); break; + case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(RecompilerBranchCompare_BGEZ, true); break; + case R4300i_REGIMM_BGEZALL: m_RecompilerOps->Compile_BranchLikely(RecompilerBranchCompare_BGEZ, true); break; default: m_RecompilerOps->UnknownOpcode(); break; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 1059e6296..50b160ad6 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -863,9 +863,21 @@ void CX86RecompilerOps::Compile_BranchLikely(RecompilerBranchCompare CompareType m_Section->m_Cont.LinkLocation2 = asmjit::Label(); 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; + } } Compile_BranchCompare(CompareType); @@ -873,6 +885,13 @@ void CX86RecompilerOps::Compile_BranchLikely(RecompilerBranchCompare CompareType m_Section->m_Cont.RegSet = m_RegWorkingSet; m_Section->m_Cont.RegSet.SetBlockCycleCount(m_Section->m_Cont.RegSet.GetBlockCycleCount() + g_System->CountPerOp()); + if (m_Section->m_Cont.LinkAddress != (uint32_t)-1) + { + m_Section->m_Cont.RegSet.UnMap_GPR(31, false); + m_Section->m_Cont.RegSet.SetMipsRegLo(31, m_Section->m_Cont.LinkAddress); + m_Section->m_Cont.RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + m_Section->m_Cont.LinkAddress = (uint32_t)-1; + } if ((m_CompilePC & 0xFFC) == 0xFFC) { if (m_Section->m_Cont.FallThrough) @@ -910,6 +929,13 @@ void CX86RecompilerOps::Compile_BranchLikely(RecompilerBranchCompare CompareType { m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet.SetBlockCycleCount(m_Section->m_Jump.RegSet.GetBlockCycleCount() + g_System->CountPerOp()); + if (m_Section->m_Jump.LinkAddress != (uint32_t)-1) + { + m_Section->m_Jump.RegSet.UnMap_GPR(31, false); + m_Section->m_Jump.RegSet.SetMipsRegLo(31, m_Section->m_Jump.LinkAddress); + m_Section->m_Jump.RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + m_Section->m_Jump.LinkAddress = (uint32_t)-1; + } m_Section->GenerateSectionLinkage(); m_PipelineStage = PIPELINE_STAGE_END_BLOCK; } @@ -931,6 +957,13 @@ void CX86RecompilerOps::Compile_BranchLikely(RecompilerBranchCompare CompareType ResetX86Protection(); m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet.SetBlockCycleCount(m_Section->m_Jump.RegSet.GetBlockCycleCount()); + if (m_Section->m_Jump.LinkAddress != (uint32_t)-1) + { + m_Section->m_Jump.RegSet.UnMap_GPR(31, false); + m_Section->m_Jump.RegSet.SetMipsRegLo(31, m_Section->m_Jump.LinkAddress); + m_Section->m_Jump.RegSet.SetMipsRegState(31, CRegInfo::STATE_CONST_32_SIGN); + m_Section->m_Jump.LinkAddress = (uint32_t)-1; + } m_Section->GenerateSectionLinkage(); m_PipelineStage = PIPELINE_STAGE_END_BLOCK; }