From b5bee95acb6f98cddbc10bdbbd23e321ed8be9e9 Mon Sep 17 00:00:00 2001 From: zilmar Date: Tue, 16 Oct 2012 22:17:18 +1100 Subject: [PATCH] More code cleanup with getting ABL to try and work for super mario --- .../N64 System/Recompiler/Code Block.cpp | 2 +- .../N64 System/Recompiler/Code Section.cpp | 306 +++++++----------- .../N64 System/Recompiler/Loop Analysis.cpp | 242 +++++++------- .../N64 System/Recompiler/Loop Analysis.h | 9 +- .../N64 System/Recompiler/Reg Info.cpp | 4 +- 5 files changed, 253 insertions(+), 310 deletions(-) diff --git a/Source/Project64/N64 System/Recompiler/Code Block.cpp b/Source/Project64/N64 System/Recompiler/Code Block.cpp index 1217f5835..20dbbb519 100644 --- a/Source/Project64/N64 System/Recompiler/Code Block.cpp +++ b/Source/Project64/N64 System/Recompiler/Code Block.cpp @@ -578,4 +578,4 @@ void CCodeBlock::CompileExitCode ( void ) DWORD CCodeBlock::NextTest ( void ) { return InterlockedIncrement(&m_Test); -} +} \ No newline at end of file diff --git a/Source/Project64/N64 System/Recompiler/Code Section.cpp b/Source/Project64/N64 System/Recompiler/Code Section.cpp index 7e9b1641c..2954ff052 100644 --- a/Source/Project64/N64 System/Recompiler/Code Section.cpp +++ b/Source/Project64/N64 System/Recompiler/Code Section.cpp @@ -614,6 +614,8 @@ void CCodeSection::GenerateSectionLinkage (void) void CCodeSection::SyncRegState ( const CRegInfo & SyncTo ) { + ResetX86Protection(); + bool changed = false; UnMap_AllFPRs(); if (m_RegWorkingSet.GetRoundingModel() != SyncTo.GetRoundingModel()) { m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); } @@ -642,8 +644,6 @@ void CCodeSection::SyncRegState ( const CRegInfo & SyncTo ) for (int i = 1; i < 32; i ++) { - x86Reg Reg, x86RegHi; - if (MipsRegState(i) == SyncTo.MipsRegState(i) || (b32BitCore() && MipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO && SyncTo.MipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN) || (b32BitCore() && MipsRegState(i) == CRegInfo::STATE_MAPPED_32_SIGN && SyncTo.MipsRegState(i) == CRegInfo::STATE_MAPPED_32_ZERO)) @@ -672,12 +672,12 @@ void CCodeSection::SyncRegState ( const CRegInfo & SyncTo ) case CRegInfo::STATE_CONST_32: if (MipsRegLo(i) != SyncTo.cMipsRegLo(i)) { - WriteTraceF(TraceError,"Value of const is different Reg %d Value: 0x%08X to 0x%08X",i,MipsRegLo(i),SyncTo.cMipsRegLo(i)); + CPU_Message("Value of const is different Reg %d (%s) Value: 0x%08X to 0x%08X",i,CRegName::GPR[i],MipsRegLo(i),SyncTo.cMipsRegLo(i)); _Notify->BreakPoint(__FILE__,__LINE__); } continue; default: - WriteTraceF(TraceError,"Unhandled Reg state %d\nin SyncRegState",MipsRegState(i)); + CPU_Message("Unhandled Reg state %d\nin SyncRegState",MipsRegState(i)); _Notify->BreakPoint(__FILE__,__LINE__); } } @@ -686,129 +686,130 @@ void CCodeSection::SyncRegState ( const CRegInfo & SyncTo ) switch (SyncTo.MipsRegState(i)) { case CRegInfo::STATE_UNKNOWN: UnMap_GPR(i,true); break; case CRegInfo::STATE_MAPPED_64: - Reg = SyncTo.MipsRegMapLo(i); - x86RegHi = SyncTo.MipsRegMapHi(i); - UnMap_X86reg(Reg); - UnMap_X86reg(x86RegHi); - switch (MipsRegState(i)) { - case CRegInfo::STATE_UNKNOWN: - MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); - MoveVariableToX86reg(&_GPR[i].UW[1],CRegName::GPR_Hi[i],x86RegHi); - break; - case CRegInfo::STATE_MAPPED_64: - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); - MoveX86RegToX86Reg(MipsRegMapHi(i),x86RegHi); - m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(i),CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - MoveX86RegToX86Reg(MipsRegMapLo(i),x86RegHi); - ShiftRightSignImmed(x86RegHi,31); - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - XorX86RegToX86Reg(x86RegHi,x86RegHi); - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i), CRegInfo::NotMapped); - break; - case CRegInfo::STATE_CONST_64: - MoveConstToX86reg(MipsRegHi(i),x86RegHi); - MoveConstToX86reg(MipsRegLo(i),Reg); - break; - case CRegInfo::STATE_CONST_32: - MoveConstToX86reg(MipsRegLo_S(i) >> 31,x86RegHi); - MoveConstToX86reg(MipsRegLo(i),Reg); - break; - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(i)); - _Notify->BreakPoint(__FILE__,__LINE__); - continue; + { + x86Reg Reg = SyncTo.MipsRegMapLo(i); + x86Reg x86RegHi = SyncTo.MipsRegMapHi(i); + UnMap_X86reg(Reg); + UnMap_X86reg(x86RegHi); + switch (MipsRegState(i)) { + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); + MoveVariableToX86reg(&_GPR[i].UW[1],CRegName::GPR_Hi[i],x86RegHi); + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); + MoveX86RegToX86Reg(MipsRegMapHi(i),x86RegHi); + m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(i),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + MoveX86RegToX86Reg(MipsRegMapLo(i),x86RegHi); + ShiftRightSignImmed(x86RegHi,31); + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + XorX86RegToX86Reg(x86RegHi,x86RegHi); + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i), CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_64: + MoveConstToX86reg(MipsRegHi(i),x86RegHi); + MoveConstToX86reg(MipsRegLo(i),Reg); + break; + case CRegInfo::STATE_CONST_32: + MoveConstToX86reg(MipsRegLo_S(i) >> 31,x86RegHi); + MoveConstToX86reg(MipsRegLo(i),Reg); + break; + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(i)); + _Notify->BreakPoint(__FILE__,__LINE__); + continue; + } + m_RegWorkingSet.SetMipsRegMapLo(i,Reg); + m_RegWorkingSet.SetMipsRegMapHi(i,x86RegHi); + m_RegWorkingSet.SetMipsRegState(i,CRegInfo::STATE_MAPPED_64); + m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86Mapped(x86RegHi,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg,1); + m_RegWorkingSet.SetX86MapOrder(x86RegHi,1); } - m_RegWorkingSet.SetMipsRegMapLo(i,Reg); - m_RegWorkingSet.SetMipsRegMapHi(i,x86RegHi); - m_RegWorkingSet.SetMipsRegState(i,CRegInfo::STATE_MAPPED_64); - m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86Mapped(x86RegHi,CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg,1); - m_RegWorkingSet.SetX86MapOrder(x86RegHi,1); break; case CRegInfo::STATE_MAPPED_32_SIGN: - Reg = SyncTo.MipsRegMapLo(i); - UnMap_X86reg(Reg); - switch (MipsRegState(i)) { - case CRegInfo::STATE_UNKNOWN: MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); break; - case CRegInfo::STATE_CONST_32: MoveConstToX86reg(MipsRegLo(i),Reg); break; - case CRegInfo::STATE_MAPPED_32_SIGN: - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - if (MipsRegMapLo(i) != Reg) { + { + x86Reg Reg = SyncTo.MipsRegMapLo(i); + UnMap_X86reg(Reg); + switch (MipsRegState(i)) { + case CRegInfo::STATE_UNKNOWN: MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); break; + case CRegInfo::STATE_CONST_32: MoveConstToX86reg(MipsRegLo(i),Reg); break; + case CRegInfo::STATE_MAPPED_32_SIGN: MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: + if (MipsRegMapLo(i) != Reg) { + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); + } + break; + case CRegInfo::STATE_MAPPED_64: + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped) ; + m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(i),CRegInfo::NotMapped); + break; + case CRegInfo::STATE_CONST_64: + CPU_Message("hi %X\nLo %X",MipsRegHi(i),MipsRegLo(i)); + default: + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d",MipsRegState(i)); + _Notify->BreakPoint(__FILE__,__LINE__); } - break; - case CRegInfo::STATE_MAPPED_64: - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped) ; - m_RegWorkingSet.SetX86Mapped(MipsRegMapHi(i),CRegInfo::NotMapped); - break; -#ifndef EXTERNAL_RELEASE - case CRegInfo::STATE_CONST_64: - _Notify->DisplayError("hi %X\nLo %X",MipsRegHi(i),MipsRegLo(i)); - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d",MipsRegState(i)); - _Notify->DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_32_SIGN\n%d",MipsRegState(i)); -#endif + m_RegWorkingSet.SetMipsRegMapLo(i,Reg); + m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_32_SIGN); + m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg,1); } - m_RegWorkingSet.SetMipsRegMapLo(i,Reg); - m_RegWorkingSet.SetMipsRegState(i, CRegInfo::STATE_MAPPED_32_SIGN); - m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg,1); break; case CRegInfo::STATE_MAPPED_32_ZERO: - Reg = SyncTo.MipsRegMapLo(i); - UnMap_X86reg(Reg); - switch (MipsRegState(i)) { - case CRegInfo::STATE_MAPPED_64: - case CRegInfo::STATE_UNKNOWN: - MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); - break; - case CRegInfo::STATE_MAPPED_32_ZERO: - MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); - m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); - break; - case CRegInfo::STATE_MAPPED_32_SIGN: - if (b32BitCore()) - { + { + x86Reg Reg = SyncTo.MipsRegMapLo(i); + UnMap_X86reg(Reg); + switch (MipsRegState(i)) { + case CRegInfo::STATE_MAPPED_64: + case CRegInfo::STATE_UNKNOWN: + MoveVariableToX86reg(&_GPR[i].UW[0],CRegName::GPR_Lo[i],Reg); + break; + case CRegInfo::STATE_MAPPED_32_ZERO: MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); - } else { + break; + case CRegInfo::STATE_MAPPED_32_SIGN: + if (b32BitCore()) + { + MoveX86RegToX86Reg(MipsRegMapLo(i),Reg); + m_RegWorkingSet.SetX86Mapped(MipsRegMapLo(i),CRegInfo::NotMapped); + } else { + CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(i)); + _Notify->BreakPoint(__FILE__,__LINE__); + } + break; + case CRegInfo::STATE_CONST_32: + if (!b32BitCore() && MipsRegLo_S(i) < 0) + { + CPU_Message("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); + CPU_Message("%s: %X",CRegName::GPR[i],MipsRegLo_S(i)); + _Notify->BreakPoint(__FILE__,__LINE__); + } + MoveConstToX86reg(MipsRegLo(i),Reg); + break; + default: CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(i)); - _Notify->DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(i)); + _Notify->BreakPoint(__FILE__,__LINE__); } - break; - case CRegInfo::STATE_CONST_32: - if (!b32BitCore() && MipsRegLo_S(i) < 0) { - CPU_Message("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); - CPU_Message("%s: %X",CRegName::GPR[i],MipsRegLo_S(i)); -#ifndef EXTERNAL_RELEASE - _Notify->DisplayError("Sign Problems in SyncRegState\nSTATE_MAPPED_32_ZERO"); -#endif - } - MoveConstToX86reg(MipsRegLo(i),Reg); - break; -#ifndef EXTERNAL_RELEASE - default: - CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(i)); - _Notify->DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_32_ZERO\n%d",MipsRegState(i)); -#endif + m_RegWorkingSet.SetMipsRegMapLo(i,Reg); + m_RegWorkingSet.SetMipsRegState(i, SyncTo.MipsRegState(i)); + m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); + m_RegWorkingSet.SetX86MapOrder(Reg,1); } - m_RegWorkingSet.SetMipsRegMapLo(i,Reg); - m_RegWorkingSet.SetMipsRegState(i, SyncTo.MipsRegState(i)); - m_RegWorkingSet.SetX86Mapped(Reg,CRegInfo::GPR_Mapped); - m_RegWorkingSet.SetX86MapOrder(Reg,1); break; default: CPU_Message("%d - %d reg: %s (%d)",SyncTo.MipsRegState(i),MipsRegState(i),CRegName::GPR[i],i); @@ -845,85 +846,6 @@ void CCodeSection::CompileCop1Test (void) { m_RegWorkingSet.FpuBeenUsed() = TRUE; } -#ifdef tremove -bool CCodeSection::CreateSectionLinkage ( void ) -{ - InheritConstants(); - - if (!FillSectionInfo(NORMAL)) - { - return false; - } - - CCodeSection ** TargetSection[2]; - CJumpInfo * JumpInfo[2]; - if (m_Jump.TargetPC < m_Cont.TargetPC) { - TargetSection[0] = (CCodeSection **)&m_JumpSection; - TargetSection[1] = (CCodeSection **)&m_ContinueSection; - JumpInfo[0] = &m_Jump; - JumpInfo[1] = &m_Cont; - } else { - TargetSection[0] = (CCodeSection **)&m_ContinueSection; - TargetSection[1] = (CCodeSection **)&m_JumpSection; - JumpInfo[0] = &m_Cont; - JumpInfo[1] = &m_Jump; - } - - CCodeBlock * BlockInfo = m_BlockInfo; - - for (int i = 0; i < 2; i ++) - { - if (JumpInfo[i]->TargetPC == (DWORD)-1 || *TargetSection[i] != NULL || JumpInfo[i]->PermLoop) - { - continue; - } - if (!JumpInfo[i]->DoneDelaySlot) - { - m_Jump.RegSet = m_RegWorkingSet; - - //this is a special delay slot section - BlockInfo->IncSectionCount(); - *TargetSection[i] = new CCodeSection(BlockInfo,CompilePC() + 4,BlockInfo->NoOfSections(),false); - (*TargetSection[i])->AddParent(this); - (*TargetSection[i])->m_LinkAllowed = false; - (*TargetSection[i])->InheritConstants(); - - if (!(*TargetSection[i])->FillSectionInfo(END_BLOCK)) - { - return false; - } - (*TargetSection[i])->m_Jump.TargetPC = (DWORD)-1; - (*TargetSection[i])->m_Cont.TargetPC = JumpInfo[i]->TargetPC; - (*TargetSection[i])->m_Cont.FallThrough = true; - (*TargetSection[i])->m_Cont.RegSet = (*TargetSection[i])->m_RegWorkingSet; - JumpInfo[i]->TargetPC = CompilePC() + 4; - - //Create the section that joins with that block - (*TargetSection[i])->m_ContinueSection = BlockInfo->ExistingSection((*TargetSection[i])->m_Cont.TargetPC); - if ((*TargetSection[i])->m_ContinueSection == NULL) { - BlockInfo->IncSectionCount(); - (*TargetSection[i])->m_ContinueSection = new CCodeSection(BlockInfo,(*TargetSection[i])->m_Cont.TargetPC,BlockInfo->NoOfSections(),true); - (*TargetSection[i])->m_ContinueSection->AddParent((*TargetSection[i])); - (*TargetSection[i])->m_ContinueSection->CreateSectionLinkage(); - } else { - (*TargetSection[i])->m_ContinueSection->AddParent((*TargetSection[i])); - } - } else { - *TargetSection[i] = BlockInfo->ExistingSection(JumpInfo[i]->TargetPC); - if (*TargetSection[i] == NULL) { - BlockInfo->IncSectionCount(); - *TargetSection[i] = new CCodeSection(BlockInfo,JumpInfo[i]->TargetPC,BlockInfo->NoOfSections(),true); - (*TargetSection[i])->AddParent(this); - (*TargetSection[i])->CreateSectionLinkage(); - } else { - (*TargetSection[i])->AddParent(this); - } - } - } - return true; -} -#endif - bool CCodeSection::ParentContinue ( void ) { if (m_ParentSection.size() > 0) diff --git a/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp b/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp index d9b058283..179e63eda 100644 --- a/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp +++ b/Source/Project64/N64 System/Recompiler/Loop Analysis.cpp @@ -6,7 +6,9 @@ LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) : m_EnterSection(Section), m_BlockInfo(CodeBlock), m_PC((DWORD)-1), - m_NextInstruction(NORMAL) + m_NextInstruction(NORMAL), + m_Test(m_BlockInfo->NextTest()), + m_TestChanged(0) { memset(&m_Command,0,sizeof(m_Command)); } @@ -38,21 +40,29 @@ bool LoopAnalysis::SetupRegisterForLoop ( void ) { return false; } - if (!CheckLoopRegisterUsage(m_EnterSection, m_BlockInfo->NextTest(),m_BlockInfo->NextTest())) + CPU_Message(__FUNCTION__ ": Section ID: %d Test: %X",m_EnterSection->m_SectionID,m_Test); + do + { + if (!CheckLoopRegisterUsage(m_EnterSection)) + { + return false; + } + } while (m_EnterSection->m_Test != m_Test); + + RegisterMap::iterator itr = m_EnterRegisters.find(m_EnterSection->m_SectionID); + if (itr == m_EnterRegisters.end()) { return false; } + m_EnterSection->m_RegEnter = *(itr->second); return true; } -bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, DWORD Test2) +bool LoopAnalysis::SetupEnterSection ( CCodeSection * Section ) { - if (Section == NULL) { return true; } - if (!Section->m_InLoop) { return true; } - if (Section->m_ParentSection.empty()) { _Notify->BreakPoint(__FILE__,__LINE__); return true; } - CPU_Message(__FUNCTION__ ": Section ID %d Section Test: %X-%X",Section->m_SectionID,Section->m_Test,Section->m_Test2); + CPU_Message(__FUNCTION__ ": Block EnterPC: %X Section ID %d Test: %X Section Test: %X CompiledLocation: %X",m_BlockInfo->VAddrEnter(),Section->m_SectionID,m_Test,Section->m_Test, Section->m_CompiledLocation); bool bFirstParent = true, bSkipedSection = false; CRegInfo RegEnter; @@ -60,31 +70,25 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D { CCodeSection * Parent = *iter; - CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection }; - CRegInfo * JumpRegInfo[] = { &Parent->m_Cont.RegSet, &Parent->m_Jump.RegSet }; - if (Parent->m_CompiledLocation) + CPU_Message(__FUNCTION__ ": Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X",Parent->m_SectionID,m_Test,Parent->m_Test, Parent->m_CompiledLocation); + if (Parent->m_Test != m_Test && (m_EnterSection != Section || Parent->m_CompiledLocation == NULL)) { - RegisterMap::iterator itr = m_ContinueRegisters.find(Parent->m_SectionID); - if (itr != m_ContinueRegisters.end()) - { - JumpRegInfo[0] = itr->second; - } - itr = m_JumpRegisters.find(Parent->m_SectionID); - if (itr != m_JumpRegisters.end()) - { - JumpRegInfo[1] = itr->second; - } + CPU_Message(__FUNCTION__ ": Ignore Parent Section ID %d Test: %X Section Test: %X CompiledLocation: %X",Parent->m_SectionID,m_Test,Parent->m_Test, Parent->m_CompiledLocation); + bSkipedSection = true; + continue; } + RegisterMap::iterator Continue_itr = m_ContinueRegisters.find(Parent->m_SectionID); + RegisterMap::iterator Jump_itr = m_JumpRegisters.find(Parent->m_SectionID); + + CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection }; + CRegInfo * JumpRegInfo[] = { + Continue_itr == m_ContinueRegisters.end() ? &Parent->m_Cont.RegSet : Continue_itr->second, + Jump_itr == m_JumpRegisters.end() ? &Parent->m_Jump.RegSet : Jump_itr->second + }; for (int i = 0; i < 2; i++) { if (TargetSection[i] != Section) { continue; } - if (Parent->m_CompiledLocation == NULL && Parent->m_Test != Test) - { - bSkipedSection = true; - continue; - } - if (bFirstParent) { bFirstParent = false; @@ -94,13 +98,8 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D { continue; } - for (int x = 0; x < 32; x++) - { - if (RegEnter.MipsRegState(x) != JumpRegInfo[i]->MipsRegState(x)) - { - RegEnter.SetMipsRegState(x,CRegInfo::STATE_UNKNOWN); - } - } + + SyncRegState(RegEnter,*JumpRegInfo[i]); } } } @@ -110,32 +109,43 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D _Notify->BreakPoint(__FILE__,__LINE__); } - if (Section->m_CompiledLocation != NULL) + RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); + if (itr != m_EnterRegisters.end()) { - RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); - if (itr != m_EnterRegisters.end()) + if (SyncRegState(*(itr->second),RegEnter)) { - *(itr->second) = RegEnter; - } else { - m_EnterRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(RegEnter))); + m_Test = m_BlockInfo->NextTest(); + m_TestChanged += 1; + if (m_TestChanged > MAX_TESTCHANGED) + { + _Notify->BreakPoint(__FILE__,__LINE__); + } } } else { - Section->m_RegEnter = RegEnter; + m_EnterRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(RegEnter))); } - if (Section->m_Test == Test) + return true; +} + +bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section) +{ + if (Section == NULL) { return true; } + if (!Section->m_InLoop) { return true; } + + if (Section->m_Test == m_Test) { return true; } - Section->m_Test = Test; - Section->m_Test2 = Test2; + + if (!SetupEnterSection(Section)) { return false; } + + CPU_Message(__FUNCTION__ ": Set Section %d test to %X from %X",Section->m_SectionID,m_Test,Section->m_Test); + Section->m_Test = m_Test; m_PC = Section->m_EnterPC; - if (Section->m_CompiledLocation) - { - RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); - m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter; - } else { - m_Reg = Section->m_RegEnter; - } + + RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); + m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter; + m_NextInstruction = NORMAL; DWORD ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (DWORD)-1; CPU_Message("ContinueSectionPC = %08X",ContinueSectionPC); @@ -147,6 +157,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D return false; } CPU_Message(" %08X: %s",m_PC,R4300iOpcodeName(m_Command.Hex,m_PC)); + CPU_Message(" %s state: %X value: %X",CRegName::GPR[1],m_Reg.MipsRegState(1),m_Reg.MipsRegLo(1)); switch (m_Command.op) { case R4300i_SPECIAL: switch (m_Command.funct) { @@ -357,19 +368,21 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D #ifdef CHECKED_BUILD if (m_Command.rs != 0 || m_Command.rt != 0) { - if (Section->m_Cont.TargetPC != m_PC + 8) + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (DWORD)-1) { _Notify->BreakPoint(__FILE__,__LINE__); } } else { if (Section->m_Cont.TargetPC != (DWORD)-1) { - _Notify->BreakPoint(__FILE__,__LINE__); + //_Notify->BreakPoint(__FILE__,__LINE__); } } if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) { - _Notify->BreakPoint(__FILE__,__LINE__); + //_Notify->BreakPoint(__FILE__,__LINE__); } if (m_PC == Section->m_Jump.TargetPC) { @@ -410,7 +423,12 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D case R4300i_ADDI: case R4300i_ADDIU: if (m_Command.rt == 0) { break; } - m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_UNKNOWN); + /*if (m_Command.rs == 0) { + m_Reg.MipsRegLo(m_Command.rt) = (short)m_Command.immediate; + m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_CONST_32); + } else {*/ + m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_UNKNOWN); + //} break; case R4300i_SLTI: if (m_Command.rt == 0) { break; } @@ -604,13 +622,15 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D case R4300i_BGTZL: m_NextInstruction = LIKELY_DELAY_SLOT; #ifdef CHECKED_BUILD - if (Section->m_Cont.TargetPC != m_PC + 8) + if (Section->m_Cont.TargetPC != m_PC + 8 && + Section->m_ContinueSection != NULL && + Section->m_Cont.TargetPC != (DWORD)-1) { _Notify->BreakPoint(__FILE__,__LINE__); } if (Section->m_Jump.TargetPC != m_PC + 4) { - _Notify->BreakPoint(__FILE__,__LINE__); + //_Notify->BreakPoint(__FILE__,__LINE__); } /*if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4) { @@ -699,18 +719,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D { if (m_NextInstruction != NORMAL) { _Notify->BreakPoint(__FILE__,__LINE__); } m_NextInstruction = END_BLOCK; - if (Section->m_CompiledLocation) - { - RegisterMap::iterator itr = m_JumpRegisters.find(Section->m_SectionID); - if (itr != m_JumpRegisters.end()) - { - *(itr->second) = m_Reg; - } else { - m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(m_Reg))); - } - } else { - Section->m_Jump.RegSet = m_Reg; - } + SetJumpRegSet(Section,m_Reg); } else { switch (m_NextInstruction) { case NORMAL: @@ -721,52 +730,16 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D m_PC += 4; break; case LIKELY_DELAY_SLOT: - if (Section->m_CompiledLocation) { - RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID); - if (itr != m_ContinueRegisters.end()) - { - *(itr->second) = m_Reg; - } else { - m_ContinueRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(m_Reg))); - } - - itr = m_JumpRegisters.find(Section->m_SectionID); - if (itr != m_JumpRegisters.end()) - { - *(itr->second) = m_Reg; - } else { - m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(m_Reg))); - } - } else { - Section->m_Cont.RegSet = m_Reg; - Section->m_Jump.RegSet = m_Reg; + SetContinueRegSet(Section,m_Reg); + SetJumpRegSet(Section,m_Reg); } m_NextInstruction = END_BLOCK; break; case DELAY_SLOT_DONE: - if (Section->m_CompiledLocation) { - RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID); - if (itr != m_ContinueRegisters.end()) - { - *(itr->second) = m_Reg; - } else { - m_ContinueRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(m_Reg))); - } - - itr = m_JumpRegisters.find(Section->m_SectionID); - if (itr != m_JumpRegisters.end()) - { - *(itr->second) = m_Reg; - } else { - m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(m_Reg))); - } - } else { - Section->m_Cont.RegSet = m_Reg; - Section->m_Jump.RegSet = m_Reg; - Section->m_Cont.DoneDelaySlot = true; - Section->m_Jump.DoneDelaySlot = true; + SetContinueRegSet(Section,m_Reg); + SetJumpRegSet(Section,m_Reg); } m_NextInstruction = END_BLOCK; break; @@ -774,10 +747,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D _Notify->BreakPoint(__FILE__,__LINE__); if (Section->m_CompiledLocation) { - _Notify->BreakPoint(__FILE__,__LINE__); } else { - Section->m_Jump.RegSet = m_Reg; - Section->m_Jump.DoneDelaySlot = true; + //Section->m_Jump.RegSet = m_Reg; + //Section->m_Jump.DoneDelaySlot = true; } m_NextInstruction = END_BLOCK; break; @@ -787,6 +759,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D if (m_PC == ContinueSectionPC) { m_NextInstruction = END_BLOCK; + SetContinueRegSet(Section,m_Reg); } if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) { @@ -798,12 +771,55 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D } } while (m_NextInstruction != END_BLOCK); - if (!CheckLoopRegisterUsage(Section->m_ContinueSection,Test,Test2)) { return false; } - if (!CheckLoopRegisterUsage(Section->m_JumpSection,Test,Test2)) { return false; } + if (!CheckLoopRegisterUsage(Section->m_ContinueSection)) { return false; } + if (!CheckLoopRegisterUsage(Section->m_JumpSection)) { return false; } + if (!SetupEnterSection(Section)) { return false; } return true; } +bool LoopAnalysis::SyncRegState ( CRegInfo & RegSet, const CRegInfo SyncReg ) +{ + bool bChanged = false; + for (int x = 0; x < 32; x++) + { + if (RegSet.MipsRegState(x) != SyncReg.MipsRegState(x)) + { + CPU_Message(__FUNCTION__ ": Clear state %s RegEnter State: %X Jump Reg State: %X",CRegName::GPR[x],RegSet.MipsRegState(x),SyncReg.MipsRegState(x)); + RegSet.SetMipsRegState(x,CRegInfo::STATE_UNKNOWN); + } + else if (RegSet.IsConst(x) && RegSet.Is32Bit(x) && RegSet.cMipsRegLo(x) != SyncReg.cMipsRegLo(x)) + { + CPU_Message(__FUNCTION__ ": Clear state %s RegEnter State: %X Jump Reg State: %X",CRegName::GPR[x],RegSet.MipsRegState(x),SyncReg.MipsRegState(x)); + RegSet.SetMipsRegState(x,CRegInfo::STATE_UNKNOWN); + } else if (RegSet.IsConst(x) && RegSet.Is64Bit(x)) { + _Notify->BreakPoint(__FILE__,__LINE__); + } + } + return bChanged; +} + +void LoopAnalysis::SetJumpRegSet ( CCodeSection * Section, const CRegInfo &Reg ) +{ + RegisterMap::iterator itr = m_JumpRegisters.find(Section->m_SectionID); + if (itr != m_JumpRegisters.end()) + { + *(itr->second) = Reg; + } else { + m_JumpRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(Reg))); + } +} + +void LoopAnalysis::SetContinueRegSet ( CCodeSection * Section, const CRegInfo &Reg ) +{ + RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID); + if (itr != m_ContinueRegisters.end()) + { + *(itr->second) = Reg; + } else { + m_ContinueRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(Reg))); + } +} void LoopAnalysis::SPECIAL_SLL ( void ) { diff --git a/Source/Project64/N64 System/Recompiler/Loop Analysis.h b/Source/Project64/N64 System/Recompiler/Loop Analysis.h index dbcd10ce2..89debb2d2 100644 --- a/Source/Project64/N64 System/Recompiler/Loop Analysis.h +++ b/Source/Project64/N64 System/Recompiler/Loop Analysis.h @@ -5,6 +5,7 @@ class CCodeBlock; class LoopAnalysis { + enum { MAX_TESTCHANGED = 1000 }; public: LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section); ~LoopAnalysis(); @@ -16,7 +17,11 @@ private: LoopAnalysis(const LoopAnalysis&); // Disable copy constructor LoopAnalysis& operator=(const LoopAnalysis&); // Disable assignment - bool CheckLoopRegisterUsage ( CCodeSection * Section, DWORD Test, DWORD Test2 ); + bool SetupEnterSection ( CCodeSection * Section ); + bool CheckLoopRegisterUsage ( CCodeSection * Section ); + bool SyncRegState ( CRegInfo & RegSet, const CRegInfo SyncReg ); + void SetJumpRegSet ( CCodeSection * Section, const CRegInfo &Reg ); + void SetContinueRegSet ( CCodeSection * Section, const CRegInfo &Reg ); /********************** R4300i OpCodes: Special **********************/ void SPECIAL_SLL ( void ); @@ -68,4 +73,6 @@ private: CRegInfo m_Reg; STEP_TYPE m_NextInstruction; OPCODE m_Command; + DWORD m_Test; + DWORD m_TestChanged; }; \ No newline at end of file diff --git a/Source/Project64/N64 System/Recompiler/Reg Info.cpp b/Source/Project64/N64 System/Recompiler/Reg Info.cpp index 0f840c0ba..d902336f7 100644 --- a/Source/Project64/N64 System/Recompiler/Reg Info.cpp +++ b/Source/Project64/N64 System/Recompiler/Reg Info.cpp @@ -1198,11 +1198,9 @@ void CRegInfo::WriteBackRegisters () } SetMipsRegState(count, CRegInfo::STATE_UNKNOWN); break; -#ifndef EXTERNAL_RELEASE default: - _Notify->DisplayError("Unknown State: %d\nin WriteBackRegisters",MipsRegState(count)); + CPU_Message(__FUNCTION__ ": Unknown State: %d reg %d (%s)",MipsRegState(count),count,CRegName::GPR[count]) _Notify->BreakPoint(__FILE__,__LINE__); -#endif } } }