mirror of
https://github.com/libretro/Play-.git
synced 2025-02-26 14:35:38 +00:00
Simplify block link code.
This commit is contained in:
parent
241e7a9809
commit
3952e74d32
@ -39,6 +39,8 @@ extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
#define INVALID_LINK_SLOT (~0U)
|
||||
|
||||
CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
|
||||
: m_begin(begin)
|
||||
, m_end(end)
|
||||
@ -48,6 +50,10 @@ CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
|
||||
#endif
|
||||
{
|
||||
assert(m_end >= m_begin);
|
||||
for(uint32 i = 0; i < LINK_SLOT_MAX; i++)
|
||||
{
|
||||
m_linkBlockTrampolineOffset[i] = INVALID_LINK_SLOT;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AOT_BUILD_CACHE
|
||||
@ -287,37 +293,28 @@ bool CBasicBlock::IsEmpty() const
|
||||
(m_end == MIPS_INVALID_PC);
|
||||
}
|
||||
|
||||
void CBasicBlock::LinkNextBlock(CBasicBlock* otherBlock)
|
||||
void CBasicBlock::LinkBlock(LINK_SLOT linkSlot, CBasicBlock* otherBlock)
|
||||
{
|
||||
assert(!IsEmpty());
|
||||
assert(!otherBlock->IsEmpty());
|
||||
assert(m_nextBlockTrampolineOffset != -1);
|
||||
assert(linkSlot < LINK_SLOT_MAX);
|
||||
assert(m_linkBlockTrampolineOffset[linkSlot] != INVALID_LINK_SLOT);
|
||||
auto patchValue = reinterpret_cast<uintptr_t>(otherBlock->m_function.GetCode());
|
||||
auto code = reinterpret_cast<uint8*>(m_function.GetCode());
|
||||
*reinterpret_cast<uintptr_t*>(code + m_nextBlockTrampolineOffset) = patchValue;
|
||||
}
|
||||
|
||||
void CBasicBlock::LinkBranchBlock(CBasicBlock* otherBlock)
|
||||
{
|
||||
assert(!IsEmpty());
|
||||
assert(!otherBlock->IsEmpty());
|
||||
assert(m_branchBlockTrampolineOffset != -1);
|
||||
auto patchValue = reinterpret_cast<uintptr_t>(otherBlock->m_function.GetCode());
|
||||
auto code = reinterpret_cast<uint8*>(m_function.GetCode());
|
||||
*reinterpret_cast<uintptr_t*>(code + m_branchBlockTrampolineOffset) = patchValue;
|
||||
*reinterpret_cast<uintptr_t*>(code + m_linkBlockTrampolineOffset[linkSlot]) = patchValue;
|
||||
}
|
||||
|
||||
void CBasicBlock::HandleExternalFunctionReference(uintptr_t symbol, uint32 offset)
|
||||
{
|
||||
if(symbol == reinterpret_cast<uintptr_t>(&NextBlockTrampoline))
|
||||
{
|
||||
if(m_branchBlockTrampolineOffset == -1)
|
||||
if(m_linkBlockTrampolineOffset[LINK_SLOT_BRANCH] == INVALID_LINK_SLOT)
|
||||
{
|
||||
m_branchBlockTrampolineOffset = offset;
|
||||
m_linkBlockTrampolineOffset[LINK_SLOT_BRANCH] = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nextBlockTrampolineOffset = offset;
|
||||
m_linkBlockTrampolineOffset[LINK_SLOT_NEXT] = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,13 @@ namespace Jitter
|
||||
class CBasicBlock
|
||||
{
|
||||
public:
|
||||
enum LINK_SLOT
|
||||
{
|
||||
LINK_SLOT_NEXT,
|
||||
LINK_SLOT_BRANCH,
|
||||
LINK_SLOT_MAX,
|
||||
};
|
||||
|
||||
CBasicBlock(CMIPS&, uint32 = MIPS_INVALID_PC, uint32 = MIPS_INVALID_PC);
|
||||
virtual ~CBasicBlock() = default;
|
||||
void Execute();
|
||||
@ -53,8 +60,7 @@ public:
|
||||
bool IsCompiled() const;
|
||||
bool IsEmpty() const;
|
||||
|
||||
void LinkNextBlock(CBasicBlock*);
|
||||
void LinkBranchBlock(CBasicBlock*);
|
||||
void LinkBlock(LINK_SLOT, CBasicBlock*);
|
||||
|
||||
#ifdef AOT_BUILD_CACHE
|
||||
static void SetAotBlockOutputStream(Framework::CStdStream*);
|
||||
@ -84,6 +90,5 @@ private:
|
||||
#else
|
||||
void (*m_function)(void*);
|
||||
#endif
|
||||
uint32 m_nextBlockTrampolineOffset = -1;
|
||||
uint32 m_branchBlockTrampolineOffset = -1;
|
||||
uint32 m_linkBlockTrampolineOffset[LINK_SLOT_MAX];
|
||||
};
|
||||
|
@ -268,8 +268,15 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
//Outgoing block link
|
||||
struct BLOCK_LINK
|
||||
{
|
||||
CBasicBlock::LINK_SLOT slot;
|
||||
uint32 address;
|
||||
};
|
||||
|
||||
typedef std::list<BasicBlockPtr> BlockList;
|
||||
typedef std::multimap<uint32, uint32> BlockLinkMap;
|
||||
typedef std::multimap<uint32, BLOCK_LINK> BlockLinkMap;
|
||||
|
||||
bool HasBlockAt(uint32 address) const
|
||||
{
|
||||
@ -301,11 +308,11 @@ protected:
|
||||
auto nextBlock = m_blockLookup.FindBlockAt(nextBlockAddress);
|
||||
if(!nextBlock->IsEmpty())
|
||||
{
|
||||
block->LinkNextBlock(nextBlock);
|
||||
block->LinkBlock(CBasicBlock::LINK_SLOT_NEXT, nextBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingNextBlockLinks.insert(std::make_pair(nextBlockAddress, startAddress));
|
||||
m_pendingBlockLinks.insert(std::make_pair(nextBlockAddress, BLOCK_LINK { CBasicBlock::LINK_SLOT_NEXT, startAddress }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,36 +321,26 @@ protected:
|
||||
auto branchBlock = m_blockLookup.FindBlockAt(branchAddress);
|
||||
if(!branchBlock->IsEmpty())
|
||||
{
|
||||
block->LinkBranchBlock(branchBlock);
|
||||
block->LinkBlock(CBasicBlock::LINK_SLOT_BRANCH, branchBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingBranchBlockLinks.insert(std::make_pair(branchAddress, startAddress));
|
||||
m_pendingBlockLinks.insert(std::make_pair(branchAddress, BLOCK_LINK { CBasicBlock::LINK_SLOT_BRANCH, startAddress }));
|
||||
}
|
||||
}
|
||||
|
||||
//Resolve any block links that could be valid now that block has been created
|
||||
{
|
||||
auto lowerBound = m_pendingNextBlockLinks.lower_bound(startAddress);
|
||||
auto upperBound = m_pendingNextBlockLinks.upper_bound(startAddress);
|
||||
auto lowerBound = m_pendingBlockLinks.lower_bound(startAddress);
|
||||
auto upperBound = m_pendingBlockLinks.upper_bound(startAddress);
|
||||
for(auto blockLinkIterator = lowerBound; blockLinkIterator != upperBound; blockLinkIterator++)
|
||||
{
|
||||
auto referringBlock = m_blockLookup.FindBlockAt(blockLinkIterator->second);
|
||||
const auto& blockLink = blockLinkIterator->second;
|
||||
auto referringBlock = m_blockLookup.FindBlockAt(blockLink.address);
|
||||
if(referringBlock->IsEmpty()) continue;
|
||||
referringBlock->LinkNextBlock(block);
|
||||
referringBlock->LinkBlock(blockLink.slot, block);
|
||||
}
|
||||
m_pendingNextBlockLinks.erase(lowerBound, upperBound);
|
||||
}
|
||||
{
|
||||
auto lowerBound = m_pendingBranchBlockLinks.lower_bound(startAddress);
|
||||
auto upperBound = m_pendingBranchBlockLinks.upper_bound(startAddress);
|
||||
for(auto blockLinkIterator = lowerBound; blockLinkIterator != upperBound; blockLinkIterator++)
|
||||
{
|
||||
auto referringBlock = m_blockLookup.FindBlockAt(blockLinkIterator->second);
|
||||
if(referringBlock->IsEmpty()) continue;
|
||||
referringBlock->LinkBranchBlock(block);
|
||||
}
|
||||
m_pendingBranchBlockLinks.erase(lowerBound, upperBound);
|
||||
m_pendingBlockLinks.erase(lowerBound, upperBound);
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,8 +395,7 @@ protected:
|
||||
|
||||
BlockList m_blocks;
|
||||
BasicBlockPtr m_emptyBlock;
|
||||
BlockLinkMap m_pendingNextBlockLinks;
|
||||
BlockLinkMap m_pendingBranchBlockLinks;
|
||||
BlockLinkMap m_pendingBlockLinks;
|
||||
CMIPS& m_context;
|
||||
uint32 m_maxAddress = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user