Ejemplo n.º 1
0
void CCodeBlock::LogSectionInfo()
{
    for (SectionList::iterator itr = m_Sections.begin(); itr != m_Sections.end(); itr++)
    {
        CCodeSection * Section = *itr;
        Section->DisplaySectionInformation();
    }
}
Ejemplo n.º 2
0
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);
    }
}
Ejemplo n.º 3
0
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();
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}