Improve unrolled loops towards zero
This commit is contained in:
parent
a19469d851
commit
8a49ffd111
|
@ -94,4 +94,24 @@ void vic_waitLine(int line)
|
||||||
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper);
|
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vic_waitBelow(int line)
|
||||||
|
{
|
||||||
|
char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
|
||||||
|
char lower = (char)line;
|
||||||
|
|
||||||
|
if (upper)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (vic.raster <= lower)
|
||||||
|
;
|
||||||
|
} while (!(vic.ctrl1 & VIC_CTRL1_RST8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (vic.raster <= lower)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma native(vic_waitLine)
|
#pragma native(vic_waitLine)
|
||||||
|
|
|
@ -115,6 +115,9 @@ void vic_waitFrames(char n);
|
||||||
// wait for a specific raster line
|
// wait for a specific raster line
|
||||||
void vic_waitLine(int line);
|
void vic_waitLine(int line);
|
||||||
|
|
||||||
|
// wait for beam to be below a line
|
||||||
|
void vic_waitBelow(int line);
|
||||||
|
|
||||||
// reference to the VIC chip
|
// reference to the VIC chip
|
||||||
#define vic (*((struct VIC *)0xd000))
|
#define vic (*((struct VIC *)0xd000))
|
||||||
|
|
||||||
|
|
|
@ -14531,6 +14531,67 @@ static bool IsInsSrcModifiedInBlocks(const ExpandingArray<InterCodeBasicBlock*>&
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::SingleLoopCountZeroCheck(void)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mLoopHead && mEntryBlocks.Size() == 2 && mFalseJump && (mTrueJump == this || mFalseJump == this) && mInstructions.Size() > 3)
|
||||||
|
{
|
||||||
|
int nins = mInstructions.Size();
|
||||||
|
|
||||||
|
InterCodeBasicBlock * pblock = mEntryBlocks[0];
|
||||||
|
if (pblock == this)
|
||||||
|
pblock = mEntryBlocks[1];
|
||||||
|
while (pblock->mInstructions.Size() == 1 && pblock->mInstructions[0]->mCode == IC_JUMP && pblock->mEntryBlocks.Size() == 1)
|
||||||
|
pblock = pblock->mEntryBlocks[0];
|
||||||
|
|
||||||
|
if (mInstructions[nins - 1]->mCode == IC_BRANCH &&
|
||||||
|
mInstructions[nins - 2]->mCode == IC_RELATIONAL_OPERATOR &&
|
||||||
|
mInstructions[nins - 3]->mCode == IC_BINARY_OPERATOR && mInstructions[nins - 3]->mOperator == IA_ADD)
|
||||||
|
{
|
||||||
|
InterInstruction* ains = mInstructions[nins - 3];
|
||||||
|
InterInstruction* cins = mInstructions[nins - 2];
|
||||||
|
InterInstruction* bins = mInstructions[nins - 1];
|
||||||
|
|
||||||
|
if (bins->mSrc[0].mTemp == cins->mDst.mTemp &&
|
||||||
|
cins->mSrc[1].mTemp == ains->mDst.mTemp &&
|
||||||
|
cins->mSrc[0].mTemp < 0 &&
|
||||||
|
ains->mSrc[1].mTemp == ains->mDst.mTemp &&
|
||||||
|
ains->mSrc[0].mTemp < 0 &&
|
||||||
|
cins->mOperator == IA_CMPGS &&
|
||||||
|
ains->mSrc[0].mIntConst < -1 &&
|
||||||
|
cins->mSrc[0].mIntConst > 0 &&
|
||||||
|
cins->mSrc[0].mIntConst < - ains->mSrc[0].mIntConst &&
|
||||||
|
!IsTempModifiedInRange(0, nins - 3, ains->mDst.mTemp))
|
||||||
|
{
|
||||||
|
int pi = pblock->mInstructions.Size() - 1;
|
||||||
|
while (pi >= 0 && pblock->mInstructions[pi]->mDst.mTemp != ains->mDst.mTemp)
|
||||||
|
pi--;
|
||||||
|
if (pi >= 0 && pblock->mInstructions[pi]->mCode == IC_CONSTANT)
|
||||||
|
{
|
||||||
|
int64 istart = pblock->mInstructions[pi]->mConst.mIntConst;
|
||||||
|
if (istart > 0)
|
||||||
|
{
|
||||||
|
int64 iend = istart % -ains->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
if (cins->mSrc[0].mIntConst < iend)
|
||||||
|
{
|
||||||
|
cins->mSrc[0].mIntConst = 0;
|
||||||
|
cins->mOperator = IA_CMPGES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->SingleLoopCountZeroCheck();
|
||||||
|
if (mFalseJump) mFalseJump->SingleLoopCountZeroCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool InterCodeBasicBlock::MoveConditionOutOfLoop(void)
|
bool InterCodeBasicBlock::MoveConditionOutOfLoop(void)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -20208,6 +20269,9 @@ void InterCodeProcedure::Close(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->SingleLoopCountZeroCheck();
|
||||||
|
|
||||||
RemoveUnusedPartialStoreInstructions();
|
RemoveUnusedPartialStoreInstructions();
|
||||||
|
|
||||||
MapVariables();
|
MapVariables();
|
||||||
|
|
|
@ -579,6 +579,7 @@ public:
|
||||||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||||
void PushMoveOutOfLoop(void);
|
void PushMoveOutOfLoop(void);
|
||||||
bool MoveConditionOutOfLoop(void);
|
bool MoveConditionOutOfLoop(void);
|
||||||
|
void SingleLoopCountZeroCheck(void);
|
||||||
|
|
||||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
||||||
void RemoveUnusedMallocs(void);
|
void RemoveUnusedMallocs(void);
|
||||||
|
|
|
@ -14401,6 +14401,64 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
yoffset = 2;
|
yoffset = 2;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (yoffset == 0xff && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 0xff)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_INY; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
yoffset = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 0xfe && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY && mIns[i + 2].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 0xfe && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_INY;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 0xfd && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY && mIns[i + 2].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (yoffset == 0xfd && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns[i + 0].mType = ASMIT_INY; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
yoffset = 0xfe;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
yoffset = 0;
|
yoffset = 0;
|
||||||
ypred = i;
|
ypred = i;
|
||||||
|
@ -14419,7 +14477,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[j + 2].mType == ASMIT_STA && mIns[j + 2].mMode == ASMIM_ZERO_PAGE && mIns[j + 2].mAddress == yreg &&
|
mIns[j + 2].mType == ASMIT_STA && mIns[j + 2].mMode == ASMIM_ZERO_PAGE && mIns[j + 2].mAddress == yreg &&
|
||||||
!(mIns[j + 2].mLive & LIVE_CPU_REG_C))
|
!(mIns[j + 2].mLive & LIVE_CPU_REG_C))
|
||||||
{
|
{
|
||||||
if (mIns[j + 1].mAddress == yoffset + 1)
|
if (mIns[j + 1].mAddress == ((yoffset + 1) & 0xff))
|
||||||
{
|
{
|
||||||
for (int k = ypred; k < i; k++)
|
for (int k = ypred; k < i; k++)
|
||||||
mIns[k].mLive |= LIVE_CPU_REG_Y;
|
mIns[k].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -14432,6 +14490,19 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
i += 2;
|
i += 2;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (mIns[j + 1].mAddress == ((yoffset - 1) & 0xff))
|
||||||
|
{
|
||||||
|
for (int k = ypred; k < i; k++)
|
||||||
|
mIns[k].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
|
||||||
|
mIns.Remove(j + 2);
|
||||||
|
mIns.Remove(j + 1);
|
||||||
|
mIns.Remove(j - 1);
|
||||||
|
mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEY));
|
||||||
|
mIns.Insert(i + 1, NativeCodeInstruction(mIns[i].mIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg));
|
||||||
|
i += 2;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14446,7 +14517,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
|
||||||
mIns[i + 3].mType == ASMIT_TAY)
|
mIns[i + 3].mType == ASMIT_TAY)
|
||||||
{
|
{
|
||||||
if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == yoffset + 1 && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == ((yoffset + 1) & 0xff) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
for (int j = ypred; j < i; j++)
|
for (int j = ypred; j < i; j++)
|
||||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
@ -14456,6 +14527,16 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[i + 3].mType = ASMIT_INY;
|
mIns[i + 3].mType = ASMIT_INY;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == ((yoffset - 1) & 0xff) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
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_DEY;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yreg = mIns[i + 1].mAddress;
|
yreg = mIns[i + 1].mAddress;
|
||||||
|
@ -14467,18 +14548,18 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
else if (i + 3 < mIns.Size() &&
|
else if (i + 3 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == yoffset + 1 &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset + 1) & 0xff) &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
!(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
for (int j = ypred; j < i + 3; j++)
|
for (int j = ypred; j < i + 3; j++)
|
||||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z);
|
||||||
mIns[i + 0].mType = ASMIT_INY;
|
mIns[i + 0].mType = ASMIT_INY;
|
||||||
mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mAddress = mIns[i + 3].mAddress;
|
mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mAddress = mIns[i + 3].mAddress;
|
||||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
ypred = i + 1;
|
ypred = i + 1;
|
||||||
yoffset++;
|
yoffset = (yoffset + 1) & 0xff;
|
||||||
|
|
||||||
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||||
{
|
{
|
||||||
|
@ -14495,18 +14576,46 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
else if (i + 3 < mIns.Size() &&
|
else if (i + 3 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == yoffset + 2 &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset - 1) & 0xff) &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
!(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
for (int j = ypred; j < i + 3; j++)
|
for (int j = ypred; j < i + 3; j++)
|
||||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z);
|
||||||
|
mIns[i + 0].mType = ASMIT_DEY;
|
||||||
|
mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mAddress = mIns[i + 3].mAddress;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
ypred = i + 1;
|
||||||
|
yoffset = (yoffset - 1) & 0xff;
|
||||||
|
|
||||||
|
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||||
|
{
|
||||||
|
mIns[i + 3].mType = ASMIT_TYA;
|
||||||
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
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 + 1].mAddress == yreg &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset + 2) & 0xff) &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
for (int j = ypred; j < i + 3; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z);
|
||||||
mIns[i + 0].mType = ASMIT_INY;
|
mIns[i + 0].mType = ASMIT_INY;
|
||||||
mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].CopyMode(mIns[i + 3]);
|
mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].CopyMode(mIns[i + 3]);
|
||||||
|
|
||||||
ypred = i + 1;
|
ypred = i + 1;
|
||||||
yoffset++;
|
yoffset = (yoffset + 2) & 0xff;
|
||||||
|
|
||||||
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||||
{
|
{
|
||||||
|
@ -14531,7 +14640,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
||||||
mIns[i + 1].mType = ASMIT_STY;
|
mIns[i + 1].mType = ASMIT_STY;
|
||||||
|
|
||||||
ypred = i + 1;
|
ypred = i + 1;
|
||||||
yoffset++;
|
yoffset = (yoffset + 1) & 0xff;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14898,7 +15007,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
||||||
mIns[i + 1].mType == ASMIT_CLC &&
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE)
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && mIns[predXPos + 2].mAddress + 1 == mIns[i + 2].mAddress)
|
if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && ((mIns[predXPos + 2].mAddress + 1) & 0xff) == mIns[i + 2].mAddress)
|
||||||
{
|
{
|
||||||
// Remove add
|
// Remove add
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
@ -14918,6 +15027,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && ((mIns[predXPos + 2].mAddress - 1) & 0xff) == mIns[i + 2].mAddress)
|
||||||
|
{
|
||||||
|
// Remove add
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
// Insert DEX
|
||||||
|
mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEX));
|
||||||
|
|
||||||
|
// Insert TAX
|
||||||
|
mIns[predXPos + 2].mLive &= ~LIVE_CPU_REG_X;
|
||||||
|
mIns.Insert(predXPos + 3, NativeCodeInstruction(mIns[i].mIns, ASMIT_TAX));
|
||||||
|
|
||||||
|
// Restart
|
||||||
|
restart = true;
|
||||||
|
predXPos = -1;
|
||||||
|
predYPos = -1;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
predXPos = i;
|
predXPos = i;
|
||||||
}
|
}
|
||||||
|
@ -14927,7 +15056,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
||||||
mIns[i + 1].mType == ASMIT_CLC &&
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE)
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && mIns[predYPos + 2].mAddress + 1 == mIns[i + 2].mAddress)
|
if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && ((mIns[predYPos + 2].mAddress + 1) & 0xff) == mIns[i + 2].mAddress)
|
||||||
{
|
{
|
||||||
// Remove add
|
// Remove add
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
@ -14947,6 +15076,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && ((mIns[predYPos + 2].mAddress - 1) & 0xff) == mIns[i + 2].mAddress)
|
||||||
|
{
|
||||||
|
// Remove add
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
// Insert DEY
|
||||||
|
mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEY));
|
||||||
|
|
||||||
|
// Insert TAX
|
||||||
|
mIns[predYPos + 2].mLive &= ~LIVE_CPU_REG_Y;
|
||||||
|
mIns.Insert(predYPos + 3, NativeCodeInstruction(mIns[i].mIns, ASMIT_TAY));
|
||||||
|
|
||||||
|
// Restart
|
||||||
|
restart = true;
|
||||||
|
predXPos = -1;
|
||||||
|
predYPos = -1;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
predYPos = i;
|
predYPos = i;
|
||||||
}
|
}
|
||||||
|
@ -41436,6 +41585,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 3].mType = ASMIT_NOP;
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress >= 0xfe &&
|
||||||
|
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_DEX; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_Z;
|
||||||
|
if (mIns[i + 2].mAddress == 0xfe)
|
||||||
|
mIns[i + 2].mType = ASMIT_DEX;
|
||||||
|
else
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X;
|
||||||
|
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||||
|
mIns[i + 3].mType = ASMIT_TXA;
|
||||||
|
else
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TXA &&
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
|
@ -41474,6 +41642,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress >= 0xfe &&
|
||||||
|
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z;
|
||||||
|
if (mIns[i + 2].mAddress == 0xfe)
|
||||||
|
mIns[i + 2].mType = ASMIT_DEY;
|
||||||
|
else
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||||
|
mIns[i + 3].mType = ASMIT_TYA;
|
||||||
|
else
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TYA &&
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
mIns[i + 1].mType == ASMIT_SEC &&
|
mIns[i + 1].mType == ASMIT_SEC &&
|
||||||
|
@ -45239,7 +45426,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "check");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -47779,7 +47966,7 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
||||||
{
|
{
|
||||||
if (ncp->mCount > 1)
|
if (ncp->mCount > 1)
|
||||||
{
|
{
|
||||||
printf("RFC %s : %d\n", ncp->mLinkerObject->mIdent->mString, ncp->mCount);
|
// printf("RFC %s : %d\n", ncp->mLinkerObject->mIdent->mString, ncp->mCount);
|
||||||
ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType);
|
ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType);
|
||||||
|
|
||||||
ExpandingArray<uint8> code;
|
ExpandingArray<uint8> code;
|
||||||
|
|
|
@ -8925,7 +8925,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
if ((initExp->mType == EX_ASSIGNMENT || initExp->mType == EX_INITIALIZATION) && initExp->mLeft->mType == EX_VARIABLE && initExp->mRight->mType == EX_CONSTANT &&
|
if ((initExp->mType == EX_ASSIGNMENT || initExp->mType == EX_INITIALIZATION) && initExp->mLeft->mType == EX_VARIABLE && initExp->mRight->mType == EX_CONSTANT &&
|
||||||
(iterateExp->mType == EX_POSTINCDEC || iterateExp->mType == EX_PREINCDEC || iterateExp->mType == EX_ASSIGNMENT && iterateExp->mToken == TK_ASSIGN_ADD && iterateExp->mRight->mType == EX_CONSTANT) &&
|
(iterateExp->mType == EX_POSTINCDEC || iterateExp->mType == EX_PREINCDEC || iterateExp->mType == EX_ASSIGNMENT && iterateExp->mToken == TK_ASSIGN_ADD && iterateExp->mRight->mType == EX_CONSTANT) &&
|
||||||
iterateExp->mLeft->IsSame(initExp->mLeft) &&
|
iterateExp->mLeft->IsSame(initExp->mLeft) &&
|
||||||
conditionExp->mType == EX_RELATIONAL && (conditionExp->mToken == TK_LESS_THAN || conditionExp->mToken == TK_GREATER_THAN) && conditionExp->mLeft->IsSame(initExp->mLeft) && conditionExp->mRight->mType == EX_CONSTANT)
|
conditionExp->mType == EX_RELATIONAL && (conditionExp->mToken == TK_LESS_THAN || conditionExp->mToken == TK_GREATER_THAN || conditionExp->mToken == TK_LESS_EQUAL || conditionExp->mToken == TK_GREATER_EQUAL) && conditionExp->mLeft->IsSame(initExp->mLeft) && conditionExp->mRight->mType == EX_CONSTANT)
|
||||||
{
|
{
|
||||||
if (initExp->mRight->mDecValue->mType == DT_CONST_INTEGER && conditionExp->mRight->mDecValue->mType == DT_CONST_INTEGER)
|
if (initExp->mRight->mDecValue->mType == DT_CONST_INTEGER && conditionExp->mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
{
|
{
|
||||||
|
@ -8933,6 +8933,17 @@ Expression* Parser::ParseStatement(void)
|
||||||
int endValue = int(conditionExp->mRight->mDecValue->mInteger);
|
int endValue = int(conditionExp->mRight->mDecValue->mInteger);
|
||||||
int stepValue = 1;
|
int stepValue = 1;
|
||||||
|
|
||||||
|
if (conditionExp->mToken == TK_LESS_EQUAL)
|
||||||
|
{
|
||||||
|
endValue++;
|
||||||
|
conditionExp->mToken = TK_LESS_THAN;
|
||||||
|
}
|
||||||
|
else if (conditionExp->mToken == TK_GREATER_EQUAL)
|
||||||
|
{
|
||||||
|
endValue--;
|
||||||
|
conditionExp->mToken = TK_GREATER_THAN;
|
||||||
|
}
|
||||||
|
|
||||||
if (iterateExp->mType == EX_ASSIGNMENT)
|
if (iterateExp->mType == EX_ASSIGNMENT)
|
||||||
stepValue = int(iterateExp->mRight->mDecValue->mInteger);
|
stepValue = int(iterateExp->mRight->mDecValue->mInteger);
|
||||||
else if (iterateExp->mToken == TK_DEC)
|
else if (iterateExp->mToken == TK_DEC)
|
||||||
|
@ -9018,7 +9029,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
unrollBody->mLeft = bodyExp;
|
unrollBody->mLeft = bodyExp;
|
||||||
Expression* bexp = unrollBody;
|
Expression* bexp = unrollBody;
|
||||||
if (endValue > startValue)
|
if ((endValue - startValue) * stepValue > 0)
|
||||||
{
|
{
|
||||||
for (int i = 1; i < unrollLoop; i++)
|
for (int i = 1; i < unrollLoop; i++)
|
||||||
{
|
{
|
||||||
|
@ -9029,6 +9040,8 @@ Expression* Parser::ParseStatement(void)
|
||||||
bexp = bexp->mRight;
|
bexp = bexp->mRight;
|
||||||
bexp->mLeft = bodyExp;
|
bexp->mLeft = bodyExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conditionExp->mRight->mDecValue->mInteger = endValue - stepValue * (unrollLoop - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remain)
|
if (remain)
|
||||||
|
|
Loading…
Reference in New Issue