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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -115,6 +115,9 @@ void vic_waitFrames(char n);
|
|||
// wait for a specific raster line
|
||||
void vic_waitLine(int line);
|
||||
|
||||
// wait for beam to be below a line
|
||||
void vic_waitBelow(int line);
|
||||
|
||||
// reference to the VIC chip
|
||||
#define vic (*((struct VIC *)0xd000))
|
||||
|
||||
|
|
|
@ -14531,6 +14531,67 @@ static bool IsInsSrcModifiedInBlocks(const ExpandingArray<InterCodeBasicBlock*>&
|
|||
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)
|
||||
{
|
||||
if (!mVisited)
|
||||
|
@ -20208,6 +20269,9 @@ void InterCodeProcedure::Close(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->SingleLoopCountZeroCheck();
|
||||
|
||||
RemoveUnusedPartialStoreInstructions();
|
||||
|
||||
MapVariables();
|
||||
|
|
|
@ -579,6 +579,7 @@ public:
|
|||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||
void PushMoveOutOfLoop(void);
|
||||
bool MoveConditionOutOfLoop(void);
|
||||
void SingleLoopCountZeroCheck(void);
|
||||
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
||||
void RemoveUnusedMallocs(void);
|
||||
|
|
|
@ -14401,6 +14401,64 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
yoffset = 2;
|
||||
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
|
||||
yoffset = 0;
|
||||
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].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++)
|
||||
mIns[k].mLive |= LIVE_CPU_REG_Y;
|
||||
|
@ -14432,6 +14490,19 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
i += 2;
|
||||
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 + 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++)
|
||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||
|
@ -14456,6 +14527,16 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
mIns[i + 3].mType = ASMIT_INY;
|
||||
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
|
||||
{
|
||||
yreg = mIns[i + 1].mAddress;
|
||||
|
@ -14467,18 +14548,18 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
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 + 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].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[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z);
|
||||
mIns[i + 0].mType = ASMIT_INY;
|
||||
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 = (yoffset + 1) & 0xff;
|
||||
|
||||
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||
{
|
||||
|
@ -14495,18 +14576,46 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
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 &&
|
||||
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].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[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 + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].CopyMode(mIns[i + 3]);
|
||||
|
||||
ypred = i + 1;
|
||||
yoffset++;
|
||||
yoffset = (yoffset + 2) & 0xff;
|
||||
|
||||
if (mIns[i + 3].mLive & LIVE_CPU_REG_A)
|
||||
{
|
||||
|
@ -14531,7 +14640,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
|
|||
mIns[i + 1].mType = ASMIT_STY;
|
||||
|
||||
ypred = i + 1;
|
||||
yoffset++;
|
||||
yoffset = (yoffset + 1) & 0xff;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14898,7 +15007,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
|||
mIns[i + 1].mType == ASMIT_CLC &&
|
||||
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
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
|
@ -14918,6 +15027,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
|||
|
||||
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
|
||||
predXPos = i;
|
||||
}
|
||||
|
@ -14927,7 +15056,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
|||
mIns[i + 1].mType == ASMIT_CLC &&
|
||||
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
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
|
@ -14947,6 +15076,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void)
|
|||
|
||||
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
|
||||
predYPos = i;
|
||||
}
|
||||
|
@ -41436,6 +41585,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
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
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_TXA &&
|
||||
|
@ -41474,6 +41642,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||
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 (
|
||||
mIns[i + 0].mType == ASMIT_TYA &&
|
||||
mIns[i + 1].mType == ASMIT_SEC &&
|
||||
|
@ -45239,7 +45426,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "check");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -47779,7 +47966,7 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
|||
{
|
||||
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);
|
||||
|
||||
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 &&
|
||||
(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) &&
|
||||
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)
|
||||
{
|
||||
|
@ -8933,6 +8933,17 @@ Expression* Parser::ParseStatement(void)
|
|||
int endValue = int(conditionExp->mRight->mDecValue->mInteger);
|
||||
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)
|
||||
stepValue = int(iterateExp->mRight->mDecValue->mInteger);
|
||||
else if (iterateExp->mToken == TK_DEC)
|
||||
|
@ -9018,7 +9029,7 @@ Expression* Parser::ParseStatement(void)
|
|||
Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||
unrollBody->mLeft = bodyExp;
|
||||
Expression* bexp = unrollBody;
|
||||
if (endValue > startValue)
|
||||
if ((endValue - startValue) * stepValue > 0)
|
||||
{
|
||||
for (int i = 1; i < unrollLoop; i++)
|
||||
{
|
||||
|
@ -9029,6 +9040,8 @@ Expression* Parser::ParseStatement(void)
|
|||
bexp = bexp->mRight;
|
||||
bexp->mLeft = bodyExp;
|
||||
}
|
||||
|
||||
conditionExp->mRight->mDecValue->mInteger = endValue - stepValue * (unrollLoop - 1);
|
||||
}
|
||||
|
||||
if (remain)
|
||||
|
|
Loading…
Reference in New Issue