Optimize loops with shift

This commit is contained in:
drmortalwombat 2023-03-14 17:49:17 +01:00
parent 175520c885
commit 11c624fb4a
2 changed files with 143 additions and 3 deletions

View File

@ -22252,14 +22252,77 @@ bool NativeCodeBasicBlock::MergeXYSameValue(int from)
return false; return false;
} }
int NativeCodeBasicBlock::RetrieveZPValue(int reg, int at) const
{
while (at >= 0 && !mIns[at].ChangesZeroPage(reg))
at--;
if (at >= 0)
{
if (mIns[at].mType == ASMIT_STA)
return RetrieveAValue(at);
else if (mIns[at].mType == ASMIT_STX)
return RetrieveXValue(at);
else if (mIns[at].mType == ASMIT_STY)
return RetrieveYValue(at);
else
return -1;
}
else if (mEntryBlocks.Size() == 1)
return mEntryBlocks[0]->RetrieveZPValue(reg, mEntryBlocks[0]->mIns.Size() - 1);
else
return -1;
}
int NativeCodeBasicBlock::RetrieveYValue(int at) const int NativeCodeBasicBlock::RetrieveYValue(int at) const
{ {
while (at > 0 && !mIns[at].ChangesYReg()) while (at >= 0 && !mIns[at].ChangesYReg())
at--; at--;
if (at >= 0)
{
if (mIns[at].mType == ASMIT_LDY && mIns[at].mMode == ASMIM_IMMEDIATE) if (mIns[at].mType == ASMIT_LDY && mIns[at].mMode == ASMIM_IMMEDIATE)
return mIns[at].mAddress; return mIns[at].mAddress;
else else
return -1; return -1;
}
else if (mEntryBlocks.Size() == 1)
return mEntryBlocks[0]->RetrieveYValue(mEntryBlocks[0]->mIns.Size() - 1);
else
return -1;
}
int NativeCodeBasicBlock::RetrieveXValue(int at) const
{
while (at >= 0 && !mIns[at].ChangesXReg())
at--;
if (at >= 0)
{
if (mIns[at].mType == ASMIT_LDX && mIns[at].mMode == ASMIM_IMMEDIATE)
return mIns[at].mAddress;
else
return -1;
}
else if (mEntryBlocks.Size() == 1)
return mEntryBlocks[0]->RetrieveXValue(mEntryBlocks[0]->mIns.Size() - 1);
else
return -1;
}
int NativeCodeBasicBlock::RetrieveAValue(int at) const
{
while (at >= 0 && !mIns[at].ChangesAccu())
at--;
if (at >= 0)
{
if (mIns[at].mType == ASMIT_LDA && mIns[at].mMode == ASMIM_IMMEDIATE)
return mIns[at].mAddress;
else
return -1;
}
else if (mEntryBlocks.Size() == 1)
return mEntryBlocks[0]->RetrieveAValue(mEntryBlocks[0]->mIns.Size() - 1);
else
return -1;
} }
void NativeCodeBasicBlock::InsertLoadYImmediate(int at, int val) void NativeCodeBasicBlock::InsertLoadYImmediate(int at, int val)
@ -27432,6 +27495,42 @@ bool NativeCodeBasicBlock::SimpleLoopReversal(NativeCodeProcedure* proc)
CheckLive(); CheckLive();
if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 1 &&
mTrueJump->mBranch == ASMIT_BNE)
{
NativeCodeBasicBlock* lb = mTrueJump;
int lbs = lb->mIns.Size();
if ((lb->mIns[lbs - 2].mType == ASMIT_ROL || lb->mIns[lbs - 2].mType == ASMIT_ROR) && lb->mIns[lbs - 2].mMode == ASMIM_ZERO_PAGE &&
lb->mIns[lbs - 1].mType == ASMIT_DEC && lb->mIns[lbs - 1].mMode == ASMIM_ZERO_PAGE && !(lb->mIns[lbs - 1].mLive & LIVE_CPU_REG_C))
{
if (!lb->ReferencesZeroPage(lb->mIns[lbs - 1].mAddress, 0, lbs - 1) && !lb->ReferencesZeroPage(lb->mIns[lbs - 2].mAddress, 0, lbs - 2) &&
!lb->mFalseJump->mEntryRequiredRegs[lb->mIns[lbs - 1].mAddress])
{
int lcount = RetrieveZPValue(lb->mIns[lbs - 1].mAddress, mIns.Size() - 1);
int lshift = RetrieveZPValue(lb->mIns[lbs - 2].mAddress, mIns.Size() - 1);
if (lcount <= 8 && lshift == 0)
{
if (!mExitRequiredRegs[CPU_REG_A])
{
if (lb->mIns[lbs - 2].mType == ASMIT_ROR)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 1 << (lcount - 1)));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 1 << (8 - lcount)));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, lb->mIns[lbs - 2].mAddress));
lb->mBranch = ASMIT_BCC;
lb->mIns[lbs - 1].mType = ASMIT_NOP; lb->mIns[lbs - 1].mMode = ASMIM_IMPLIED;
lb->mIns[lbs - 2].mLive |= LIVE_CPU_REG_C;
changed = true;
}
}
}
}
}
if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 1 && if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 1 &&
mTrueJump->mBranch == ASMIT_BCC && !mExitRequiredRegs[CPU_REG_C]) mTrueJump->mBranch == ASMIT_BCC && !mExitRequiredRegs[CPU_REG_C])
{ {
@ -27566,6 +27665,44 @@ bool NativeCodeBasicBlock::SimpleLoopReversal(NativeCodeProcedure* proc)
} }
} }
if (mTrueJump && !mFalseJump && mTrueJump->mTrueJump == mTrueJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 2 &&
mTrueJump->mBranch == ASMIT_BCC)
{
NativeCodeBasicBlock* lb = mTrueJump;
int lbs = lb->mIns.Size();
if ((lb->mIns[lbs - 3].mType == ASMIT_ROL || lb->mIns[lbs - 3].mType == ASMIT_ROR) && lb->mIns[lbs - 3].mMode == ASMIM_ZERO_PAGE &&
lb->mIns[lbs - 2].mType == ASMIT_INY &&
lb->mIns[lbs - 1].mType == ASMIT_CPY && lb->mIns[lbs - 1].mMode == ASMIM_IMMEDIATE)
{
if (!lb->ReferencesZeroPage(lb->mIns[lbs - 3].mAddress, 0, lbs - 3))
{
int ystart = RetrieveYValue(mIns.Size() - 1);
int lcount = lb->mIns[lbs - 1].mAddress - ystart;
int lshift = RetrieveZPValue(lb->mIns[lbs - 3].mAddress, mIns.Size() - 1);
if (ystart >= 0 && lcount <= 8 && lshift == 0)
{
if (!mExitRequiredRegs[CPU_REG_A])
{
if (lb->mIns[lbs - 2].mType == ASMIT_ROR)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 1 << (lcount - 1)));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 1 << (8 - lcount)));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, lb->mIns[lbs - 3].mAddress));
lb->mBranch = ASMIT_BCC;
lb->mIns[lbs - 1].mType = ASMIT_NOP; lb->mIns[lbs - 1].mMode = ASMIM_IMPLIED;
lb->mIns[lbs - 2].mLive |= LIVE_CPU_REG_C;
lb->mIns[lbs - 3].mLive |= LIVE_CPU_REG_C;
changed = true;
}
}
}
}
}
if (mTrueJump && mTrueJump->SimpleLoopReversal(proc)) if (mTrueJump && mTrueJump->SimpleLoopReversal(proc))
changed = true; changed = true;
if (mFalseJump && mFalseJump->SimpleLoopReversal(proc)) if (mFalseJump && mFalseJump->SimpleLoopReversal(proc))

View File

@ -396,7 +396,10 @@ public:
bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr); bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr);
bool MergeXYSameValue(int from); bool MergeXYSameValue(int from);
void InsertLoadYImmediate(int at, int val); void InsertLoadYImmediate(int at, int val);
int RetrieveAValue(int at) const;
int RetrieveXValue(int at) const;
int RetrieveYValue(int at) const; int RetrieveYValue(int at) const;
int RetrieveZPValue(int reg, int at) const;
bool ReverseReplaceTAX(int at); bool ReverseReplaceTAX(int at);