Optimize loops with shift
This commit is contained in:
parent
175520c885
commit
11c624fb4a
|
@ -22252,12 +22252,75 @@ bool NativeCodeBasicBlock::MergeXYSameValue(int from)
|
|||
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
|
||||
{
|
||||
while (at > 0 && !mIns[at].ChangesYReg())
|
||||
while (at >= 0 && !mIns[at].ChangesYReg())
|
||||
at--;
|
||||
if (mIns[at].mType == ASMIT_LDY && mIns[at].mMode == ASMIM_IMMEDIATE)
|
||||
return mIns[at].mAddress;
|
||||
if (at >= 0)
|
||||
{
|
||||
if (mIns[at].mType == ASMIT_LDY && mIns[at].mMode == ASMIM_IMMEDIATE)
|
||||
return mIns[at].mAddress;
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
@ -27432,6 +27495,42 @@ bool NativeCodeBasicBlock::SimpleLoopReversal(NativeCodeProcedure* proc)
|
|||
|
||||
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 &&
|
||||
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))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->SimpleLoopReversal(proc))
|
||||
|
|
|
@ -396,7 +396,10 @@ public:
|
|||
bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr);
|
||||
bool MergeXYSameValue(int from);
|
||||
void InsertLoadYImmediate(int at, int val);
|
||||
int RetrieveAValue(int at) const;
|
||||
int RetrieveXValue(int at) const;
|
||||
int RetrieveYValue(int at) const;
|
||||
int RetrieveZPValue(int reg, int at) const;
|
||||
|
||||
bool ReverseReplaceTAX(int at);
|
||||
|
||||
|
|
Loading…
Reference in New Issue