Optimize simple search loops
This commit is contained in:
parent
e1a30a25c7
commit
ff1377f7bb
|
@ -6077,6 +6077,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||||
mFalseValueRange[s1].LimitMin(0);
|
mFalseValueRange[s1].LimitMin(0);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mFalseValueRange[s0].LimitMin(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,8 @@ void NativeRegisterDataSet::ResetZeroPage(int addr)
|
||||||
{
|
{
|
||||||
if (mRegs[i].mMode == NRDM_ZERO_PAGE && mRegs[i].mValue == addr)
|
if (mRegs[i].mMode == NRDM_ZERO_PAGE && mRegs[i].mValue == addr)
|
||||||
mRegs[i].Reset();
|
mRegs[i].Reset();
|
||||||
|
else if (mRegs[i].mMode == NRDM_INDIRECT_Y && (mRegs[i].mValue == addr || mRegs[i].mValue + 1 == addr))
|
||||||
|
mRegs[i].Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +85,28 @@ void NativeRegisterDataSet::ResetAbsolute(LinkerObject* linkerObject, int addr)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_REGS; i++)
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
{
|
{
|
||||||
if (mRegs[i].mMode == NRDM_ABSOLUTE && mRegs[i].mLinkerObject == linkerObject && mRegs[i].mValue == addr)
|
if ((mRegs[i].mMode == NRDM_ABSOLUTE || mRegs[i].mMode == NRDM_ABSOLUTE_X || mRegs[i].mMode == NRDM_ABSOLUTE_Y)
|
||||||
|
&& mRegs[i].mLinkerObject == linkerObject && mRegs[i].mValue == addr)
|
||||||
|
mRegs[i].Reset();
|
||||||
|
else if (mRegs[i].mMode == NRDM_INDIRECT_Y)
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRegisterDataSet::ResetX(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
{
|
||||||
|
if (mRegs[i].mMode == NRDM_ABSOLUTE_X)
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeRegisterDataSet::ResetY(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
{
|
||||||
|
if (mRegs[i].mMode == NRDM_ABSOLUTE_Y || mRegs[i].mMode == NRDM_INDIRECT_Y )
|
||||||
mRegs[i].Reset();
|
mRegs[i].Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +115,13 @@ void NativeRegisterDataSet::ResetIndirect(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_REGS; i++)
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
{
|
{
|
||||||
if (mRegs[i].mMode == NRDM_ABSOLUTE)
|
if (mRegs[i].mMode == NRDM_ABSOLUTE ||
|
||||||
|
mRegs[i].mMode == NRDM_ABSOLUTE_X ||
|
||||||
|
mRegs[i].mMode == NRDM_ABSOLUTE_Y ||
|
||||||
|
mRegs[i].mMode == NRDM_INDIRECT_Y )
|
||||||
|
{
|
||||||
mRegs[i].Reset();
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +185,11 @@ void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set)
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mRegs[i].mMode == NRDM_ABSOLUTE_X || mRegs[i].mMode == NRDM_ABSOLUTE_Y || mRegs[i].mMode == NRDM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
mRegs[i].Reset();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
@ -2301,6 +2334,8 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[CPU_REG_X].Reset();
|
data.mRegs[CPU_REG_X].Reset();
|
||||||
data.mRegs[CPU_REG_Y].Reset();
|
data.mRegs[CPU_REG_Y].Reset();
|
||||||
|
|
||||||
|
data.ResetIndirect();
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
data.ResetZeroPage(BC_REG_ACCU + i);
|
data.ResetZeroPage(BC_REG_ACCU + i);
|
||||||
|
@ -2421,7 +2456,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mMode != ASMIM_ZERO_PAGE && mMode != ASMIM_ABSOLUTE)
|
if (mMode != ASMIM_ZERO_PAGE && mMode != ASMIM_ABSOLUTE && mMode != ASMIM_INDIRECT_Y)
|
||||||
data.mRegs[CPU_REG_A].Reset();
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
}
|
}
|
||||||
|
@ -2615,6 +2650,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ASMIT_LDX:
|
case ASMIT_LDX:
|
||||||
|
data.ResetX();
|
||||||
if (mMode == ASMIM_IMMEDIATE)
|
if (mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_X].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_X].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
|
@ -2640,10 +2676,12 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
break;
|
break;
|
||||||
case ASMIT_INX:
|
case ASMIT_INX:
|
||||||
case ASMIT_DEX:
|
case ASMIT_DEX:
|
||||||
|
data.ResetX();
|
||||||
data.mRegs[CPU_REG_X].Reset();
|
data.mRegs[CPU_REG_X].Reset();
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_LDY:
|
case ASMIT_LDY:
|
||||||
|
data.ResetY();
|
||||||
if (mMode == ASMIM_IMMEDIATE)
|
if (mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_Y].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_Y].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
|
@ -2669,6 +2707,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
break;
|
break;
|
||||||
case ASMIT_INY:
|
case ASMIT_INY:
|
||||||
case ASMIT_DEY:
|
case ASMIT_DEY:
|
||||||
|
data.ResetY();
|
||||||
data.mRegs[CPU_REG_Y].Reset();
|
data.mRegs[CPU_REG_Y].Reset();
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
|
@ -2694,6 +2733,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_TAX:
|
case ASMIT_TAX:
|
||||||
|
data.ResetX();
|
||||||
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
|
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
|
||||||
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
|
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
|
@ -2704,6 +2744,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_TAY:
|
case ASMIT_TAY:
|
||||||
|
data.ResetY();
|
||||||
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
|
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
|
||||||
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
|
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
|
@ -3098,12 +3139,45 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress + 1].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress].mValue + 1 == data.mRegs[mAddress + 1].mValue)
|
if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress + 1].mMode == NRDM_ZERO_PAGE && data.mRegs[mAddress].mValue + 1 == data.mRegs[mAddress + 1].mValue)
|
||||||
{
|
{
|
||||||
mAddress = data.mRegs[mAddress].mValue;
|
mAddress = data.mRegs[mAddress].mValue;
|
||||||
|
if (mType == ASMIT_LDA)
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
}
|
}
|
||||||
else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE_ADDRESS && data.mRegs[mAddress + 1].mMode == NRDM_IMMEDIATE_ADDRESS && data.mRegs[mAddress].mLinkerObject == data.mRegs[mAddress + 1].mLinkerObject)
|
else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE_ADDRESS && data.mRegs[mAddress + 1].mMode == NRDM_IMMEDIATE_ADDRESS && data.mRegs[mAddress].mLinkerObject == data.mRegs[mAddress + 1].mLinkerObject)
|
||||||
{
|
{
|
||||||
mMode = ASMIM_ABSOLUTE_Y;
|
mMode = ASMIM_ABSOLUTE_Y;
|
||||||
mLinkerObject = data.mRegs[mAddress].mLinkerObject;
|
mLinkerObject = data.mRegs[mAddress].mLinkerObject;
|
||||||
mAddress = data.mRegs[mAddress + 1].mValue;
|
mAddress = data.mRegs[mAddress + 1].mValue;
|
||||||
|
if (mType == ASMIT_LDA)
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
|
}
|
||||||
|
else if (mType == ASMIT_LDA)
|
||||||
|
{
|
||||||
|
if (!(mFlags & NCIF_VOLATILE))
|
||||||
|
{
|
||||||
|
if (data.mRegs[CPU_REG_A].mMode == NRDM_INDIRECT_Y && data.mRegs[CPU_REG_A].mValue == mAddress)
|
||||||
|
{
|
||||||
|
if (mLive & LIVE_CPU_REG_Z)
|
||||||
|
{
|
||||||
|
mType = ASMIT_ORA;
|
||||||
|
mMode = ASMIM_IMMEDIATE;
|
||||||
|
mAddress = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mType = ASMIT_NOP;
|
||||||
|
mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mMode = NRDM_INDIRECT_Y;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_A].mFlags = mFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ChangesAddress())
|
if (ChangesAddress())
|
||||||
|
@ -12077,6 +12151,85 @@ bool NativeCodeBasicBlock::AlternateXYUsage(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mTrueJump && mFalseJump)
|
||||||
|
{
|
||||||
|
if (!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1 && mTrueJump->mTrueJump->mNumEntries == 2)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
||||||
|
mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mType == ASMIT_AND && !(mTrueJump->mIns[0].mAddress & ~mFalseJump->mIns[0].mAddress))
|
||||||
|
{
|
||||||
|
mTrueJump->mTrueJump->mIns.Insert(0, mFalseJump->mIns[0]);
|
||||||
|
mFalseJump->mIns.SetSize(0, true);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mTrueJump->mIns[0].mType == ASMIT_AND && mFalseJump->mIns[0].mType == ASMIT_LDA && !(mFalseJump->mIns[0].mAddress & ~mTrueJump->mIns[0].mAddress))
|
||||||
|
{
|
||||||
|
mTrueJump->mTrueJump->mIns.Insert(0, mTrueJump->mIns[0]);
|
||||||
|
mTrueJump->mIns.SetSize(0, true);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y] && !mFalseJump->mEntryRequiredRegs[CPU_REG_Y] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
int sz = mIns.Size() - 1;
|
||||||
|
while (sz >= 0 && !mIns[sz].ReferencesYReg())
|
||||||
|
sz--;
|
||||||
|
if (sz >= 0 && mIns[sz].mType == ASMIT_LDY && (mIns[sz].mMode == ASMIM_ZERO_PAGE || mIns[sz].mMode == ASMIM_ABSOLUTE) && !(mIns[sz].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
int i = sz + 1;
|
||||||
|
while (i < mIns.Size() && !mIns[sz].MayBeChangedOnAddress(mIns[i]))
|
||||||
|
i++;
|
||||||
|
if (i == mIns.Size())
|
||||||
|
{
|
||||||
|
mIns[sz].mLive |= mIns[mIns.Size() - 1].mLive;
|
||||||
|
mTrueJump->mIns.Insert(0, mIns[sz]);
|
||||||
|
mIns.Remove(sz);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mTrueJump->mEntryRequiredRegs[CPU_REG_X] && !mFalseJump->mEntryRequiredRegs[CPU_REG_X] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
int sz = mIns.Size() - 1;
|
||||||
|
while (sz >= 0 && !mIns[sz].ReferencesXReg())
|
||||||
|
sz--;
|
||||||
|
if (sz >= 0 && mIns[sz].mType == ASMIT_LDX && (mIns[sz].mMode == ASMIM_ZERO_PAGE || mIns[sz].mMode == ASMIM_ABSOLUTE) && !(mIns[sz].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
int i = sz + 1;
|
||||||
|
while (i < mIns.Size() && !mIns[sz].MayBeChangedOnAddress(mIns[i]))
|
||||||
|
i++;
|
||||||
|
if (i == mIns.Size())
|
||||||
|
{
|
||||||
|
mIns[sz].mLive |= mIns[mIns.Size() - 1].mLive;
|
||||||
|
mTrueJump->mIns.Insert(0, mIns[sz]);
|
||||||
|
mIns.Remove(sz);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (mTrueJump && mTrueJump->SimplifyDiamond(proc))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->SimplifyDiamond(proc))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::Split16BitLoopCount(NativeCodeProcedure* proc)
|
bool NativeCodeBasicBlock::Split16BitLoopCount(NativeCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -20074,6 +20227,75 @@ bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
|
if (mLoopHead && mNumEntries == 2)
|
||||||
|
{
|
||||||
|
if (mTrueJump && mFalseJump &&
|
||||||
|
mFalseJump->mNumEntries == 1 && !mFalseJump->mFalseJump && mFalseJump->mTrueJump == this &&
|
||||||
|
mTrueJump->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock * pred = mEntryBlocks[0];
|
||||||
|
if (pred == mFalseJump)
|
||||||
|
pred = mEntryBlocks[0];
|
||||||
|
NativeCodeBasicBlock * succ = mTrueJump;
|
||||||
|
NativeCodeBasicBlock * body = mFalseJump;
|
||||||
|
|
||||||
|
if (mIns.Size() > 0 && body->mIns.Size() > 0)
|
||||||
|
{
|
||||||
|
int fsz = body->mIns.Size();
|
||||||
|
|
||||||
|
if (mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
body->mIns[fsz - 1].mType == ASMIT_INC && body->mIns[fsz - 1].SameEffectiveAddress(mIns[0]))
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
while (i < mIns.Size() && !mIns[i].ChangesYReg() && !mIns[i].ReferencesZeroPage(mIns[0].mAddress))
|
||||||
|
i++;
|
||||||
|
if (i == mIns.Size())
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while (i + 1 < fsz && !body->mIns[i].ChangesYReg() && !body->mIns[i].ReferencesZeroPage(mIns[0].mAddress))
|
||||||
|
i++;
|
||||||
|
if (i + 1 == fsz)
|
||||||
|
{
|
||||||
|
pred->mIns.Push(mIns[0]);
|
||||||
|
succ->mIns.Insert(0, NativeCodeInstruction(ASMIT_STY, mIns[0]));
|
||||||
|
body->mIns[fsz - 1].mType = ASMIT_INY;
|
||||||
|
body->mIns[fsz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns.Remove(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
for (int i = 0; i < fsz; i++)
|
||||||
|
body->mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->OptimizeFindLoop(proc))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->OptimizeFindLoop(proc))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::OptimizeSelect(NativeCodeProcedure* proc)
|
bool NativeCodeBasicBlock::OptimizeSelect(NativeCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -25088,6 +25310,34 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TAX &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 1 &&
|
||||||
|
mIns[i + 4].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 4]) && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 4].mType = ASMIT_INC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TAX &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||||
|
mIns[i + 4].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 4]) && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 4].mType = ASMIT_DEC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -27229,6 +27479,12 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
changed = true;
|
changed = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->OptimizeFindLoop(this))
|
||||||
|
changed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->ReduceLocalYPressure())
|
if (mEntryBlock->ReduceLocalYPressure())
|
||||||
|
@ -27386,6 +27642,14 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
mEntryBlock->CheckBlocks();
|
mEntryBlock->CheckBlocks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if (step == 5)
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->SimplifyDiamond(this))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (step >= 6)
|
if (step >= 6)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,10 @@ enum NativeRegisterDataMode
|
||||||
NRDM_IMMEDIATE,
|
NRDM_IMMEDIATE,
|
||||||
NRDM_IMMEDIATE_ADDRESS,
|
NRDM_IMMEDIATE_ADDRESS,
|
||||||
NRDM_ZERO_PAGE,
|
NRDM_ZERO_PAGE,
|
||||||
NRDM_ABSOLUTE
|
NRDM_ABSOLUTE,
|
||||||
|
NRDM_ABSOLUTE_X,
|
||||||
|
NRDM_ABSOLUTE_Y,
|
||||||
|
NRDM_INDIRECT_Y
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NativeRegisterData
|
struct NativeRegisterData
|
||||||
|
@ -43,6 +46,8 @@ struct NativeRegisterDataSet
|
||||||
void ResetZeroPage(int addr);
|
void ResetZeroPage(int addr);
|
||||||
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
||||||
void ResetIndirect(void);
|
void ResetIndirect(void);
|
||||||
|
void ResetX(void);
|
||||||
|
void ResetY(void);
|
||||||
void Intersect(const NativeRegisterDataSet& set);
|
void Intersect(const NativeRegisterDataSet& set);
|
||||||
void IntersectMask(const NativeRegisterDataSet& set);
|
void IntersectMask(const NativeRegisterDataSet& set);
|
||||||
};
|
};
|
||||||
|
@ -202,6 +207,8 @@ public:
|
||||||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||||
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
|
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
|
||||||
|
|
||||||
|
bool OptimizeFindLoop(NativeCodeProcedure* proc);
|
||||||
|
|
||||||
void PutByte(uint8 code);
|
void PutByte(uint8 code);
|
||||||
void PutWord(uint16 code);
|
void PutWord(uint16 code);
|
||||||
|
|
||||||
|
@ -373,6 +380,7 @@ public:
|
||||||
|
|
||||||
bool ExpandADCToBranch(NativeCodeProcedure* proc);
|
bool ExpandADCToBranch(NativeCodeProcedure* proc);
|
||||||
bool Split16BitLoopCount(NativeCodeProcedure* proc);
|
bool Split16BitLoopCount(NativeCodeProcedure* proc);
|
||||||
|
bool SimplifyDiamond(NativeCodeProcedure* proc);
|
||||||
|
|
||||||
bool MoveAccuTrainUp(int at, int end);
|
bool MoveAccuTrainUp(int at, int end);
|
||||||
bool MoveAccuTrainsUp(void);
|
bool MoveAccuTrainsUp(void);
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.7.149");
|
strcpy(strProductVersion, "1.7.150");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,7,149,0
|
FILEVERSION 1,7,150,0
|
||||||
PRODUCTVERSION 1,7,149,0
|
PRODUCTVERSION 1,7,150,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.7.149.0"
|
VALUE "FileVersion", "1.7.150.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.7.149.0"
|
VALUE "ProductVersion", "1.7.150.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -4231,15 +4231,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{7C4429C0-F5A0-4041-9049-DA5A6CB331BF}"
|
"ProductCode" = "8:{CC0139D2-24F8-4A28-B4B8-E9FA10C912BF}"
|
||||||
"PackageCode" = "8:{0CF4448C-B1E3-4471-A7D8-9929B12A24C4}"
|
"PackageCode" = "8:{0F10381E-B5C0-4E70-B759-DEED3A7827B8}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.7.149"
|
"ProductVersion" = "8:1.7.150"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue