Optimize signed range comparison
This commit is contained in:
parent
cb5f5f421f
commit
2ed784ea17
|
@ -54,6 +54,9 @@ if %errorlevel% neq 0 goto :error
|
||||||
call :test testint32cmp.c
|
call :test testint32cmp.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
call :test testinterval.c
|
||||||
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
call :test floatstringtest.c
|
call :test floatstringtest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
void testint0(void)
|
||||||
|
{
|
||||||
|
int a0n = 0, an0 = 0;
|
||||||
|
int b0n = 0, bn0 = 0;
|
||||||
|
|
||||||
|
for(int i=-1000; i<1000; i++)
|
||||||
|
{
|
||||||
|
if (i >= 0 && i < 500)
|
||||||
|
a0n += 1;
|
||||||
|
if (i < 500 && i >= 0)
|
||||||
|
an0 += 1;
|
||||||
|
if (i >= 0 && i <= 499)
|
||||||
|
b0n += 1;
|
||||||
|
if (i <= 499 && i >= 0)
|
||||||
|
bn0 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(a0n == 500);
|
||||||
|
assert(an0 == 500);
|
||||||
|
assert(b0n == 500);
|
||||||
|
assert(bn0 == 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef signed char int8;
|
||||||
|
|
||||||
|
void testbyte0(void)
|
||||||
|
{
|
||||||
|
int8 a0n = 0, an0 = 0;
|
||||||
|
int8 b0n = 0, bn0 = 0;
|
||||||
|
|
||||||
|
for(int8 i=-100; i<100; i++)
|
||||||
|
{
|
||||||
|
if (i >= 0 && i < 50)
|
||||||
|
a0n += 1;
|
||||||
|
if (i < 50 && i >= 0)
|
||||||
|
an0 += 1;
|
||||||
|
if (i >= 0 && i <= 49)
|
||||||
|
b0n += 1;
|
||||||
|
if (i <= 49 && i >= 0)
|
||||||
|
bn0 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(a0n == 50);
|
||||||
|
assert(an0 == 50);
|
||||||
|
assert(b0n == 50);
|
||||||
|
assert(bn0 == 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
testint0();
|
||||||
|
testbyte0();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -272,6 +272,12 @@ public:
|
||||||
|
|
||||||
int Size(void) const { return size; }
|
int Size(void) const { return size; }
|
||||||
|
|
||||||
|
T Last() const
|
||||||
|
{
|
||||||
|
assert(size > 0);
|
||||||
|
return array[size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
void SetSize(int size, bool clear = false)
|
void SetSize(int size, bool clear = false)
|
||||||
{
|
{
|
||||||
Grow(size, clear);
|
Grow(size, clear);
|
||||||
|
|
|
@ -14,6 +14,11 @@ int InterTypeSize[] = {
|
||||||
2
|
2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool IsIntegerType(InterType type)
|
||||||
|
{
|
||||||
|
return type >= IT_INT8 && type <= IT_INT32;
|
||||||
|
}
|
||||||
|
|
||||||
ValueSet::ValueSet(void)
|
ValueSet::ValueSet(void)
|
||||||
{
|
{
|
||||||
mSize = 32;
|
mSize = 32;
|
||||||
|
@ -4451,6 +4456,94 @@ bool InterCodeBasicBlock::IsEqual(const InterCodeBasicBlock* block) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterCodeBasicBlock::OptimizeIntervalCompare(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
int sz = mInstructions.Size();
|
||||||
|
if (sz >= 2 && mTrueJump && mFalseJump && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR &&
|
||||||
|
mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp && !mExitRequiredTemps[mInstructions[sz - 1]->mSrc[0].mTemp] &&
|
||||||
|
IsIntegerType(mInstructions[sz - 2]->mSrc[0].mType))
|
||||||
|
{
|
||||||
|
if (mInstructions[sz - 2]->mOperator == IA_CMPGES && mInstructions[sz - 2]->mSrc[0].mTemp == -1)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions.Size() == 2 && mTrueJump->mInstructions[1]->mCode == IC_BRANCH && mTrueJump->mFalseJump == mFalseJump &&
|
||||||
|
mTrueJump->mInstructions[0]->mCode == IC_RELATIONAL_OPERATOR && mTrueJump->mInstructions[0]->mDst.mTemp == mTrueJump->mInstructions[1]->mSrc->mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mSrc[0].mTemp == -1 && mTrueJump->mInstructions[0]->mSrc[1].mTemp == mInstructions[sz - 2]->mSrc[1].mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mOperator == IA_CMPLS && mInstructions[sz - 2]->mSrc[0].mIntConst == 0 && mTrueJump->mInstructions[0]->mSrc[0].mIntConst > 0)
|
||||||
|
{
|
||||||
|
mInstructions[sz - 2]->mOperator = IA_CMPLU;
|
||||||
|
mInstructions[sz - 2]->mSrc[0].mIntConst = mTrueJump->mInstructions[0]->mSrc[0].mIntConst;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mTrueJump->mInstructions[0]->mOperator == IA_CMPLES && mInstructions[sz - 2]->mSrc[0].mIntConst == 0 && mTrueJump->mInstructions[0]->mSrc[0].mIntConst > 0)
|
||||||
|
{
|
||||||
|
mInstructions[sz - 2]->mOperator = IA_CMPLEU;
|
||||||
|
mInstructions[sz - 2]->mSrc[0].mIntConst = mTrueJump->mInstructions[0]->mSrc[0].mIntConst;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLS && mInstructions[sz - 2]->mSrc[0].mTemp == -1)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions.Size() == 2 && mTrueJump->mInstructions[1]->mCode == IC_BRANCH && mTrueJump->mFalseJump == mFalseJump &&
|
||||||
|
mTrueJump->mInstructions[0]->mCode == IC_RELATIONAL_OPERATOR && mTrueJump->mInstructions[0]->mDst.mTemp == mTrueJump->mInstructions[1]->mSrc->mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mSrc[0].mTemp == -1 && mTrueJump->mInstructions[0]->mSrc[1].mTemp == mInstructions[sz - 2]->mSrc[1].mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mOperator == IA_CMPGES && mInstructions[sz - 2]->mSrc[0].mIntConst > 0 && mTrueJump->mInstructions[0]->mSrc[0].mIntConst == 0)
|
||||||
|
{
|
||||||
|
mInstructions[sz - 2]->mOperator = IA_CMPLU;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mInstructions[sz - 2]->mOperator == IA_CMPLES && mInstructions[sz - 2]->mSrc[0].mTemp == -1)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions.Size() == 2 && mTrueJump->mInstructions[1]->mCode == IC_BRANCH && mTrueJump->mFalseJump == mFalseJump &&
|
||||||
|
mTrueJump->mInstructions[0]->mCode == IC_RELATIONAL_OPERATOR && mTrueJump->mInstructions[0]->mDst.mTemp == mTrueJump->mInstructions[1]->mSrc->mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mSrc[0].mTemp == -1 && mTrueJump->mInstructions[0]->mSrc[1].mTemp == mInstructions[sz - 2]->mSrc[1].mTemp)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mInstructions[0]->mOperator == IA_CMPGES && mInstructions[sz - 2]->mSrc[0].mIntConst > 0 && mTrueJump->mInstructions[0]->mSrc[0].mIntConst == 0)
|
||||||
|
{
|
||||||
|
mInstructions[sz - 2]->mOperator = IA_CMPLEU;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->OptimizeIntervalCompare())
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->OptimizeIntervalCompare())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::FollowJumps(void)
|
void InterCodeBasicBlock::FollowJumps(void)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -4655,6 +4748,29 @@ static bool IsCommutative(InterOperator op)
|
||||||
{
|
{
|
||||||
return op == IA_ADD || op == IA_MUL || op == IA_AND || op == IA_OR || op == IA_XOR;
|
return op == IA_ADD || op == IA_MUL || op == IA_AND || op == IA_OR || op == IA_XOR;
|
||||||
}
|
}
|
||||||
|
void InterCodeBasicBlock::CompactInstructions(void)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mInstructions[i]->mCode != IC_NONE)
|
||||||
|
{
|
||||||
|
mInstructions[j++] = mInstructions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mInstructions.SetSize(j);
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->CompactInstructions();
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->CompactInstructions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::PeepholeOptimization(void)
|
void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -5528,6 +5644,16 @@ void InterCodeProcedure::Close(void)
|
||||||
BuildDominators();
|
BuildDominators();
|
||||||
DisassembleDebug("added dominators");
|
DisassembleDebug("added dominators");
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CompactInstructions();
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->OptimizeIntervalCompare();
|
||||||
|
|
||||||
|
DisassembleDebug("interval compare");
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
|
|
@ -514,6 +514,8 @@ public:
|
||||||
|
|
||||||
bool IsEqual(const InterCodeBasicBlock* block) const;
|
bool IsEqual(const InterCodeBasicBlock* block) const;
|
||||||
|
|
||||||
|
void CompactInstructions(void);
|
||||||
|
bool OptimizeIntervalCompare(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterCodeModule;
|
class InterCodeModule;
|
||||||
|
|
|
@ -8057,6 +8057,37 @@ bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& bre
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[j + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
|
||||||
|
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 2].mAddress + 1 &&
|
||||||
|
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
|
||||||
|
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
|
||||||
|
{
|
||||||
|
breg = mIns[j + 2].mAddress;
|
||||||
|
ireg = mIns[j + 1].mAddress;
|
||||||
|
|
||||||
|
int k = j + 7;
|
||||||
|
while (k < at)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
if (breg == reg)
|
||||||
|
{
|
||||||
|
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1))
|
||||||
|
return false;
|
||||||
|
if (mIns[k].mMode == ASMIM_INDIRECT_Y && mIns[k].mAddress == breg)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
apos = j;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
|
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
|
||||||
return false;
|
return false;
|
||||||
|
@ -8243,6 +8274,41 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveLoadStoreXUp(int at)
|
||||||
|
{
|
||||||
|
int j = at;
|
||||||
|
while (j > 0 && !((mIns[j - 1].mType == ASMIT_STA || mIns[j - 1].mType == ASMIT_LDA) && mIns[j - 1].mMode == ASMIM_ZERO_PAGE && mIns[j - 1].mAddress == mIns[at].mAddress))
|
||||||
|
{
|
||||||
|
j--;
|
||||||
|
if ((mIns[j].mMode == ASMIM_ZERO_PAGE || mIns[j].mMode == ASMIM_INDIRECT_Y) && mIns[j].mAddress == mIns[at + 1].mAddress)
|
||||||
|
return false;
|
||||||
|
if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress + 1 == mIns[at + 1].mAddress)
|
||||||
|
return false;
|
||||||
|
if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress())
|
||||||
|
return false;
|
||||||
|
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && !mIns[j].mLinkerObject)
|
||||||
|
return false;
|
||||||
|
if (mIns[j].mType == ASMIT_JSR)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0 && j < at)
|
||||||
|
{
|
||||||
|
for (int i = at; i > j; i--)
|
||||||
|
{
|
||||||
|
mIns[i] = mIns[i - 1];
|
||||||
|
}
|
||||||
|
mIns[j - 1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[j] = mIns[at + 1];
|
||||||
|
mIns[j].mType = ASMIT_STA;
|
||||||
|
mIns[at + 1].mType = ASMIT_NOP;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::MoveLoadAddImmStoreUp(int at)
|
bool NativeCodeBasicBlock::MoveLoadAddImmStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at - 1;
|
int j = at - 1;
|
||||||
|
@ -9105,6 +9171,47 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
||||||
j += 2;
|
j += 2;
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
|
||||||
|
mIns[i + 3].mType == ASMIT_EOR && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||||
|
!(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns[j + 0].mType = ASMIT_AND; mIns[j + 0].mMode = ASMIM_IMMEDIATE; mIns[j + 0].mAddress = 0x80;
|
||||||
|
mIns[j + 1].mType = ASMIT_BPL; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 2;
|
||||||
|
mIns[j + 2].mType = ASMIT_LDA; mIns[j + 2].mMode = ASMIM_IMMEDIATE; mIns[j + 2].mAddress = 0xff;
|
||||||
|
j += 3;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX; mIns[j + 0].mMode = ASMIM_ZERO_PAGE; mIns[j + 0].mAddress = mIns[i + 1].mAddress;
|
||||||
|
mIns[j + 1].mType = ASMIT_INX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_STX; mIns[j + 2].mMode = ASMIM_ZERO_PAGE; mIns[j + 2].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 3;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX; mIns[j + 0].mMode = ASMIM_ZERO_PAGE; mIns[j + 0].mAddress = mIns[i + 1].mAddress;
|
||||||
|
mIns[j + 1].mType = ASMIT_DEX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_STX; mIns[j + 2].mMode = ASMIM_ZERO_PAGE; mIns[j + 2].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 3;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mIns[j++] = mIns[i++];
|
mIns[j++] = mIns[i++];
|
||||||
}
|
}
|
||||||
|
@ -9245,6 +9352,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// move load store pairs up to initial store
|
||||||
|
|
||||||
|
for (int i = 2; i + 1 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (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 + 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)) == 0)
|
||||||
|
{
|
||||||
|
if (MoveLoadStoreXUp(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// move load - store (),y up to initial store
|
// move load - store (),y up to initial store
|
||||||
//
|
//
|
||||||
|
@ -9458,6 +9578,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sz > 4 &&
|
||||||
|
mIns[sz - 4].mType == ASMIT_ASL && mIns[sz - 4].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[sz - 3].mType == ASMIT_LDA && mIns[sz - 3].mMode == ASMIM_IMMEDIATE && mIns[sz - 3].mAddress == 0 &&
|
||||||
|
mIns[sz - 2].mType == ASMIT_ADC && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0xff &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_EOR && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0xff && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
if (mBranch == ASMIT_BEQ)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_BPL;
|
||||||
|
mIns[sz - 4] = ASMIT_NOP;
|
||||||
|
mIns[sz - 3] = ASMIT_NOP;
|
||||||
|
mIns[sz - 2] = ASMIT_NOP;
|
||||||
|
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mAddress = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mBranch == ASMIT_BNE)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_BMI;
|
||||||
|
mIns[sz - 4] = ASMIT_NOP;
|
||||||
|
mIns[sz - 3] = ASMIT_NOP;
|
||||||
|
mIns[sz - 2] = ASMIT_NOP;
|
||||||
|
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mAddress = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -9768,6 +9914,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_CPX;
|
||||||
|
mIns[i + 0].mLive |= CPU_REG_X;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CMP && (mIns[i + 1].mMode == ASMIM_IMMEDIATE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_CPY;
|
||||||
|
mIns[i + 0].mLive |= CPU_REG_Y;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
|
@ -10029,6 +10191,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 0].mType = ASMIT_SEC;
|
mIns[i + 0].mType = ASMIT_SEC;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC)
|
||||||
|
{
|
||||||
|
mIns[i + 1] = mIns[i + 0];
|
||||||
|
mIns[i + 0].mType = ASMIT_CLC;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_C;
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_C;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_TYA &&
|
mIns[i + 1].mType == ASMIT_TYA &&
|
||||||
|
@ -10044,6 +10218,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 2].mType = ASMIT_TYA; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
mIns[i + 2].mType = ASMIT_TYA; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) &&
|
||||||
|
!mIns[i + 1].ChangesAddress() && !mIns[i + 1].ChangesGlobalMemory() &&
|
||||||
|
!mIns[i + 1].ChangesYReg() && !mIns[i + 1].ChangesXReg())
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
|
@ -10133,6 +10317,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 3].mType = ASMIT_DEC;
|
mIns[i + 3].mType = ASMIT_DEC;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (mIns[i + 1].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 1].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
(mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mType = ASMIT_INC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i + 1].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 1].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
|
mIns[i + 0].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
(mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mType = ASMIT_DEC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff) == 0xff &&
|
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff) == 0xff &&
|
||||||
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
@ -10254,10 +10460,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 3].mFlags = mIns[i + 0].mFlags;
|
mIns[i + 3].mFlags = mIns[i + 0].mFlags;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff &&
|
||||||
|
mIns[i + 2].mType == ASMIT_EOR && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LSR && mIns[i + 3].mMode == ASMIM_IMPLIED && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
|
||||||
!mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) &&
|
!mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 3].mAddress && !(mIns[i + 3].mLive & LIVE_MEM))
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 3].mAddress && !(mIns[i + 3].mLive & LIVE_MEM))
|
||||||
{
|
{
|
||||||
|
@ -10303,6 +10524,38 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 2].mAddress = mIns[i + 0].mAddress;
|
mIns[i + 2].mAddress = mIns[i + 0].mAddress;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
|
||||||
|
!mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) &&
|
||||||
|
!mIns[i + 3].ChangesYReg() && (mIns[i + 3].mMode == ASMIM_IMMEDIATE || mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 1].mAddress) &&
|
||||||
|
mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 4].mAddress && !(mIns[i + 4].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
int apos, breg, ireg;
|
||||||
|
if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg))
|
||||||
|
{
|
||||||
|
if (breg == mIns[i + 1].mAddress)
|
||||||
|
{
|
||||||
|
mIns[apos + 3].mType = ASMIT_NOP;
|
||||||
|
mIns[apos + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[apos + 6].mType = ASMIT_NOP;
|
||||||
|
mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
|
if (mIns[i + 4].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
|
mIns.Insert(i + 5, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
}
|
||||||
|
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
|
||||||
|
mIns[i + 0].mAddress = ireg;
|
||||||
|
mIns[i + 1].mAddress = breg;
|
||||||
|
mIns[i + 4].mAddress = breg;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
|
@ -174,6 +174,8 @@ public:
|
||||||
void MarkLoopHead(void);
|
void MarkLoopHead(void);
|
||||||
|
|
||||||
bool MoveLoadStoreUp(int at);
|
bool MoveLoadStoreUp(int at);
|
||||||
|
bool MoveLoadStoreXUp(int at);
|
||||||
|
|
||||||
bool MoveIndirectLoadStoreUp(int at);
|
bool MoveIndirectLoadStoreUp(int at);
|
||||||
bool MoveAbsoluteLoadStoreUp(int at);
|
bool MoveAbsoluteLoadStoreUp(int at);
|
||||||
bool MoveLoadAddImmStoreUp(int at);
|
bool MoveLoadAddImmStoreUp(int at);
|
||||||
|
|
Loading…
Reference in New Issue