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;
|
||||
}
|
||||
|
||||
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);
|
||||
jitter->MarkFirstBlockLabel();
|
||||
|
||||
for(uint32 address = m_begin; address <= m_end; address += 4)
|
||||
{
|
||||
|
@ -206,8 +222,8 @@ void CBasicBlock::CompileRange(CMipsJitter* jitter)
|
|||
assert(jitter->IsStackEmpty());
|
||||
}
|
||||
|
||||
jitter->MarkFinalBlockLabel();
|
||||
CompileEpilog(jitter);
|
||||
jitter->MarkLastBlockLabel();
|
||||
CompileEpilog(jitter, loopsOnItself);
|
||||
}
|
||||
|
||||
void CBasicBlock::CompileProlog(CMipsJitter* jitter)
|
||||
|
@ -228,7 +244,7 @@ void CBasicBlock::CompileProlog(CMipsJitter* jitter)
|
|||
#endif
|
||||
}
|
||||
|
||||
void CBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
||||
void CBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
|
||||
{
|
||||
//Update cycle quota
|
||||
jitter->PushRel(offsetof(CMIPS, m_State.cycleQuota));
|
||||
|
@ -258,15 +274,28 @@ void CBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
|||
jitter->PushCst(MIPS_INVALID_PC);
|
||||
jitter->PullRel(offsetof(CMIPS, m_State.nDelayedJumpAddr));
|
||||
|
||||
#if !defined(AOT_BUILD_CACHE) && !defined(__EMSCRIPTEN__)
|
||||
jitter->PushRel(offsetof(CMIPS, m_State.nHasException));
|
||||
jitter->PushCst(0);
|
||||
jitter->BeginIf(Jitter::CONDITION_EQ);
|
||||
if(loopsOnItself)
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
jitter->Else();
|
||||
{
|
||||
|
|
|
@ -102,7 +102,7 @@ protected:
|
|||
CMIPS& m_context;
|
||||
|
||||
virtual void CompileProlog(CMipsJitter*);
|
||||
virtual void CompileEpilog(CMipsJitter*);
|
||||
virtual void CompileEpilog(CMipsJitter*, bool);
|
||||
|
||||
private:
|
||||
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->Goto(m_codeGen->GetFinalBlockLabel());
|
||||
m_codeGen->Goto(m_codeGen->GetLastBlockLabel());
|
||||
}
|
||||
m_codeGen->EndIf();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
||||
: CJitter(codeGen)
|
||||
, m_firstBlockLabel(-1)
|
||||
, m_lastBlockLabel(-1)
|
||||
{
|
||||
for(unsigned int i = 0; i < 4; i++)
|
||||
|
@ -17,6 +18,7 @@ CMipsJitter::CMipsJitter(Jitter::CCodeGen* codeGen)
|
|||
void CMipsJitter::Begin()
|
||||
{
|
||||
CJitter::Begin();
|
||||
m_firstBlockLabel = -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)
|
||||
{
|
||||
|
@ -72,7 +80,13 @@ Jitter::CJitter::LABEL CMipsJitter::GetFinalBlockLabel()
|
|||
return m_lastBlockLabel;
|
||||
}
|
||||
|
||||
void CMipsJitter::MarkFinalBlockLabel()
|
||||
void CMipsJitter::MarkFirstBlockLabel()
|
||||
{
|
||||
m_firstBlockLabel = CreateLabel();
|
||||
MarkLabel(m_firstBlockLabel);
|
||||
}
|
||||
|
||||
void CMipsJitter::MarkLastBlockLabel()
|
||||
{
|
||||
if(m_lastBlockLabel != -1)
|
||||
{
|
||||
|
|
|
@ -15,8 +15,11 @@ public:
|
|||
|
||||
void SetVariableAsConstant(size_t, uint32);
|
||||
|
||||
LABEL GetFinalBlockLabel();
|
||||
void MarkFinalBlockLabel();
|
||||
LABEL GetFirstBlockLabel();
|
||||
LABEL GetLastBlockLabel();
|
||||
|
||||
void MarkFirstBlockLabel();
|
||||
void MarkLastBlockLabel();
|
||||
|
||||
private:
|
||||
struct VARIABLESTATUS
|
||||
|
@ -31,5 +34,6 @@ private:
|
|||
void SetVariableStatus(size_t, const VARIABLESTATUS&);
|
||||
|
||||
VariableStatusMap m_variableStatus;
|
||||
LABEL m_lastBlockLabel;
|
||||
LABEL m_firstBlockLabel = -1;
|
||||
LABEL m_lastBlockLabel = -1;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "EeBasicBlock.h"
|
||||
|
||||
void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
||||
void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter, bool loopsOnItself)
|
||||
{
|
||||
if(IsIdleLoopBlock())
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ void CEeBasicBlock::CompileEpilog(CMipsJitter* jitter)
|
|||
jitter->PullRel(offsetof(CMIPS, m_State.nHasException));
|
||||
}
|
||||
|
||||
CBasicBlock::CompileEpilog(jitter);
|
||||
CBasicBlock::CompileEpilog(jitter, loopsOnItself);
|
||||
}
|
||||
|
||||
bool CEeBasicBlock::IsIdleLoopBlock() const
|
||||
|
|
|
@ -8,7 +8,7 @@ public:
|
|||
using CBasicBlock::CBasicBlock;
|
||||
|
||||
protected:
|
||||
void CompileEpilog(CMipsJitter*) override;
|
||||
void CompileEpilog(CMipsJitter*, bool) override;
|
||||
|
||||
private:
|
||||
bool IsIdleLoopBlock() const;
|
||||
|
|
|
@ -217,7 +217,7 @@ void CVuBasicBlock::CompileRange(CMipsJitter* jitter)
|
|||
jitter->PullRel(offsetof(CMIPS, m_State.pipeTime));
|
||||
}
|
||||
|
||||
CompileEpilog(jitter);
|
||||
CompileEpilog(jitter, false);
|
||||
}
|
||||
|
||||
bool CVuBasicBlock::IsConditionalBranch(uint32 opcodeLo)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue