More simple common subexpression elimination in native code
This commit is contained in:
parent
9f28fdfcc0
commit
9c5e018c5a
|
@ -12685,7 +12685,19 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
|||
mInstructions[i + 1]->mNumOperands = 0;
|
||||
changed = true;
|
||||
}
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && (mInstructions[i + 0]->mOperator == IA_SUB || mInstructions[i + 0]->mOperator == IA_XOR) &&
|
||||
mInstructions[i + 0]->mSrc[0].mTemp >= 0 && mInstructions[i + 0]->mSrc[0].mTemp == mInstructions[i + 0]->mSrc[1].mTemp)
|
||||
{
|
||||
mInstructions[i + 0]->mCode = IC_CONSTANT;
|
||||
mInstructions[i + 0]->mNumOperands = 0;
|
||||
mInstructions[i + 0]->mConst.mType = mInstructions[i + 0]->mDst.mType;
|
||||
mInstructions[i + 0]->mConst.mIntConst = 0;
|
||||
mInstructions[i + 0]->mConst.mFloatConst = 0;
|
||||
changed = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
else if (
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SHR && mInstructions[i + 0]->mSrc[0].mTemp < 0 &&
|
||||
|
@ -13137,6 +13149,96 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
|
|||
changed = true;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (i + 2 < mInstructions.Size() &&
|
||||
mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR &&
|
||||
mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||
mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR &&
|
||||
mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 1]->mSrc[0].mTemp &&
|
||||
mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 1]->mSrc[1].mTemp &&
|
||||
mInstructions[i + 2]->mSrc[0].mTemp >= 0 && mInstructions[i + 2]->mSrc[1].mTemp >= 0 &&
|
||||
mInstructions[i + 2]->mSrc[0].mFinal && mInstructions[i + 2]->mSrc[1].mFinal &&
|
||||
mInstructions[i + 2]->mDst.mType == IT_INT16)
|
||||
{
|
||||
bool fail = false;
|
||||
int s0, s1, c0, c1, s2 = i + 2;
|
||||
|
||||
if (mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 1]->mDst.mTemp)
|
||||
{
|
||||
s0 = i + 0; s1 = i + 1;
|
||||
}
|
||||
else if (mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i + 1]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i + 0]->mDst.mTemp)
|
||||
{
|
||||
s0 = i + 1; s1 = i + 0;
|
||||
}
|
||||
else
|
||||
fail = true;
|
||||
|
||||
if (!fail)
|
||||
{
|
||||
if (mInstructions[s0]->mSrc[0].mTemp < 0)
|
||||
c0 = 0;
|
||||
else if (mInstructions[s0]->mSrc[1].mTemp < 0)
|
||||
c0 = 1;
|
||||
else
|
||||
fail = true;
|
||||
|
||||
if (mInstructions[s1]->mSrc[0].mTemp < 0)
|
||||
c1 = 0;
|
||||
else if (mInstructions[s1]->mSrc[1].mTemp < 0)
|
||||
c1 = 1;
|
||||
else
|
||||
fail = true;
|
||||
|
||||
if (!fail)
|
||||
{
|
||||
InterOperator o0 = mInstructions[s0]->mOperator;
|
||||
InterOperator o1 = mInstructions[s1]->mOperator;
|
||||
InterOperator o2 = mInstructions[s2]->mOperator;
|
||||
|
||||
if (o2 == IA_SUB)
|
||||
{
|
||||
if ((o0 == IA_ADD || o0 == IA_SUB && c0 == 0) && (o1 == IA_ADD || o1 == IA_SUB && c1 == 0))
|
||||
{
|
||||
int iconst =
|
||||
(o1 == IA_ADD ? mInstructions[s1]->mSrc[c1].mIntConst : -mInstructions[s1]->mSrc[c1].mIntConst) -
|
||||
(o0 == IA_ADD ? mInstructions[s0]->mSrc[c0].mIntConst : -mInstructions[s0]->mSrc[c0].mIntConst);
|
||||
|
||||
mInstructions[s0]->mSrc[0] = mInstructions[s0]->mSrc[1 - c0];
|
||||
mInstructions[s0]->mSrc[1] = mInstructions[s1]->mSrc[1 - c1];
|
||||
mInstructions[s0]->mDst.mRange.Reset();
|
||||
mInstructions[s0]->mOperator = IA_SUB;
|
||||
mInstructions[s2]->mOperator = IA_ADD;
|
||||
mInstructions[s2]->mSrc[0].mRange = mInstructions[s0]->mDst.mRange;
|
||||
mInstructions[s2]->mSrc[1].mTemp = -1;
|
||||
mInstructions[s2]->mSrc[1].mIntConst = iconst;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (o2 == IA_ADD)
|
||||
{
|
||||
if ((o0 == IA_ADD || o0 == IA_SUB && c0 == 0) && (o1 == IA_ADD || o1 == IA_SUB && c1 == 0))
|
||||
{
|
||||
int iconst =
|
||||
(o1 == IA_ADD ? mInstructions[s1]->mSrc[c1].mIntConst : -mInstructions[s1]->mSrc[c1].mIntConst) +
|
||||
(o0 == IA_ADD ? mInstructions[s0]->mSrc[c0].mIntConst : -mInstructions[s0]->mSrc[c0].mIntConst);
|
||||
|
||||
mInstructions[s0]->mSrc[0] = mInstructions[s0]->mSrc[1 - c0];
|
||||
mInstructions[s0]->mSrc[1] = mInstructions[s1]->mSrc[1 - c1];
|
||||
mInstructions[s0]->mDst.mRange.Reset();
|
||||
mInstructions[s0]->mOperator = IA_ADD;
|
||||
mInstructions[s2]->mOperator = IA_ADD;
|
||||
mInstructions[s2]->mSrc[0].mRange = mInstructions[s0]->mDst.mRange;
|
||||
mInstructions[s2]->mSrc[1].mTemp = -1;
|
||||
mInstructions[s2]->mSrc[1].mIntConst = iconst;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// Postincrement artifact
|
||||
if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||
|
|
|
@ -1400,6 +1400,35 @@ bool NativeCodeInstruction::IsSame(const NativeCodeInstruction& ins) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::IsSameLS(const NativeCodeInstruction& ins) const
|
||||
{
|
||||
if ((mType == ins.mType || mType == ASMIT_STA && ins.mType == ASMIT_LDA) && mMode == ins.mMode && mParam == ins.mParam)
|
||||
{
|
||||
switch (mMode)
|
||||
{
|
||||
case ASMIM_IMPLIED:
|
||||
return true;
|
||||
case ASMIM_IMMEDIATE:
|
||||
case ASMIM_ZERO_PAGE:
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
case ASMIM_INDIRECT_X:
|
||||
case ASMIM_INDIRECT_Y:
|
||||
return ins.mAddress == mAddress;
|
||||
case ASMIM_IMMEDIATE_ADDRESS:
|
||||
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress && ins.mFlags == mFlags);
|
||||
case ASMIM_ABSOLUTE:
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins)
|
||||
{
|
||||
if ((ChangesAddress() || ins.ChangesAddress()) && MayBeSameAddress(ins))
|
||||
|
@ -13824,9 +13853,26 @@ bool NativeCodeBasicBlock::IsSimpleSubExpression(int at) const
|
|||
}
|
||||
}
|
||||
|
||||
if (at >= 3 &&
|
||||
mIns[at - 3].mType == ASMIT_STA && mIns[at - 3].mMode == ASMIM_ZERO_PAGE && mIns[at - 2].mType == ASMIT_CLC &&
|
||||
mIns[at - 1].mType == ASMIT_ADC && mIns[at - 1].mMode == ASMIM_IMMEDIATE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::IsSameSimpleSubExpression(int pat, int at) const
|
||||
{
|
||||
if (pat >= 2 && mIns[pat - 2].mType == ASMIT_LDA)
|
||||
{
|
||||
return mIns[pat - 2].IsSame(mIns[at - 2]) && mIns[pat - 1].IsSame(mIns[at - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mIns[pat - 3].SameEffectiveAddress(mIns[at - 2]) && mIns[pat - 1].IsSame(mIns[at - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -13849,7 +13895,7 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
|||
if (IsSimpleSubExpression(i))
|
||||
{
|
||||
int si = cex[ins.mAddress];
|
||||
if (si >= 0 && mIns[si - 2].IsSame(mIns[i - 2]) && mIns[si - 1].IsSame(mIns[i - 1]) && !(ins.mLive & LIVE_CPU_REG_C))
|
||||
if (si >= 0 && IsSameSimpleSubExpression(si, i) && !(ins.mLive & LIVE_CPU_REG_C))
|
||||
{
|
||||
mIns[i].mType = ASMIT_LDA;
|
||||
mIns[si].mLive |= LIVE_MEM;
|
||||
|
@ -13876,8 +13922,12 @@ bool NativeCodeBasicBlock::PropagateCommonSubExpression(void)
|
|||
cex[ins.mAddress] = -1;
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
if (cex[j] >= 0 && mIns[cex[j] - 2].mAddress == ins.mAddress)
|
||||
int k = cex[j];
|
||||
if (k >= 0 && (
|
||||
mIns[k - 2].mType == ASMIT_LDA && mIns[k - 2].mAddress == ins.mAddress || mIns[k - 3].mAddress == ins.mAddress))
|
||||
{
|
||||
cex[j] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17533,6 +17583,145 @@ bool NativeCodeBasicBlock::ShortcutPointerAddForward(void)
|
|||
return changed;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int NativeCodeExpressionID;
|
||||
|
||||
struct NativeCodeExpression
|
||||
{
|
||||
int mIndex;
|
||||
AsmInsType mType;
|
||||
NativeCodeInstruction * mIns;
|
||||
int mLeft, mRight;
|
||||
int mReg;
|
||||
|
||||
NativeCodeExpression(AsmInsType type, NativeCodeInstruction* ins)
|
||||
: mIndex(NativeCodeExpressionID++), mType(type), mIns(ins), mLeft(-1), mRight(-1), mReg(-1)
|
||||
{
|
||||
}
|
||||
|
||||
NativeCodeExpression(AsmInsType type, int left, int right)
|
||||
: mIndex(NativeCodeExpressionID++), mType(type), mIns(nullptr), mLeft(left), mRight(right), mReg(reg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct NativeCodeExpressions
|
||||
{
|
||||
ExpandingArray<NativeCodeExpression> mExps;
|
||||
|
||||
void KillReg(int reg);
|
||||
void KillYReg(void);
|
||||
void KillXReg(void);
|
||||
void KillAddr(const NativeCodeInstruction& ins);
|
||||
int AddLoad(const NativeCodeInstruction& ins);
|
||||
};
|
||||
|
||||
|
||||
void NativeCodeExpressions::KillReg(int reg)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mExps.Size())
|
||||
{
|
||||
if (mExps[i].mReg == reg)
|
||||
mExps.Remove(i);
|
||||
else if (mExps[i].mIns)
|
||||
{
|
||||
if (reg == CPU_REG_Y && mExps[i].mIns->RequiresYReg())
|
||||
mExps.Remove(i);
|
||||
else if (reg == CPU_REG_X && mExps[i].mIns->RequiresXReg())
|
||||
mExps.Remove(i);
|
||||
else if (mExps[i].mIns->ReferencesZeroPage(reg))
|
||||
mExps.Remove(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeCodeExpressions::KillYReg(void)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mExps.Size())
|
||||
{
|
||||
if (mExps[i].mIns && mExps[i].mIns->RequiresYReg())
|
||||
mExps.Remove(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeCodeExpressions::KillAddr(const NativeCodeInstruction& ins)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mExps.Size())
|
||||
{
|
||||
if (mExps[i].mIns && mExps[i].mIns->MayBeChangedOnAddress(ins))
|
||||
mExps.Remove(i);
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int NativeCodeExpressions::AddLoad(const NativeCodeInstruction& ins)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mExps.Size() && !(mExps[i].mType == ASMIT_LDA && mExps[i].mIns->SameAddress(ins))
|
||||
i++;
|
||||
if (i < mExps.Size())
|
||||
return mExps[i].mIndex;
|
||||
else
|
||||
{
|
||||
NativeCodeExpressions e(ASMIT_LDA, &ins);
|
||||
mExps.Push(e);
|
||||
return e.mIndex;
|
||||
}
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CommonSubExpressionElimination(void)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
NativeCodeExpressions exps;
|
||||
|
||||
int aexp = -1, xexp = -1, yexp = -1;
|
||||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[i]);
|
||||
|
||||
|
||||
|
||||
switch (ins.mType)
|
||||
{
|
||||
case ASMIT_LDA:
|
||||
aexp = exps.AddLoad(ins);
|
||||
break;
|
||||
case ASMIT_LDX:
|
||||
aexp = exps.AddLoad(ins);
|
||||
break;
|
||||
case ASMIT_LDY:
|
||||
aexp = exps.AddLoad(ins);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->CommonSubExpressionElimination())
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->CommonSubExpressionElimination())
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool NativeCodeBasicBlock::CanChangeTailZPStoreToX(int addr, const NativeCodeBasicBlock* nblock, const NativeCodeBasicBlock* fblock) const
|
||||
{
|
||||
if (mExitRequiredRegs[CPU_REG_X])
|
||||
|
@ -34466,6 +34655,56 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDX &&
|
||||
mIns[i + 1].mType == ASMIT_INX && mIns[i + 2].mType == ASMIT_INX &&
|
||||
mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & LIVE_CPU_REG_X))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_INC;
|
||||
mIns[i + 3].mType = ASMIT_INC;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDX &&
|
||||
mIns[i + 1].mType == ASMIT_DEX && mIns[i + 2].mType == ASMIT_DEX &&
|
||||
mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & LIVE_CPU_REG_X))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_DEC;
|
||||
mIns[i + 3].mType = ASMIT_DEC;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
else if (pass > 10 &&
|
||||
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_INC, mIns[i + 0].mMode) &&
|
||||
mIns[i + 1].mType == ASMIT_CLC &&
|
||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 &&
|
||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_INC;
|
||||
mIns[i + 3].mType = ASMIT_INC;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
else if (pass > 10 &&
|
||||
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_DEC, mIns[i + 0].mMode) &&
|
||||
mIns[i + 1].mType == ASMIT_SEC &&
|
||||
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 &&
|
||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_DEC;
|
||||
mIns[i + 3].mType = ASMIT_DEC;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
!(mIns[i + 1].ChangesYReg() || mIns[i + 1].mMode == ASMIM_INDIRECT_Y || mIns[i + 1].RequiresXReg()) &&
|
||||
|
@ -35601,30 +35840,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
}
|
||||
}
|
||||
|
||||
if (i + 8 < mIns.Size() && pass > 3 &&
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_CLC &&
|
||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 4].mType == ASMIT_LDA &&
|
||||
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
|
||||
mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 3].mAddress && !(mIns[i + 8].mLive & LIVE_MEM))
|
||||
if (i + 7 < mIns.Size() && pass > 3 &&
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 3].mType == ASMIT_LDA &&
|
||||
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
||||
mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM))
|
||||
{
|
||||
int total = mIns[i + 2].mAddress + mIns[i + 7].mAddress + 256 * mIns[i + 5].mAddress;
|
||||
if (!(mIns[i + 8].mLive & LIVE_CPU_REG_Y) || !(mIns[i + 8].mLive & LIVE_CPU_REG_Z))
|
||||
int total = mIns[i + 1].mAddress + mIns[i + 6].mAddress + 256 * mIns[i + 4].mAddress;
|
||||
if (!(mIns[i + 7].mLive & LIVE_CPU_REG_Y) || !(mIns[i + 7].mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
if (mIns[i + 8].mLive & LIVE_CPU_REG_Y)
|
||||
mIns.Insert(i + 9, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 7].mAddress));
|
||||
mIns[i + 7].mAddress = total & 255;
|
||||
mIns[i + 5].mAddress = total >> 8;
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
if (mIns[i + 7].mLive & LIVE_CPU_REG_Y)
|
||||
mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 6].mAddress));
|
||||
mIns[i + 6].mAddress = total & 255;
|
||||
mIns[i + 4].mAddress = total >> 8;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (i + 6 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
|
@ -35978,6 +36215,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (mIns[i + 0].mType == ASMIT_CLC &&
|
||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 3].mType == ASMIT_LDA &&
|
||||
mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 2].mAddress + 1 &&
|
||||
mIns[i + 2].mAddress != BC_REG_STACK &&
|
||||
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
int yval = RetrieveYValue(i);
|
||||
proc->ResetPatched();
|
||||
|
||||
if (CheckForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (PatchForwardSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, mIns[i + 1], i + 7, yval))
|
||||
progress = true;
|
||||
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
|
||||
if (mTrueJump)
|
||||
mTrueJump->CheckLive();
|
||||
if (mFalseJump)
|
||||
mFalseJump->CheckLive();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
|
@ -37821,7 +38087,7 @@ void NativeCodeProcedure::RebuildEntry(void)
|
|||
|
||||
void NativeCodeProcedure::Optimize(void)
|
||||
{
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "_mapUp");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "setpair");
|
||||
|
||||
#if 1
|
||||
int step = 0;
|
||||
|
@ -38017,7 +38283,6 @@ void NativeCodeProcedure::Optimize(void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
if (step > 0)
|
||||
{
|
||||
|
@ -38453,7 +38718,6 @@ void NativeCodeProcedure::Optimize(void)
|
|||
else
|
||||
cnt++;
|
||||
|
||||
|
||||
} while (changed);
|
||||
|
||||
#if 1
|
||||
|
|
|
@ -147,6 +147,7 @@ public:
|
|||
bool MayBeChangedOnAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||
bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||
bool IsSame(const NativeCodeInstruction& ins) const;
|
||||
bool IsSameLS(const NativeCodeInstruction& ins) const;
|
||||
bool IsCommutative(void) const;
|
||||
bool IsShift(void) const;
|
||||
bool IsShiftOrInc(void) const;
|
||||
|
@ -506,6 +507,7 @@ public:
|
|||
bool GlobalSwapXY(void);
|
||||
|
||||
bool IsSimpleSubExpression(int at) const;
|
||||
bool IsSameSimpleSubExpression(int pat, int at) const;
|
||||
bool PropagateCommonSubExpression(void);
|
||||
|
||||
bool ForwardAbsoluteLoadStores(void);
|
||||
|
@ -516,6 +518,8 @@ public:
|
|||
bool CheckShortcutPointerAddForward(int at);
|
||||
bool ShortcutPointerAddForward(void);
|
||||
|
||||
bool CommonSubExpressionElimination(void);
|
||||
|
||||
bool CheckPatchFailReg(const NativeCodeBasicBlock* block, int reg);
|
||||
bool CheckPatchFailRegPair(const NativeCodeBasicBlock* block, int reg);
|
||||
bool CheckPatchFailUse(void);
|
||||
|
|
Loading…
Reference in New Issue