Firedemo and n64 stars now runs under ABL

This commit is contained in:
zilmar 2012-10-15 18:41:30 +11:00
parent b83e4dcf7b
commit ccb1de6682
7 changed files with 109 additions and 167 deletions

View File

@ -14,7 +14,6 @@ CCodeBlock::CCodeBlock(DWORD VAddrEnter, BYTE * RecompPos) :
m_Sections.push_back(m_EnterSection);
}
if (_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0]))))
{
m_MemLocation[1] = m_MemLocation[0] + 1;
@ -46,7 +45,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
if (TargetPC > ((CurrentPC + 0x1000) & 0xFFFFF000))
{
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
}
if (TargetPC < m_EnterSection->m_EnterPC)
@ -82,7 +81,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
m_SectionMap.insert(SectionMap::value_type(TargetPC,Section));
}
Section->AddParent(CurrentSection);
if (TargetPC < CurrentPC)
if (TargetPC < CurrentPC && TargetPC != m_VAddrEnter)
{
CCodeSection * SplitSection = m_EnterSection;
for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++)
@ -94,7 +93,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
SplitSection = itr->second;
}
CCodeSection * BaseSection = Section;
BaseSection->SetJumpAddress(SplitSection->m_Jump.JumpPC, SplitSection->m_Jump.TargetPC);
BaseSection->SetJumpAddress(SplitSection->m_Jump.JumpPC, SplitSection->m_Jump.TargetPC,SplitSection->m_Jump.PermLoop);
BaseSection->m_JumpSection = SplitSection->m_JumpSection;
BaseSection->SetContinueAddress(SplitSection->m_Cont.JumpPC,SplitSection->m_Cont.TargetPC);
BaseSection->m_ContinueSection = SplitSection->m_ContinueSection;
@ -105,7 +104,7 @@ bool CCodeBlock::SetSection ( CCodeSection * & Section, CCodeSection * CurrentSe
SplitSection->m_JumpSection = NULL;
SplitSection->m_ContinueSection = BaseSection;
SplitSection->SetContinueAddress(TargetPC - 4, TargetPC);
SplitSection->SetJumpAddress((DWORD)-1,(DWORD)-1);
SplitSection->SetJumpAddress((DWORD)-1,(DWORD)-1,false);
}
}
return true;
@ -135,16 +134,25 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
}
CurrentSection = itr->second;
CPU_Message("Section %d",CurrentSection->m_SectionID);
if (EnterSection != m_EnterSection)
{
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
break;
}
}
}
} else {
CurrentSection->m_EndSection = true;
break;
}
bool LikelyBranch, EndBlock, IncludeDelaySlot;
bool LikelyBranch, EndBlock, IncludeDelaySlot, PermLoop;
DWORD TargetPC, ContinuePC, SectionCount = m_Sections.size();
if (!AnalyzeInstruction(TestPC, TargetPC, ContinuePC, LikelyBranch, IncludeDelaySlot, EndBlock))
if (!AnalyzeInstruction(TestPC, TargetPC, ContinuePC, LikelyBranch, IncludeDelaySlot, EndBlock, PermLoop))
{
_Notify->BreakPoint(__FILE__,__LINE__);
return false;
@ -172,11 +180,11 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
if (LikelyBranch)
{
CurrentSection->SetJumpAddress(TestPC, TestPC + 4);
CurrentSection->SetJumpAddress(TestPC, TestPC + 4,false);
if (SetSection(CurrentSection->m_JumpSection, CurrentSection, TestPC + 4,false,TestPC))
{
CCodeSection * JumpSection = CurrentSection->m_JumpSection;
JumpSection->SetJumpAddress(TestPC, TargetPC);
JumpSection->SetJumpAddress(TestPC, TargetPC,false);
JumpSection->SetDelaySlot();
if (!SetSection(JumpSection->m_JumpSection,CurrentSection->m_JumpSection,TargetPC,true,TestPC))
{
@ -188,8 +196,8 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
}
else if (TargetPC != ((DWORD)-1))
{
CurrentSection->SetJumpAddress(TestPC, TargetPC);
if (!SetSection(CurrentSection->m_JumpSection, CurrentSection, TargetPC,true,TestPC))
CurrentSection->SetJumpAddress(TestPC, TargetPC,PermLoop);
if (PermLoop || !SetSection(CurrentSection->m_JumpSection, CurrentSection, TargetPC,true,TestPC))
{
if (ContinuePC == (DWORD)-1)
{
@ -294,13 +302,14 @@ bool CCodeBlock::AnalyseBlock ( void )
return true;
}
bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock )
bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock, bool & PermLoop )
{
TargetPC = (DWORD)-1;
ContinuePC = (DWORD)-1;
LikelyBranch = false;
IncludeDelaySlot = false;
EndBlock = false;
PermLoop = false;
OPCODE Command;
if (!_MMU->LW_VAddr(PC, Command.Hex)) {
@ -349,6 +358,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
{
case R4300i_REGIMM_BLTZ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
IncludeDelaySlot = true;
break;
@ -379,6 +392,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
break;
case R4300i_J:
TargetPC = (PC & 0xF0000000) + (Command.target << 2);
if (TargetPC == PC)
{
PermLoop = true;
}
IncludeDelaySlot = true;
break;
case R4300i_JAL:
@ -387,6 +404,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
break;
case R4300i_BEQ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (Command.rs != 0 || Command.rt != 0)
{
ContinuePC = PC + 8;
@ -397,6 +418,10 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
case R4300i_BLEZ:
case R4300i_BGTZ:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
IncludeDelaySlot = true;
break;
@ -445,8 +470,25 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
case R4300i_SH: case R4300i_SW: case R4300i_SWR: case R4300i_SWL:
case R4300i_SWC1: case R4300i_SDC1: case R4300i_SD:
break;
case R4300i_BEQL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (Command.rs != 0 || Command.rt != 0)
{
ContinuePC = PC + 8;
}
IncludeDelaySlot = true;
LikelyBranch = true;
break;
case R4300i_BNEL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
LikelyBranch = true;
IncludeDelaySlot = true;

View File

@ -40,7 +40,8 @@ private:
void LogSectionInfo ( void ) ;
bool SetSection ( CCodeSection * & Section, CCodeSection * CurrentSection, DWORD TargetPC, bool LinkAllowed, DWORD CurrentPC );
bool SetJumpInfo ( CCodeSection * & Section, DWORD TargetPC, DWORD CurrentPC );
bool AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot, bool & EndBlock );
bool AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & ContinuePC, bool & LikelyBranch, bool & IncludeDelaySlot,
bool & EndBlock, bool & PermLoop );
DWORD m_VAddrEnter;
DWORD m_VAddrFirst; // the address of the first opcode in the block

View File

@ -571,8 +571,8 @@ void CCodeSection::GenerateSectionLinkage (void)
CompileExit (CompilePC(),JumpInfo[i]->TargetPC,JumpInfo[i]->RegSet,CExitInfo::Normal,true,NULL);
continue;
}
if (JumpInfo[i]->TargetPC != TargetSection[i]->m_EnterPC) {
_Notify->DisplayError("I need to add more code in GenerateSectionLinkage cause this is going to cause an exception");
if (JumpInfo[i]->TargetPC != TargetSection[i]->m_EnterPC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (TargetSection[i]->m_CompiledLocation == NULL)
@ -664,23 +664,21 @@ void CCodeSection::SyncRegState ( const CRegInfo & SyncTo )
}
break;
case CRegInfo::STATE_CONST_64:
if (MipsReg(i) != SyncTo.MipsReg(i)) {
#if (!defined(EXTERNAL_RELEASE))
_Notify->DisplayError("Umm.. how ???");
#endif
if (MipsReg(i) != SyncTo.MipsReg(i))
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
continue;
case CRegInfo::STATE_CONST_32:
if (MipsRegLo(i) != SyncTo.cMipsRegLo(i)) {
#if (!defined(EXTERNAL_RELEASE))
_Notify->DisplayError("Umm.. how ???");
#endif
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));
_Notify->BreakPoint(__FILE__,__LINE__);
}
continue;
#ifndef EXTERNAL_RELEASE
default:
_Notify->DisplayError("Unhandled Reg state %d\nin SyncRegState",MipsRegState(i));
#endif
WriteTraceF(TraceError,"Unhandled Reg state %d\nin SyncRegState",MipsRegState(i));
_Notify->BreakPoint(__FILE__,__LINE__);
}
}
changed = true;
@ -723,10 +721,8 @@ void CCodeSection::SyncRegState ( const CRegInfo & SyncTo )
MoveConstToX86reg(MipsRegLo(i),Reg);
break;
default:
#ifndef EXTERNAL_RELEASE
CPU_Message("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(i));
_Notify->DisplayError("Do something with states in SyncRegState\nSTATE_MAPPED_64\n%d",MipsRegState(i));
#endif
_Notify->BreakPoint(__FILE__,__LINE__);
continue;
}
m_RegWorkingSet.SetMipsRegMapLo(i,Reg);
@ -827,11 +823,12 @@ void CCodeSection::SetDelaySlot (void)
m_DelaySlot = true;
}
void CCodeSection::SetJumpAddress (DWORD JumpPC, DWORD TargetPC)
void CCodeSection::SetJumpAddress (DWORD JumpPC, DWORD TargetPC, bool PermLoop)
{
m_Jump.JumpPC = JumpPC;
m_Jump.TargetPC = TargetPC;
m_Jump.BranchLabel.Format("0x%08X",TargetPC);
m_Jump.PermLoop = PermLoop;
}
void CCodeSection::SetContinueAddress (DWORD JumpPC, DWORD TargetPC)
@ -1358,9 +1355,10 @@ bool CCodeSection::GenerateX86Code ( DWORD Test )
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
m_CompilePC -= 4;
m_Cont.RegSet = m_RegWorkingSet;
m_Cont.FallThrough = true;
m_Cont.JumpPC = m_CompilePC - 4;
m_Cont.JumpPC = m_CompilePC;
GenerateSectionLinkage();
m_NextInstruction = END_BLOCK;
}
@ -1494,63 +1492,6 @@ void CCodeSection::DetermineLoop(DWORD Test, DWORD Test2, DWORD TestID)
}
}
#ifdef tofix
bool CCodeSection::FixConstants (DWORD Test)
{
if (this == NULL) { return false; }
if (m_Test == Test) { return false; }
m_Test = Test;
InheritConstants();
bool Changed = false;
CRegInfo Original[2] = { m_Cont.RegSet, m_Jump.RegSet };
if (!m_ParentSection.empty())
{
for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++)
{
CCodeSection * Parent = *iter;
if (Parent->m_ContinueSection == this)
{
for (int i = 0; i < 32; i++)
{
if (m_RegEnter.MipsRegState(i) != Parent->m_Cont.RegSet.MipsRegState(i)) {
m_RegEnter.SetMipsRegState(i,CRegInfo::STATE_UNKNOWN);
//*Changed = true;
}
m_RegEnter.SetMipsRegState(i, CRegInfo::STATE_UNKNOWN);
}
}
if (Parent->m_JumpSection == this) {
for (int i = 0; i < 32; i++) {
if (m_RegEnter.MipsRegState(i) != Parent->m_Jump.RegSet.MipsRegState(i)) {
m_RegEnter.SetMipsRegState(i,CRegInfo::STATE_UNKNOWN);
//*Changed = true;
}
}
}
m_RegWorkingSet = m_RegEnter;
}
}
FillSectionInfo(NORMAL);
if (Original[0] != m_Cont.RegSet)
{
Changed = true;
}
if (Original[1] != m_Jump.RegSet)
{
Changed = true;
}
if (m_JumpSection && m_JumpSection->FixConstants(Test)) { Changed = true; }
if (m_ContinueSection && m_ContinueSection->FixConstants(Test)) { Changed = true; }
return Changed;
}
#endif
CCodeSection * CCodeSection::ExistingSection(DWORD Addr, DWORD Test)
{
if (this == NULL) { return NULL; }
@ -1587,42 +1528,6 @@ bool CCodeSection::SectionAccessible ( DWORD SectionId, DWORD Test )
return m_JumpSection->SectionAccessible(SectionId,Test);
}
#ifdef toremove
void CCodeSection::InheritConstants( void )
{
if (m_ParentSection.empty())
{
m_RegWorkingSet = m_RegEnter;
return;
}
CCodeSection * Parent = *(m_ParentSection.begin());
CRegInfo * RegSet = (this == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet);
m_RegEnter = *RegSet;
m_RegWorkingSet = *RegSet;
for (SECTION_LIST::iterator iter = m_ParentSection.begin(); iter != m_ParentSection.end(); iter++)
{
if (iter == m_ParentSection.begin()) { continue; }
Parent = *iter;
RegSet = this == Parent->m_ContinueSection?&Parent->m_Cont.RegSet:&Parent->m_Jump.RegSet;
for (int i = 0; i < 32; i++) {
if (IsConst(i)) {
if (MipsRegState(i) != RegSet->MipsRegState(i)) {
m_RegWorkingSet.SetMipsRegState(i,CRegInfo::STATE_UNKNOWN);
} else if (Is32Bit(i) && cMipsRegLo(i) != RegSet->cMipsRegLo(i)) {
m_RegWorkingSet.SetMipsRegState(i,CRegInfo::STATE_UNKNOWN);
} else if (Is64Bit(i) && MipsReg(i) != RegSet->MipsReg(i)) {
m_RegWorkingSet.SetMipsRegState(i,CRegInfo::STATE_UNKNOWN);
}
}
}
}
m_RegEnter = m_RegWorkingSet;
}
#endif
void CCodeSection::UnlinkParent( CCodeSection * Parent, bool ContinueSection )
{
if (this == NULL)
@ -2010,17 +1915,15 @@ bool CCodeSection::InheritParentInfo ( void )
}
break;
case CRegInfo::STATE_CONST_32:
if (MipsRegLo(i2) != RegSet->MipsRegLo(i2)) {
#if (!defined(EXTERNAL_RELEASE))
_Notify->DisplayError("Umm.. how ???");
#endif
if (MipsRegLo(i2) != RegSet->MipsRegLo(i2))
{
_Notify->BreakPoint(__FILE__,__LINE__);
NeedSync = true;
}
break;
#ifndef EXTERNAL_RELEASE
default:
_Notify->DisplayError("Unhandled Reg state %d\nin InheritParentInfo",MipsRegState(i2));
#endif
default:
WriteTraceF(TraceError,"Unhandled Reg state %d\nin InheritParentInfo",MipsRegState(i2));
_Notify->BreakPoint(__FILE__,__LINE__);
}
}
if (NeedSync == false) { continue; }

View File

@ -12,7 +12,7 @@ public:
~CCodeSection( void );
void SetDelaySlot ( void );
void SetJumpAddress ( DWORD JumpPC, DWORD TargetPC );
void SetJumpAddress ( DWORD JumpPC, DWORD TargetPC, bool PermLoop );
void SetContinueAddress ( DWORD JumpPC, DWORD TargetPC );
void CompileCop1Test ( void );
bool CreateSectionLinkage ( void );

View File

@ -8,8 +8,8 @@ public:
stdstr BranchLabel;
DWORD * LinkLocation;
DWORD * LinkLocation2;
BOOL FallThrough;
BOOL PermLoop;
BOOL DoneDelaySlot; //maybe deletable
bool FallThrough;
bool PermLoop;
bool DoneDelaySlot; //maybe deletable
CRegInfo RegSet;
};

View File

@ -166,15 +166,24 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
switch (m_Command.rt) {
case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
m_NextInstruction = DELAY_SLOT;
Section->m_Cont.TargetPC = m_PC + 8;
Section->m_Jump.TargetPC = m_PC + ((short)m_Command.offset << 2) + 4;
if (m_PC == Section->m_Jump.TargetPC) {
if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,0)) {
#ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (m_PC == Section->m_Jump.TargetPC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt)) {
Section->m_Jump.PermLoop = true;
}
#endif
}
#endif
break;
@ -270,11 +279,16 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
#endif
break;
case R4300i_J:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
m_NextInstruction = DELAY_SLOT;
Section->m_Jump.TargetPC = (m_PC & 0xF0000000) + (m_Command.target << 2);
if (m_PC == Section->m_Jump.TargetPC) { Section->m_Jump.PermLoop = true; }
#ifdef CHECKED_BUILD
if (Section->m_Jump.TargetPC != (m_PC & 0xF0000000) + (m_Command.target << 2))
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
if (m_PC == Section->m_Jump.TargetPC && !Section->m_Jump.PermLoop)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
#endif
break;
case R4300i_BEQ:
@ -335,16 +349,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
case R4300i_ADDI:
case R4300i_ADDIU:
if (m_Command.rt == 0) { break; }
if (m_Command.rs == m_Command.rt)
{
m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_UNKNOWN);
}
if (m_Reg.IsConst(m_Command.rs)) {
m_Reg.MipsRegLo(m_Command.rt) = m_Reg.MipsRegLo(m_Command.rs) + (short)m_Command.immediate;
m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_CONST_32);
} else {
m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_UNKNOWN);
}
m_Reg.SetMipsRegState(m_Command.rt,CRegInfo::STATE_UNKNOWN);
break;
case R4300i_SLTI:
if (m_Command.rt == 0) { break; }
@ -895,16 +900,7 @@ void LoopAnalysis::SPECIAL_ADD ( void )
void LoopAnalysis::SPECIAL_ADDU ( void )
{
if (m_Command.rd == 0) { return; }
if (m_Command.rt == m_Command.rd || m_Command.rs == m_Command.rd)
{
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
if (m_Reg.IsConst(m_Command.rt) && m_Reg.IsConst(m_Command.rs)) {
m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rs) + m_Reg.MipsRegLo(m_Command.rt);
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32);
} else {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
void LoopAnalysis::SPECIAL_SUB ( void )

View File

@ -38,7 +38,7 @@ CGameSettings::CGameSettings()
CGameSettings::~CGameSettings()
{
m_RefCount -= 1;
if (m_Registered && m_RefCount == 0)
if (_Settings && m_Registered && m_RefCount == 0)
{
_Settings->UnregisterChangeCB(Game_UseTlb,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);
_Settings->UnregisterChangeCB(Game_ViRefreshRate,this,(CSettings::SettingChangedFunc)StaticRefreshSettings);