Cleaned up more code related to ABL

This commit is contained in:
zilmar 2012-10-16 08:47:05 +11:00
parent ccb1de6682
commit aad58b8866
4 changed files with 191 additions and 63 deletions

View File

@ -186,10 +186,7 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
CCodeSection * JumpSection = CurrentSection->m_JumpSection; CCodeSection * JumpSection = CurrentSection->m_JumpSection;
JumpSection->SetJumpAddress(TestPC, TargetPC,false); JumpSection->SetJumpAddress(TestPC, TargetPC,false);
JumpSection->SetDelaySlot(); JumpSection->SetDelaySlot();
if (!SetSection(JumpSection->m_JumpSection,CurrentSection->m_JumpSection,TargetPC,true,TestPC)) SetSection(JumpSection->m_JumpSection,CurrentSection->m_JumpSection,TargetPC,true,TestPC);
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
} else { } else {
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
} }
@ -230,6 +227,12 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
} }
CurrentSection = NewSection; CurrentSection = NewSection;
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
break;
}
TestPC = CurrentSection->m_EnterPC; TestPC = CurrentSection->m_EnterPC;
CPU_Message("a. Section %d",CurrentSection->m_SectionID); CPU_Message("a. Section %d",CurrentSection->m_SectionID);
TestPC -= 4; TestPC -= 4;
@ -251,6 +254,12 @@ bool CCodeBlock::CreateBlockLinkage ( CCodeSection * EnterSection )
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
} }
CurrentSection = NewSection; CurrentSection = NewSection;
if (CurrentSection->m_JumpSection != NULL ||
CurrentSection->m_ContinueSection != NULL ||
CurrentSection->m_EndSection)
{
break;
}
TestPC = CurrentSection->m_EnterPC; TestPC = CurrentSection->m_EnterPC;
CPU_Message("b. Section %d",CurrentSection->m_SectionID); CPU_Message("b. Section %d",CurrentSection->m_SectionID);
} }
@ -298,7 +307,7 @@ bool CCodeBlock::AnalyseBlock ( void )
if (!bLinkBlocks()) { return true; } if (!bLinkBlocks()) { return true; }
if (!CreateBlockLinkage(m_EnterSection)) { return false; } if (!CreateBlockLinkage(m_EnterSection)) { return false; }
DetermineLoops(); DetermineLoops();
//LogSectionInfo(); LogSectionInfo();
return true; return true;
} }
@ -341,6 +350,7 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU: case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU: case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU:
break; break;
case R4300i_SPECIAL_JALR:
case R4300i_SPECIAL_JR: case R4300i_SPECIAL_JR:
EndBlock = true; EndBlock = true;
IncludeDelaySlot = true; IncludeDelaySlot = true;
@ -385,6 +395,17 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
} }
} }
break; break;
case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
LikelyBranch = true;
IncludeDelaySlot = true;
break;
default: default:
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
return false; return false;
@ -456,6 +477,15 @@ bool CCodeBlock::AnalyzeInstruction ( DWORD PC, DWORD & TargetPC, DWORD & Contin
case R4300i_COP1_MF: case R4300i_COP1_CF: case R4300i_COP1_MT: case R4300i_COP1_CT: case R4300i_COP1_MF: case R4300i_COP1_CF: case R4300i_COP1_MT: case R4300i_COP1_CT:
case R4300i_COP1_S: case R4300i_COP1_D: case R4300i_COP1_W: case R4300i_COP1_L: case R4300i_COP1_S: case R4300i_COP1_D: case R4300i_COP1_W: case R4300i_COP1_L:
break; break;
case R4300i_COP1_BC:
TargetPC = PC + ((short)Command.offset << 2) + 4;
if (TargetPC == PC)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
ContinuePC = PC + 8;
IncludeDelaySlot = true;
break;
default: default:
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
return false; return false;

View File

@ -1765,9 +1765,10 @@ bool CCodeSection::InheritParentInfo ( void )
//Fix up initial state //Fix up initial state
UnMap_AllFPRs(); UnMap_AllFPRs();
if (ParentList.size() != NoOfCompiledParents)
{ //determine loop reg usage
//determine loop reg usage if (m_InLoop && ParentList.size() > 1)
{
if (!SetupRegisterForLoop()) { return false; } if (!SetupRegisterForLoop()) { return false; }
m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown); m_RegWorkingSet.SetRoundingModel(CRegInfo::RoundUnknown);
} }

View File

