2007-12-09 22:01:01 +00:00
|
|
|
#include "BasicBlock.h"
|
|
|
|
#include "MemStream.h"
|
|
|
|
#include "offsetof_def.h"
|
2010-08-11 03:47:19 +00:00
|
|
|
#include "MipsJitter.h"
|
|
|
|
#include "Jitter_CodeGenFactory.h"
|
2007-12-09 22:01:01 +00:00
|
|
|
|
|
|
|
using namespace Framework;
|
|
|
|
|
|
|
|
CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end) :
|
|
|
|
m_begin(begin),
|
|
|
|
m_end(end),
|
|
|
|
m_context(context),
|
2010-08-11 03:47:19 +00:00
|
|
|
m_function(NULL),
|
2008-06-30 18:58:04 +00:00
|
|
|
m_selfLoopCount(0),
|
2010-11-17 03:59:29 +00:00
|
|
|
m_refCount(0),
|
2008-06-30 18:58:04 +00:00
|
|
|
m_branchHint(NULL)
|
2007-12-09 22:01:01 +00:00
|
|
|
{
|
|
|
|
assert(m_end >= m_begin);
|
|
|
|
}
|
|
|
|
|
|
|
|
CBasicBlock::~CBasicBlock()
|
|
|
|
{
|
2010-08-11 03:47:19 +00:00
|
|
|
if(m_function != NULL)
|
|
|
|
{
|
|
|
|
delete m_function;
|
|
|
|
m_function = NULL;
|
|
|
|
}
|
2007-12-09 22:01:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CBasicBlock::Compile()
|
|
|
|
{
|
|
|
|
CMemStream stream;
|
|
|
|
{
|
2010-08-11 03:47:19 +00:00
|
|
|
static CMipsJitter* jitter = NULL;
|
|
|
|
if(jitter == NULL)
|
|
|
|
{
|
|
|
|
Jitter::CCodeGen* codeGen = Jitter::CreateCodeGen();
|
|
|
|
jitter = new CMipsJitter(codeGen);
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
jitter->SetVariableAsConstant(
|
|
|
|
offsetof(CMIPS, m_State.nGPR[CMIPS::R0].nV[i]),
|
|
|
|
0
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
jitter->SetStream(&stream);
|
|
|
|
jitter->Begin();
|
|
|
|
CompileRange(jitter);
|
|
|
|
// codeGen.DumpVariables(0);
|
|
|
|
// codeGen.EndQuota();
|
|
|
|
jitter->End();
|
2007-12-09 22:01:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-11 03:47:19 +00:00
|
|
|
m_function = new CMemoryFunction(stream.GetBuffer(), stream.GetSize());
|
2007-12-09 22:01:01 +00:00
|
|
|
}
|
|
|
|
|
2010-08-11 03:47:19 +00:00
|
|
|
void CBasicBlock::CompileRange(CMipsJitter* jitter)
|
2009-06-06 15:38:03 +00:00
|
|
|
{
|
|
|
|
for(uint32 address = m_begin; address <= m_end; address += 4)
|
|
|
|
{
|
|
|
|
m_context.m_pArch->CompileInstruction(
|
|
|
|
address,
|
2010-08-11 03:47:19 +00:00
|
|
|
jitter,
|
2009-06-06 15:38:03 +00:00
|
|
|
&m_context);
|
|
|
|
//Sanity check
|
2010-08-11 03:47:19 +00:00
|
|
|
assert(jitter->IsStackEmpty());
|
2009-06-06 15:38:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-09 22:01:01 +00:00
|
|
|
unsigned int CBasicBlock::Execute()
|
|
|
|
{
|
2010-08-11 03:47:19 +00:00
|
|
|
(*m_function)(&m_context);
|
2007-12-11 21:54:23 +00:00
|
|
|
|
2007-12-09 22:01:01 +00:00
|
|
|
if(m_context.m_State.nDelayedJumpAddr != MIPS_INVALID_PC)
|
|
|
|
{
|
|
|
|
m_context.m_State.nPC = m_context.m_State.nDelayedJumpAddr;
|
|
|
|
m_context.m_State.nDelayedJumpAddr = MIPS_INVALID_PC;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_context.m_State.nPC = m_end + 4;
|
|
|
|
}
|
|
|
|
|
2011-12-26 05:52:20 +00:00
|
|
|
assert((m_context.m_State.nGPR[CMIPS::RA].nV0 & 3) == 0);
|
2011-12-06 03:13:21 +00:00
|
|
|
assert(m_context.m_State.nCOP2[0].nV0 == 0x00000000);
|
|
|
|
assert(m_context.m_State.nCOP2[0].nV1 == 0x00000000);
|
|
|
|
assert(m_context.m_State.nCOP2[0].nV2 == 0x00000000);
|
|
|
|
assert(m_context.m_State.nCOP2[0].nV3 == 0x3F800000);
|
|
|
|
|
2007-12-09 22:01:01 +00:00
|
|
|
return ((m_end - m_begin) / 4) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CBasicBlock::GetBeginAddress() const
|
|
|
|
{
|
|
|
|
return m_begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CBasicBlock::GetEndAddress() const
|
|
|
|
{
|
|
|
|
return m_end;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CBasicBlock::IsCompiled() const
|
|
|
|
{
|
2010-08-11 03:47:19 +00:00
|
|
|
return m_function != NULL;
|
2007-12-09 22:01:01 +00:00
|
|
|
}
|
2008-03-19 11:30:45 +00:00
|
|
|
|
|
|
|
unsigned int CBasicBlock::GetSelfLoopCount() const
|
|
|
|
{
|
|
|
|
return m_selfLoopCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBasicBlock::SetSelfLoopCount(unsigned int selfLoopCount)
|
|
|
|
{
|
|
|
|
m_selfLoopCount = selfLoopCount;
|
|
|
|
}
|
2008-06-30 18:58:04 +00:00
|
|
|
|
2010-11-17 03:59:29 +00:00
|
|
|
BasicBlockPtr CBasicBlock::GetBranchHint() const
|
2008-06-30 18:58:04 +00:00
|
|
|
{
|
|
|
|
return m_branchHint;
|
|
|
|
}
|
|
|
|
|
2010-11-17 03:59:29 +00:00
|
|
|
void CBasicBlock::SetBranchHint(const BasicBlockPtr& branchHint)
|
2008-06-30 18:58:04 +00:00
|
|
|
{
|
|
|
|
m_branchHint = branchHint;
|
|
|
|
}
|