mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
Stay inside block when it's branch target is itself.
This commit is contained in:
parent
e2683a6246
commit
930e90a9a2
8 changed files with 67 additions and 20 deletions
|
@ -194,7 +194,23 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool loopsOnItself = [&]() {
|
||||||
|
if(m_begin == m_end)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32 branchInstAddr = m_end - 4;
|
||||||
|
uint32 inst = m_context.m_pMemoryMap->GetInstruction(branchInstAddr);
|
||||||
|
if(m_context.m_pArch->IsInstructionBranch(&m_context, branchInstAddr, inst) != MIPS_BRANCH_NORMAL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32 target = m_context.m_pArch->GetInstructionEffectiveAddress(&m_context, branchInstAddr, inst);
|
||||||
|
return target == m_begin;
|
||||||
|
}();
|
||||||
|
|
||||||
CompileProlog(jitter);
|
CompileProlog(jitter);
|
||||||
|
jitter->MarkFirstBlockLabel();
|
||||||
|
|
||||||
for(uint32 address = m_begin; address <= m_end; address += 4)
|
for(uint32 address = m_begin; address <= m_end; address += 4)
|
||||||
{
|
{
|
||||||
|
@ -206,8 +222,8 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
|
||||||
assert(jitter->IsStackEmpty());
|
assert(jitter->IsStackEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
jitter->MarkFinalBlockLabel();
|
jitter->MarkLastBlockLabel();
|
||||||
CompileEpilog(jitter);
|
CompileEpilog(jitter, loopsOnItself);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBasicBlock::CompileProlog(CMipsJitter* jitter)
|
void CBasicBlock::CompileProlog(CMipsJitter* jitter)
|
||||||
|
@ -228,7 +244,7 @@ void CBasicBlock::CompileProlog(CMipsJitter* jitter)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
void CBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
|
||||||
{
|
{
|
||||||
//Update cycle quota
|
//Update cycle quota
|
||||||
jitter->PushRel(offsetof(CMIPS, m_State.cycleQuota));
|
jitter->PushRel(offsetof(CMIPS, m_State.cycleQuota));
|
||||||
|
@ -258,15 +274,28 @@ void CBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
||||||
jitter->PushCst(MIPS_INVALID_PC);
|
jitter->PushCst(MIPS_INVALID_PC);
|
||||||
jitter->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
jitter->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
||||||
|
|
||||||
#if !defined(AOT_BUILD_CACHE) && !defined(__EMSCRIPTEN__)
|
if(loopsOnItself)
|
||||||
jitter->PushRel(offsetof(CMIPS, m_State.nHasException));
|
|
||||||
jitter->PushCst(0);
|
|
||||||
jitter->BeginIf(Jitter::CONDITION_EQ);
|
|
||||||
{
|
{
|
||||||
jitter->JumpToDynamic(reinterpret_cast<void*>(&NextBlockTrampoline));
|
jitter->PushRel(offsetof(CMIPS, m_State.nHasException));
|
||||||
|
jitter->PushCst(0);
|
||||||
|
jitter->BeginIf(Jitter::CONDITION_EQ);
|
||||||
|
{
|
||||||
|
jitter->Goto(jitter->GetFirstBlockLabel());
|
||||||
|
}
|
||||||
|
jitter->EndIf();
|
||||||
}
|
}
|
||||||
jitter->EndIf();
|
else
|
||||||
|
{
|
||||||
|
#if !defined(AOT_BUILD_CACHE) && !defined(__EMSCRIPTEN__)
|
||||||
|
jitter->PushRel(offsetof(CMIPS, m_State.nHasException));
|
||||||
|
jitter->PushCst(0);
|
||||||
|
jitter->BeginIf(Jitter::CONDITION_EQ);
|
||||||
|
{
|
||||||
|
jitter->JumpToDynamic(reinterpret_cast<void*>(&NextBlockTrampoline));
|
||||||
|
}
|
||||||
|
jitter->EndIf();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
jitter->Else();
|
jitter->Else();
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,7 +102,7 @@ protected:
|
||||||
CMIPS& m_context;
|
CMIPS& m_context;
|
||||||
|
|
||||||
virtual void CompileProlog(CMipsJitter*);
|
virtual void CompileProlog(CMipsJitter*);
|
||||||
virtual void CompileEpilog(CMipsJitter*);
|
virtual void CompileEpilog(CMipsJitter*, bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleExternalFunctionReference(uintptr_t, uint32, Jitter::CCodeGen::SYMBOL_REF_TYPE);
|
void HandleExternalFunctionReference(uintptr_t, uint32, Jitter::CCodeGen::SYMBOL_REF_TYPE);
|
||||||
|
|
|
@ -180,7 +180,7 @@ void CMIPSInstructionFactory::BranchLikely(Jitter::CONDITION condition)
|
||||||
}
|
}
|
||||||
m_codeGen->Else();
|
m_codeGen->Else();
|
||||||
{
|
{
|
||||||
m_codeGen->Goto(m_codeGen->GetFinalBlockLabel());
|
m_codeGen->Goto(m_codeGen->GetLastBlockLabel());
|
||||||
}
|
}
|
||||||
m_codeGen->EndIf();
|
m_codeGen->EndIf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
||||||
: CJitter(codeGen)
|
: CJitter(codeGen)
|
||||||
|
, m_firstBlockLabel(-1)
|
||||||
, m_lastBlockLabel(-1)
|
, m_lastBlockLabel(-1)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < 4; i++)
|
for(unsigned int i = 0; i < 4; i++)
|
||||||
|
@ -17,6 +18,7 @@ CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
||||||
void CMipsJitter::Begin()
|
void CMipsJitter::Begin()
|
||||||
{
|
{
|
||||||
CJitter::Begin();
|
CJitter::Begin();
|
||||||
|
m_firstBlockLabel = -1;
|
||||||
m_lastBlockLabel = -1;
|
m_lastBlockLabel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +65,13 @@ void CMipsJitter::PushRel64(size_t offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Jitter::CJitter::LABEL CMipsJitter::GetFinalBlockLabel()
|
Jitter::CJitter::LABEL CMipsJitter::GetFirstBlockLabel()
|
||||||
|
{
|
||||||
|
assert(m_firstBlockLabel != -1);
|
||||||
|
return m_firstBlockLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
Jitter::CJitter::LABEL CMipsJitter::GetLastBlockLabel()
|
||||||
{
|
{
|
||||||
if(m_lastBlockLabel == -1)
|
if(m_lastBlockLabel == -1)
|
||||||
{
|
{
|
||||||
|
@ -72,7 +80,13 @@ Jitter::CJitter::LABEL CMipsJitter::GetFinalBlockLabel()
|
||||||
return m_lastBlockLabel;
|
return m_lastBlockLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMipsJitter::MarkFinalBlockLabel()
|
void CMipsJitter::MarkFirstBlockLabel()
|
||||||
|
{
|
||||||
|
m_firstBlockLabel = CreateLabel();
|
||||||
|
MarkLabel(m_firstBlockLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMipsJitter::MarkLastBlockLabel()
|
||||||
{
|
{
|
||||||
if(m_lastBlockLabel != -1)
|
if(m_lastBlockLabel != -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,8 +15,11 @@ public:
|
||||||
|
|
||||||
void SetVariableAsConstant(size_t, uint32);
|
void SetVariableAsConstant(size_t, uint32);
|
||||||
|
|
||||||
LABEL GetFinalBlockLabel();
|
LABEL GetFirstBlockLabel();
|
||||||
void MarkFinalBlockLabel();
|
LABEL GetLastBlockLabel();
|
||||||
|
|
||||||
|
void MarkFirstBlockLabel();
|
||||||
|
void MarkLastBlockLabel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct VARIABLESTATUS
|
struct VARIABLESTATUS
|
||||||
|
@ -31,5 +34,6 @@ private:
|
||||||
void SetVariableStatus(size_t, const VARIABLESTATUS&);
|
void SetVariableStatus(size_t, const VARIABLESTATUS&);
|
||||||
|
|
||||||
VariableStatusMap m_variableStatus;
|
VariableStatusMap m_variableStatus;
|
||||||
LABEL m_lastBlockLabel;
|
LABEL m_firstBlockLabel = -1;
|
||||||
|
LABEL m_lastBlockLabel = -1;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "EeBasicBlock.h"
|
#include "EeBasicBlock.h"
|
||||||
|
|
||||||
void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
|
||||||
{
|
{
|
||||||
if(IsIdleLoopBlock())
|
if(IsIdleLoopBlock())
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
||||||
jitter->PullRel(offsetof(CMIPS, m_State.nHasException));
|
jitter->PullRel(offsetof(CMIPS, m_State.nHasException));
|
||||||
}
|
}
|
||||||
|
|
||||||
CBasicBlock::CompileEpilog(jitter);
|
CBasicBlock::CompileEpilog(jitter, loopsOnItself);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CEeBasicBlock::IsIdleLoopBlock() const
|
bool CEeBasicBlock::IsIdleLoopBlock() const
|
||||||
|
|
|
@ -8,7 +8,7 @@ public:
|
||||||
using CBasicBlock::CBasicBlock;
|
using CBasicBlock::CBasicBlock;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CompileEpilog(CMipsJitter*) override;
|
void CompileEpilog(CMipsJitter*, bool) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsIdleLoopBlock() const;
|
bool IsIdleLoopBlock() const;
|
||||||
|
|
|
@ -217,7 +217,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
|
||||||
jitter->PullRel(offsetof(CMIPS, m_State.pipeTime));
|
jitter->PullRel(offsetof(CMIPS, m_State.pipeTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
CompileEpilog(jitter);
|
CompileEpilog(jitter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVuBasicBlock::IsConditionalBranch(uint32 opcodeLo)
|
bool CVuBasicBlock::IsConditionalBranch(uint32 opcodeLo)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue