2017-06-25 15:50:59 -04:00
|
|
|
#pragma once
|
2007-12-06 23:05:38 +00:00
|
|
|
|
2008-07-29 19:01:20 +00:00
|
|
|
#include <list>
|
2007-12-06 23:05:38 +00:00
|
|
|
#include "MIPS.h"
|
|
|
|
#include "BasicBlock.h"
|
|
|
|
|
|
|
|
class CMipsExecutor
|
|
|
|
{
|
|
|
|
public:
|
2018-04-30 21:01:23 +01:00
|
|
|
CMipsExecutor(CMIPS&, uint32);
|
|
|
|
virtual ~CMipsExecutor();
|
2017-06-26 21:06:57 -04:00
|
|
|
|
|
|
|
template <uint32 (*TranslateFunction)(CMIPS*, uint32) = CMIPS::TranslateAddress64>
|
|
|
|
int Execute(int cycles)
|
|
|
|
{
|
|
|
|
assert(TranslateFunction == m_context.m_pAddrTranslator);
|
|
|
|
CBasicBlock* block(nullptr);
|
|
|
|
while(cycles > 0)
|
|
|
|
{
|
|
|
|
uint32 address = TranslateFunction(&m_context, m_context.m_State.nPC);
|
|
|
|
if(!block || address != block->GetBeginAddress())
|
|
|
|
{
|
|
|
|
block = FindBlockStartingAt(address);
|
|
|
|
if(!block)
|
|
|
|
{
|
|
|
|
//We need to partition the space and compile the blocks
|
|
|
|
PartitionFunction(address);
|
|
|
|
block = FindBlockStartingAt(address);
|
|
|
|
assert(block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUGGER_INCLUDED
|
|
|
|
if(!m_breakpointsDisabledOnce && MustBreak()) break;
|
|
|
|
m_breakpointsDisabledOnce = false;
|
|
|
|
#endif
|
|
|
|
cycles -= block->Execute();
|
|
|
|
if(m_context.m_State.nHasException) break;
|
|
|
|
}
|
|
|
|
return cycles;
|
|
|
|
}
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
CBasicBlock* FindBlockAt(uint32) const;
|
|
|
|
CBasicBlock* FindBlockStartingAt(uint32) const;
|
|
|
|
void DeleteBlock(CBasicBlock*);
|
|
|
|
virtual void Reset();
|
|
|
|
void ClearActiveBlocks();
|
|
|
|
virtual void ClearActiveBlocksInRange(uint32, uint32);
|
2007-12-06 23:05:38 +00:00
|
|
|
|
2012-09-29 01:28:23 +00:00
|
|
|
#ifdef DEBUGGER_INCLUDED
|
2018-04-30 21:01:23 +01:00
|
|
|
bool MustBreak() const;
|
|
|
|
void DisableBreakpointsOnce();
|
2012-09-29 01:28:23 +00:00
|
|
|
#endif
|
|
|
|
|
2008-03-24 01:18:20 +00:00
|
|
|
protected:
|
2013-04-14 06:35:40 +00:00
|
|
|
typedef std::shared_ptr<CBasicBlock> BasicBlockPtr;
|
2011-11-24 07:13:30 +00:00
|
|
|
typedef std::list<BasicBlockPtr> BlockList;
|
2007-12-06 23:05:38 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
void CreateBlock(uint32, uint32);
|
|
|
|
virtual BasicBlockPtr BlockFactory(CMIPS&, uint32, uint32);
|
|
|
|
virtual void PartitionFunction(uint32);
|
2007-12-06 23:05:38 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
void ClearActiveBlocksInRangeInternal(uint32, uint32, CBasicBlock*);
|
2012-03-13 06:16:33 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
BlockList m_blocks;
|
|
|
|
CMIPS& m_context;
|
|
|
|
uint32 m_maxAddress = 0;
|
|
|
|
|
|
|
|
CBasicBlock*** m_blockTable = nullptr;
|
|
|
|
uint32 m_subTableCount = 0;
|
2012-09-29 01:28:23 +00:00
|
|
|
|
|
|
|
#ifdef DEBUGGER_INCLUDED
|
2018-04-30 21:01:23 +01:00
|
|
|
bool m_breakpointsDisabledOnce = false;
|
2012-09-29 01:28:23 +00:00
|
|
|
#endif
|
2007-12-06 23:05:38 +00:00
|
|
|
};
|