void CCodeBlock::LogSectionInfo() { for (SectionList::iterator itr = m_Sections.begin(); itr != m_Sections.end(); itr++) { CCodeSection * Section = *itr; Section->DisplaySectionInformation(); } }
void CCodeBlock::DetermineLoops() { for (SectionMap::iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) { CCodeSection * Section = itr->second; uint32_t Test = NextTest(); Section->DetermineLoop(Test, Test, Section->m_SectionID); } }
CCodeBlock::CCodeBlock(uint32_t VAddrEnter, uint8_t * RecompPos) : m_VAddrEnter(VAddrEnter), m_VAddrFirst(VAddrEnter), m_VAddrLast(VAddrEnter), m_CompiledLocation(RecompPos), m_EnterSection(NULL), m_Test(1) { CCodeSection * baseSection = new CCodeSection(this, VAddrEnter, 0, false); if (baseSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } m_Sections.push_back(baseSection); baseSection->AddParent(NULL); baseSection->m_CompiledLocation = (uint8_t *)-1; baseSection->m_Cont.JumpPC = VAddrEnter; baseSection->m_Cont.FallThrough = true; baseSection->m_Cont.RegSet = baseSection->m_RegEnter; m_EnterSection = new CCodeSection(this, VAddrEnter, 1, true); if (m_EnterSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } baseSection->m_ContinueSection = m_EnterSection; m_EnterSection->AddParent(baseSection); m_Sections.push_back(m_EnterSection); m_SectionMap.insert(SectionMap::value_type(VAddrEnter,m_EnterSection)); if (g_TransVaddr->VAddrToRealAddr(VAddrEnter,*(reinterpret_cast<void **>(&m_MemLocation[0])))) { m_MemLocation[1] = m_MemLocation[0] + 1; m_MemContents[0] = *m_MemLocation[0]; m_MemContents[1] = *m_MemLocation[1]; } else { memset(m_MemLocation,0,sizeof(m_MemLocation)); memset(m_MemContents,0,sizeof(m_MemContents)); } AnalyseBlock(); }
CCodeBlock::CCodeBlock(uint32_t VAddrEnter, uint8_t * CompiledLocation) : m_VAddrEnter(VAddrEnter), m_VAddrFirst(VAddrEnter), m_VAddrLast(VAddrEnter), m_CompiledLocation(CompiledLocation), m_EnterSection(NULL), m_RecompilerOps(NULL), m_Test(1) { #if defined(__arm__) || defined(_M_ARM) // make sure function starts at odd address so that the system knows it is thumb mode if (((uint32_t)m_CompiledLocation % 2) == 0) { m_CompiledLocation+=1; } #endif #if defined(__i386__) || defined(_M_IX86) m_RecompilerOps = new CX86RecompilerOps; #elif defined(__arm__) || defined(_M_ARM) m_RecompilerOps = new CArmRecompilerOps; #endif if (m_RecompilerOps == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); return; } CCodeSection * baseSection = new CCodeSection(this, VAddrEnter, 0, false); if (baseSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } m_Sections.push_back(baseSection); baseSection->AddParent(NULL); baseSection->m_CompiledLocation = (uint8_t *)-1; baseSection->m_Cont.JumpPC = VAddrEnter; baseSection->m_Cont.FallThrough = true; baseSection->m_Cont.RegSet = baseSection->m_RegEnter; m_EnterSection = new CCodeSection(this, VAddrEnter, 1, true); if (m_EnterSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } baseSection->m_ContinueSection = m_EnterSection; m_EnterSection->AddParent(baseSection); m_Sections.push_back(m_EnterSection); m_SectionMap.insert(SectionMap::value_type(VAddrEnter, m_EnterSection)); if (g_TransVaddr->VAddrToRealAddr(VAddrEnter, *(reinterpret_cast<void **>(&m_MemLocation[0])))) { m_MemLocation[1] = m_MemLocation[0] + 1; m_MemContents[0] = *m_MemLocation[0]; m_MemContents[1] = *m_MemLocation[1]; } else { memset(m_MemLocation, 0, sizeof(m_MemLocation)); memset(m_MemContents, 0, sizeof(m_MemContents)); } AnalyseBlock(); }
bool CCodeBlock::CreateBlockLinkage(CCodeSection * EnterSection) { CCodeSection * CurrentSection = EnterSection; CPU_Message("Section %d", CurrentSection->m_SectionID); for (uint32_t TestPC = EnterSection->m_EnterPC, EndPC = ((EnterSection->m_EnterPC + 0x1000) & 0xFFFFF000); TestPC <= EndPC; TestPC += 4) { if (TestPC != EndPC) { SectionMap::const_iterator itr = m_SectionMap.find(TestPC); if (itr != m_SectionMap.end() && CurrentSection != itr->second) { if (CurrentSection->m_ContinueSection != NULL && CurrentSection->m_ContinueSection != itr->second) { g_Notify->BreakPoint(__FILE__, __LINE__); } if (CurrentSection->m_ContinueSection == NULL) { SetSection(CurrentSection->m_ContinueSection, CurrentSection, TestPC, true, TestPC); CurrentSection->SetContinueAddress(TestPC - 4, TestPC); } CurrentSection->m_EndPC = TestPC - 4; 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, PermLoop; uint32_t TargetPC, ContinuePC; CurrentSection->m_EndPC = TestPC; if (!AnalyzeInstruction(TestPC, TargetPC, ContinuePC, LikelyBranch, IncludeDelaySlot, EndBlock, PermLoop)) { g_Notify->BreakPoint(__FILE__, __LINE__); return false; } if (TestPC + 4 == EndPC && IncludeDelaySlot) { TargetPC = (uint32_t)-1; ContinuePC = (uint32_t)-1; EndBlock = true; } if (TargetPC == (uint32_t)-1 && !EndBlock) { if (ContinuePC != (uint32_t)-1) { g_Notify->BreakPoint(__FILE__, __LINE__); } continue; } if (EndBlock) { CPU_Message("%s: End Block", __FUNCTION__); CurrentSection->m_EndSection = true; // find other sections that need compiling break; } if (ContinuePC != (uint32_t)-1) { CPU_Message("%s: SetContinueAddress TestPC = %X ContinuePC = %X", __FUNCTION__, TestPC, ContinuePC); CurrentSection->SetContinueAddress(TestPC, ContinuePC); if (!SetSection(CurrentSection->m_ContinueSection, CurrentSection, ContinuePC, true, TestPC)) { ContinuePC = (uint32_t)-1; } } if (LikelyBranch) { CPU_Message("%s: SetJumpAddress TestPC = %X Target = %X", __FUNCTION__, TestPC, TestPC + 4); CurrentSection->SetJumpAddress(TestPC, TestPC + 4, false); if (SetSection(CurrentSection->m_JumpSection, CurrentSection, TestPC + 4, false, TestPC)) { bool BranchLikelyBranch, BranchEndBlock, BranchIncludeDelaySlot, BranchPermLoop; uint32_t BranchTargetPC, BranchContinuePC; CCodeSection * JumpSection = CurrentSection->m_JumpSection; if (!AnalyzeInstruction(JumpSection->m_EnterPC, BranchTargetPC, BranchContinuePC, BranchLikelyBranch, BranchIncludeDelaySlot, BranchEndBlock, BranchPermLoop)) { g_Notify->BreakPoint(__FILE__, __LINE__); return false; } if (BranchLikelyBranch || BranchIncludeDelaySlot || BranchPermLoop) { g_Notify->BreakPoint(__FILE__, __LINE__); return false; } JumpSection->m_EndPC = TestPC + 4; if (BranchEndBlock) { CPU_Message("%s: Jump End Block", __FUNCTION__); JumpSection->m_EndSection = true; TargetPC = (uint32_t)-1; } else { JumpSection->SetJumpAddress(TestPC, TargetPC, false); } JumpSection->SetDelaySlot(); SetSection(JumpSection->m_JumpSection, JumpSection, TargetPC, true, TestPC); } else { g_Notify->BreakPoint(__FILE__, __LINE__); } } else if (TargetPC != ((uint32_t)-1)) { CPU_Message("%s: SetJumpAddress TestPC = %X Target = %X", __FUNCTION__, TestPC, TargetPC); CurrentSection->SetJumpAddress(TestPC, TargetPC, PermLoop); if (PermLoop || !SetSection(CurrentSection->m_JumpSection, CurrentSection, TargetPC, true, TestPC)) { if (ContinuePC == (uint32_t)-1) { CurrentSection->m_EndSection = true; } } } TestPC += IncludeDelaySlot ? 8 : 4; //Find the next section CCodeSection * NewSection = NULL; for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) { if (CurrentSection->m_JumpSection != NULL || CurrentSection->m_ContinueSection != NULL || CurrentSection->m_EndSection) { continue; } NewSection = itr->second; break; } if (NewSection == NULL) { break; } if (CurrentSection == NewSection) { g_Notify->BreakPoint(__FILE__, __LINE__); } CurrentSection = NewSection; if (CurrentSection->m_JumpSection != NULL || CurrentSection->m_ContinueSection != NULL || CurrentSection->m_EndSection) { break; } TestPC = CurrentSection->m_EnterPC; CPU_Message("a. Section %d", CurrentSection->m_SectionID); TestPC -= 4; } for (SectionMap::iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) { CCodeSection * Section = itr->second; if (Section->m_JumpSection != NULL || Section->m_ContinueSection != NULL || Section->m_EndSection) { continue; } if (!CreateBlockLinkage(Section)) { return false; } break; } if (CurrentSection->m_EndPC == (uint32_t)-1) { g_Notify->BreakPoint(__FILE__, __LINE__); } return true; }
bool CCodeBlock::SetSection(CCodeSection * & Section, CCodeSection * CurrentSection, uint32_t TargetPC, bool LinkAllowed, uint32_t CurrentPC) { if (Section != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } if (TargetPC >= ((CurrentPC + 0x1000) & 0xFFFFF000)) { return false; } if (TargetPC < m_EnterSection->m_EnterPC) { return false; } if (LinkAllowed) { if (Section != NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } SectionMap::const_iterator itr = m_SectionMap.find(TargetPC); if (itr != m_SectionMap.end()) { Section = itr->second; Section->AddParent(CurrentSection); } } if (Section == NULL) { Section = new CCodeSection(this, TargetPC, m_Sections.size(), LinkAllowed); if (Section == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); return false; } m_Sections.push_back(Section); if (LinkAllowed) { m_SectionMap.insert(SectionMap::value_type(TargetPC, Section)); } Section->AddParent(CurrentSection); if (TargetPC <= CurrentPC && TargetPC != m_VAddrEnter) { CCodeSection * SplitSection = NULL; for (SectionMap::const_iterator itr = m_SectionMap.begin(); itr != m_SectionMap.end(); itr++) { if (itr->first >= TargetPC) { break; } SplitSection = itr->second; } if (SplitSection == NULL) { g_Notify->BreakPoint(__FILE__, __LINE__); } if (SplitSection->m_EndPC == (uint32_t)-1) { g_Notify->BreakPoint(__FILE__, __LINE__); } if (SplitSection->m_EndPC >= TargetPC) { CPU_Message("%s: Split Section: %d with section: %d", __FUNCTION__, SplitSection->m_SectionID, Section->m_SectionID); CCodeSection * BaseSection = Section; BaseSection->m_EndPC = SplitSection->m_EndPC; 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; BaseSection->m_JumpSection->SwitchParent(SplitSection, BaseSection); BaseSection->m_ContinueSection->SwitchParent(SplitSection, BaseSection); BaseSection->AddParent(SplitSection); SplitSection->m_EndPC = TargetPC - 4; SplitSection->m_JumpSection = NULL; SplitSection->m_ContinueSection = BaseSection; SplitSection->SetContinueAddress(TargetPC - 4, TargetPC); SplitSection->SetJumpAddress((uint32_t)-1, (uint32_t)-1, false); } } } return true; }