Fix join entry loadstore zp if accu is used cross block

This commit is contained in:
drmortalwombat 2023-11-16 21:52:06 +01:00
parent 157f9c00e5
commit 38e1cd0bab

View File

@ -20235,75 +20235,86 @@ bool NativeCodeBasicBlock::JoinEntryLoadStoreZP(void)
CheckLive(); CheckLive();
for (int i = 0; i + 1 < mIns.Size(); i++) if (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X])
{ {
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) || for (int i = 0; i + 1 < mIns.Size(); i++)
mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))
{ {
int saddr = mIns[i].mAddress, daddr = mIns[i + 1].mAddress; if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) ||
if (!ReferencesZeroPage(saddr, 0, i) && !ReferencesZeroPage(daddr, 0, i)) mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))
{ {
int n = 0; int saddr = mIns[i].mAddress, daddr = mIns[i + 1].mAddress;
for (int j = 0; j < mEntryBlocks.Size(); j++) if (!ReferencesZeroPage(saddr, 0, i) && !ReferencesZeroPage(daddr, 0, i))
{
if (mEntryBlocks[j]->CanJoinEntryLoadStoreZP(saddr, daddr))
n++;
}
if (n == mEntryBlocks.Size())
{ {
int n = 0;
for (int j = 0; j < mEntryBlocks.Size(); j++) for (int j = 0; j < mEntryBlocks.Size(); j++)
{ {
mEntryBlocks[j]->DoJoinEntryLoadStoreZP(saddr, daddr); if (mEntryBlocks[j]->CanJoinEntryLoadStoreZP(saddr, daddr))
mEntryBlocks[j]->mExitRequiredRegs += daddr; n++;
} }
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
}
else if (n >= 2)
{
NativeCodeBasicBlock* xblock = mProc->AllocateBlock();
int j = 0; if (n == mEntryBlocks.Size())
while (j < mEntryBlocks.Size())
{ {
NativeCodeBasicBlock* eb = mEntryBlocks[j]; for (int j = 0; j < mEntryBlocks.Size(); j++)
if (eb->CanJoinEntryLoadStoreZP(saddr, daddr))
{ {
eb->DoJoinEntryLoadStoreZP(saddr, daddr); mEntryBlocks[j]->DoJoinEntryLoadStoreZP(saddr, daddr);
eb->mExitRequiredRegs += daddr; mEntryBlocks[j]->mExitRequiredRegs += daddr;
j++; }
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
}
else if (n >= 2)
{
NativeCodeBasicBlock* xblock = mProc->AllocateBlock();
int j = 0;
while (j < mEntryBlocks.Size())
{
NativeCodeBasicBlock* eb = mEntryBlocks[j];
if (eb->CanJoinEntryLoadStoreZP(saddr, daddr))
{
eb->DoJoinEntryLoadStoreZP(saddr, daddr);
eb->mExitRequiredRegs += daddr;
j++;
}
else
{
if (eb->mTrueJump == this)
eb->mTrueJump = xblock;
if (eb->mFalseJump == this)
eb->mFalseJump = xblock;
mEntryBlocks.Remove(j);
xblock->mEntryBlocks.Push(eb);
xblock->mNumEntries++;
}
}
xblock->mEntryRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs += daddr;
if (!mEntryRequiredRegs[CPU_REG_A])
{
xblock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDA, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
xblock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
} }
else else
{ {
if (eb->mTrueJump == this) xblock->mIns.Push(NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDX, ASMIM_ZERO_PAGE, mIns[i + 0].mAddress));
eb->mTrueJump = xblock; xblock->mIns.Push(NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_STX, ASMIM_ZERO_PAGE, mIns[i + 1].mAddress));
if (eb->mFalseJump == this)
eb->mFalseJump = xblock;
mEntryBlocks.Remove(j);
xblock->mEntryBlocks.Push(eb);
xblock->mNumEntries++;
} }
xblock->Close(mIns[i].mIns, this, nullptr, ASMIT_JMP);
mEntryBlocks.Push(xblock);
mNumEntries++;
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
} }
xblock->mEntryRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs += daddr;
xblock->mIns.Push(mIns[i + 0]);
xblock->mIns.Push(mIns[i + 1]);
xblock->Close(mIns[i].mIns, this, nullptr, ASMIT_JMP);
mEntryBlocks.Push(xblock);
mNumEntries++;
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
} }
} }
} }
@ -42715,7 +42726,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "parse_statement"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_builtin");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -43623,7 +43634,6 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
#if _DEBUG #if _DEBUG
ResetVisited(); ResetVisited();
mEntryBlock->CheckBlocks(true); mEntryBlock->CheckBlocks(true);
@ -43651,19 +43661,20 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
if (step > 6) if (step > 6)
{ {
ResetVisited(); ResetVisited();
if (mEntryBlock->JoinEntryLoadStoreZP()) if (mEntryBlock->JoinEntryLoadStoreZP())
changed = true; changed = true;
} }
#endif #endif
#if _DEBUG #if _DEBUG
ResetVisited(); ResetVisited();
mEntryBlock->CheckBlocks(true); mEntryBlock->CheckBlocks(true);
#endif #endif
#if 1 #if 1
if (step == 3 || step == 4) if (step == 3 || step == 4)
{ {
@ -43731,6 +43742,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#if 1 #if 1
if (step == 5 || step == 6) if (step == 5 || step == 6)
{ {