@ -11,6 +11,27 @@ LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) :
memset(&m_Command,0,sizeof(m_Command)); memset(&m_Command,0,sizeof(m_Command));
} }
LoopAnalysis::~LoopAnalysis()
{
for (RegisterMap::iterator itr = m_EnterRegisters.begin(); itr != m_EnterRegisters.end(); itr++)
{
delete itr->second;
}
m_EnterRegisters.clear();
for (RegisterMap::iterator itr = m_ContinueRegisters.begin(); itr != m_ContinueRegisters.end(); itr++)
{
delete itr->second;
}
m_ContinueRegisters.clear();
for (RegisterMap::iterator itr = m_JumpRegisters.begin(); itr != m_JumpRegisters.end(); itr++)
{
delete itr->second;
}
m_JumpRegisters.clear();
}
bool LoopAnalysis::SetupRegisterForLoop ( void ) bool LoopAnalysis::SetupRegisterForLoop ( void )
{ {
if (!m_EnterSection->m_InLoop) if (!m_EnterSection->m_InLoop)
@ -31,7 +52,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
if (Section->m_ParentSection.empty()) { _Notify->BreakPoint(__FILE__,__LINE__); 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__ ": Section ID %d Section Test: %X-%X",Section->m_SectionID,Section->m_Test,Section->m_Test2);
bool bFirstParent = true, bSkipedSection = false; bool bFirstParent = true, bSkipedSection = false;
CRegInfo RegEnter; CRegInfo RegEnter;
@ -40,7 +61,20 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
CCodeSection * Parent = *iter; CCodeSection * Parent = *iter;
CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection }; CCodeSection * TargetSection[] = { Parent->m_ContinueSection, Parent->m_JumpSection };
CJumpInfo * JumpInfo[] = { &Parent->m_Cont, &Parent->m_Jump }; CRegInfo * JumpRegInfo[] = { &Parent->m_Cont.RegSet, &Parent->m_Jump.RegSet };
if (Parent->m_CompiledLocation)
{
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;
}
}
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
@ -54,15 +88,15 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
if (bFirstParent) if (bFirstParent)
{ {
bFirstParent = false; bFirstParent = false;
RegEnter = JumpInfo[i]->RegSet; RegEnter = *JumpRegInfo[i];
} else { } else {
if (JumpInfo[i]->RegSet == RegEnter) if (*JumpRegInfo[i] == RegEnter)
{ {
continue; continue;
} }
for (int x = 0; x < 32; x++) for (int x = 0; x < 32; x++)
{ {
if (RegEnter.MipsRegState(x) != JumpInfo[i]->RegSet.MipsRegState(x)) if (RegEnter.MipsRegState(x) != JumpRegInfo[i]->MipsRegState(x))
{ {
RegEnter.SetMipsRegState(x,CRegInfo::STATE_UNKNOWN); RegEnter.SetMipsRegState(x,CRegInfo::STATE_UNKNOWN);
} }
@ -78,23 +112,33 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
if (Section->m_CompiledLocation != NULL) if (Section->m_CompiledLocation != NULL)
{ {
if (!CheckLoopRegisterUsage(Section->m_ContinueSection,Test,Test2)) { return false; } RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID);
if (!CheckLoopRegisterUsage(Section->m_JumpSection,Test,Test2)) { return false; } if (itr != m_EnterRegisters.end())
return true; {
*(itr->second) = RegEnter;
} else {
m_EnterRegisters.insert(RegisterMap::value_type(Section->m_SectionID,new CRegInfo(RegEnter)));
}
} else {
Section->m_RegEnter = RegEnter;
} }
if (Section->m_Test == Test) if (Section->m_Test == Test)
{ {
Section->m_RegEnter = RegEnter;
return true; return true;
} }
Section->m_RegEnter = RegEnter;
Section->m_Test = Test; Section->m_Test = Test;
Section->m_Test2 = Test2; Section->m_Test2 = Test2;
m_PC = Section->m_EnterPC; m_PC = Section->m_EnterPC;
m_Reg = Section->m_RegEnter; 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;
}
m_NextInstruction = NORMAL; m_NextInstruction = NORMAL;
DWORD ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (DWORD)-1; DWORD ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (DWORD)-1;
//CPU_Message("ContinueSectionPC = %08X",ContinueSectionPC); CPU_Message("ContinueSectionPC = %08X",ContinueSectionPC);
do { do {
if (!_MMU->LW_VAddr(m_PC, m_Command.Hex)) if (!_MMU->LW_VAddr(m_PC, m_Command.Hex))
@ -189,15 +233,32 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
break; break;
case R4300i_REGIMM_BLTZL: case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL: case R4300i_REGIMM_BGEZL:
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
m_NextInstruction = LIKELY_DELAY_SLOT; m_NextInstruction = LIKELY_DELAY_SLOT;
Section->m_Cont.TargetPC = m_PC + 8; #ifdef CHECKED_BUILD
Section->m_Jump.TargetPC = m_PC + ((short)m_Command.offset << 2) + 4; if (Section->m_Cont.TargetPC != m_PC + 8)
if (m_PC == Section->m_Jump.TargetPC) { {
if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,0)) { _Notify->BreakPoint(__FILE__,__LINE__);
Section->m_Jump.PermLoop = true; }
if (Section->m_Jump.TargetPC != m_PC + 4)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
/*if (Section->m_Jump.TargetPC != m_PC + ((short)m_Command.offset << 2) + 4)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}*/
if (m_PC == m_PC + ((short)m_Command.offset << 2) + 4)
{
_Notify->BreakPoint(__FILE__,__LINE__);
#ifdef tofix
if (!DelaySlotEffectsCompare(m_PC,m_Command.rs,m_Command.rt))
{
if (!Section->m_Jump.PermLoop)
{
_Notify->BreakPoint(__FILE__,__LINE__);
}
} }
#endif
} }
#endif #endif
break; break;
@ -638,7 +699,18 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
{ {
if (m_NextInstruction != NORMAL) { _Notify->BreakPoint(__FILE__,__LINE__); } if (m_NextInstruction != NORMAL) { _Notify->BreakPoint(__FILE__,__LINE__); }
m_NextInstruction = END_BLOCK; m_NextInstruction = END_BLOCK;
Section->m_Jump.RegSet = m_Reg; 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;
}
} else { } else {
switch (m_NextInstruction) { switch (m_NextInstruction) {
case NORMAL: case NORMAL:
@ -649,21 +721,64 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
m_PC += 4; m_PC += 4;
break; break;
case LIKELY_DELAY_SLOT: case LIKELY_DELAY_SLOT:
Section->m_Cont.RegSet = m_Reg; if (Section->m_CompiledLocation)
Section->m_Jump.RegSet = m_Reg; {
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;
}
m_NextInstruction = END_BLOCK; m_NextInstruction = END_BLOCK;
break; break;
case DELAY_SLOT_DONE: case DELAY_SLOT_DONE:
Section->m_Cont.RegSet = m_Reg; if (Section->m_CompiledLocation)
Section->m_Jump.RegSet = m_Reg; {
Section->m_Cont.DoneDelaySlot = true; RegisterMap::iterator itr = m_ContinueRegisters.find(Section->m_SectionID);
Section->m_Jump.DoneDelaySlot = true; 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;
}
m_NextInstruction = END_BLOCK; m_NextInstruction = END_BLOCK;
break; break;
case LIKELY_DELAY_SLOT_DONE: case LIKELY_DELAY_SLOT_DONE:
_Notify->BreakPoint(__FILE__,__LINE__); _Notify->BreakPoint(__FILE__,__LINE__);
Section->m_Jump.RegSet = m_Reg; if (Section->m_CompiledLocation)
Section->m_Jump.DoneDelaySlot = true; {
_Notify->BreakPoint(__FILE__,__LINE__);
} else {
Section->m_Jump.RegSet = m_Reg;
Section->m_Jump.DoneDelaySlot = true;
}
m_NextInstruction = END_BLOCK; m_NextInstruction = END_BLOCK;
break; break;
} }
@ -693,43 +808,19 @@ bool LoopAnalysis::CheckLoopRegisterUsage( CCodeSection * Section, DWORD Test, D
void LoopAnalysis::SPECIAL_SLL ( void ) void LoopAnalysis::SPECIAL_SLL ( void )
{ {
if (m_Command.rd == 0) { return; } if (m_Command.rd == 0) { return; }
if (m_Command.rt == m_Command.rd) { m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
if (m_Reg.IsConst(m_Command.rt)) {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32);
m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rt) << m_Command.sa;
} else {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
} }
void LoopAnalysis::SPECIAL_SRL ( void ) void LoopAnalysis::SPECIAL_SRL ( void )
{ {
if (m_Command.rd == 0) { return; } if (m_Command.rd == 0) { return; }
if (m_Command.rt == m_Command.rd) { m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
if (m_Reg.IsConst(m_Command.rt)) {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32);
m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo(m_Command.rt) >> m_Command.sa;
} else {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
} }
void LoopAnalysis::SPECIAL_SRA ( void ) void LoopAnalysis::SPECIAL_SRA ( void )
{ {
if (m_Command.rd == 0) { return; } if (m_Command.rd == 0) { return; }
if (m_Command.rt == m_Command.rd) { m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
if (m_Reg.IsConst(m_Command.rt)) {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_CONST_32);
m_Reg.MipsRegLo(m_Command.rd) = m_Reg.MipsRegLo_S(m_Command.rt) >> m_Command.sa;
} else {
m_Reg.SetMipsRegState(m_Command.rd,CRegInfo::STATE_UNKNOWN);
}
} }
void LoopAnalysis::SPECIAL_SLLV ( void ) void LoopAnalysis::SPECIAL_SLLV ( void )

View File

@ -7,6 +7,7 @@ class LoopAnalysis
{ {
public: public:
LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section); LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section);
~LoopAnalysis();
bool SetupRegisterForLoop ( void ); bool SetupRegisterForLoop ( void );
@ -56,6 +57,11 @@ private:
void SPECIAL_DSRL32 ( void ); void SPECIAL_DSRL32 ( void );
void SPECIAL_DSRA32 ( void ); void SPECIAL_DSRA32 ( void );
typedef std::map<int,CRegInfo *> RegisterMap;
RegisterMap m_EnterRegisters;
RegisterMap m_ContinueRegisters;
RegisterMap m_JumpRegisters;
CCodeSection * m_EnterSection; CCodeSection * m_EnterSection;
CCodeBlock * m_BlockInfo; CCodeBlock * m_BlockInfo;
DWORD m_PC; DWORD m_PC;