Avoid inlining of native functions into byte code
This commit is contained in:
parent
c5fc186336
commit
b43edb2b4c
|
@ -9,7 +9,7 @@ static const unsigned mul40[25] = {
|
||||||
800, 840, 880, 920, 960
|
800, 840, 880, 920, 960
|
||||||
};
|
};
|
||||||
|
|
||||||
static void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
static __native inline void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||||
{
|
{
|
||||||
for(char i=0; i<n; i++)
|
for(char i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
|
@ -18,9 +18,7 @@ static void copy_fwd(char * sdp, const char * ssp, char * cdp, const char * csp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma native(copy_fwd)
|
static __native inline void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
||||||
|
|
||||||
static void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
|
||||||
{
|
{
|
||||||
for(char i=0; i<n; i++)
|
for(char i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
|
@ -29,9 +27,7 @@ static void fill_fwd(char * sdp, char * cdp, char ch, char color, char n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma native(fill_fwd)
|
static __native inline void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
||||||
|
|
||||||
static void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp, char n)
|
|
||||||
{
|
{
|
||||||
while (n)
|
while (n)
|
||||||
{
|
{
|
||||||
|
@ -41,9 +37,6 @@ static void copy_bwd(char * sdp, const char * ssp, char * cdp, const char * csp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma native(copy_bwd)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cwin_init(CharWin * win, char * screen, char sx, char sy, char wx, char wy)
|
void cwin_init(CharWin * win, char * screen, char sx, char sy, char wx, char wy)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1991,8 +1991,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlineConstexpr || (exp->mLeft->mDecValue->mFlags & DTF_INLINE))
|
if (inlineConstexpr)
|
||||||
doInline = true;
|
doInline = true;
|
||||||
|
else if (exp->mLeft->mDecValue->mFlags & DTF_INLINE)
|
||||||
|
{
|
||||||
|
if (proc->mNativeProcedure || !(exp->mLeft->mDecValue->mFlags & DTF_NATIVE))
|
||||||
|
doInline = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doInline)
|
if (doInline)
|
||||||
|
|
|
@ -2428,6 +2428,15 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[mAddress].mMode = NRDM_IMMEDIATE;
|
data.mRegs[mAddress].mMode = NRDM_IMMEDIATE;
|
||||||
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_X].mValue;
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
}
|
}
|
||||||
|
else if (data.mRegs[CPU_REG_X].mMode == NRDM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress].mMode = NRDM_ZERO_PAGE;
|
||||||
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
}
|
||||||
|
else if (data.mRegs[CPU_REG_X].mMode == NRDM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress] = data.mRegs[CPU_REG_X];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data.mRegs[CPU_REG_X].mMode = NRDM_ZERO_PAGE;
|
data.mRegs[CPU_REG_X].mMode = NRDM_ZERO_PAGE;
|
||||||
|
@ -2441,6 +2450,15 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[mAddress].mMode = NRDM_IMMEDIATE;
|
data.mRegs[mAddress].mMode = NRDM_IMMEDIATE;
|
||||||
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_Y].mValue;
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
}
|
}
|
||||||
|
else if (data.mRegs[CPU_REG_Y].mMode == NRDM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress].mMode = NRDM_ZERO_PAGE;
|
||||||
|
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
}
|
||||||
|
else if (data.mRegs[CPU_REG_Y].mMode == NRDM_ABSOLUTE)
|
||||||
|
{
|
||||||
|
data.mRegs[mAddress] = data.mRegs[CPU_REG_Y];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data.mRegs[CPU_REG_Y].mMode = NRDM_ZERO_PAGE;
|
data.mRegs[CPU_REG_Y].mMode = NRDM_ZERO_PAGE;
|
||||||
|
@ -9356,6 +9374,16 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(void)
|
||||||
mIns[i + 3].mType = ASMIT_STY;
|
mIns[i + 3].mType = ASMIT_STY;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (i + 1 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == yreg &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && yoffset == 0)
|
||||||
|
{
|
||||||
|
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 + 0].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 1].mType = ASMIT_STY;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
else if (mIns[i].mType == ASMIT_INY)
|
else if (mIns[i].mType == ASMIT_INY)
|
||||||
{
|
{
|
||||||
yoffset = (yoffset + 1) & 255;
|
yoffset = (yoffset + 1) & 255;
|
||||||
|
@ -9384,6 +9412,137 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::ForwardZpXIndex(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
int xreg = -1, xoffset = 0, xpred = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (xreg == mIns[i].mAddress)
|
||||||
|
{
|
||||||
|
if (xoffset == 0)
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (xoffset == 1 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INX)
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
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 (xoffset == 2 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INX && mIns[i + 2].mType == ASMIT_INX)
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
|
||||||
|
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
|
||||||
|
xoffset = 0;
|
||||||
|
xpred = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xreg = mIns[i].mAddress;
|
||||||
|
xoffset = 0;
|
||||||
|
xpred = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 + 3].mType == ASMIT_TAX)
|
||||||
|
{
|
||||||
|
if (mIns[i + 1].mAddress == xreg && mIns[i + 2].mAddress == xoffset + 1 && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
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_INX;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xreg = mIns[i + 1].mAddress;
|
||||||
|
xoffset = mIns[i + 2].mAddress;
|
||||||
|
xpred = i + 3;
|
||||||
|
i += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 == xreg &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == xoffset + 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == xreg &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 0].mType = ASMIT_INX;
|
||||||
|
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_STX;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (i + 1 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == xreg &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == xreg && xoffset == 0)
|
||||||
|
{
|
||||||
|
for (int j = xpred; j < i; j++)
|
||||||
|
mIns[j].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 0].mType = ASMIT_INX; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 1].mType = ASMIT_STX;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_INX)
|
||||||
|
{
|
||||||
|
xoffset = (xoffset + 1) & 255;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_DEX)
|
||||||
|
{
|
||||||
|
xoffset = (xoffset + 1) & 255;
|
||||||
|
}
|
||||||
|
else if (mIns[i].ChangesXReg())
|
||||||
|
{
|
||||||
|
xreg = -1;
|
||||||
|
}
|
||||||
|
else if (xreg >= 0 && mIns[i].ChangesZeroPage(xreg))
|
||||||
|
{
|
||||||
|
xreg = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->ForwardZpXIndex())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
if (mFalseJump && mFalseJump->ForwardZpXIndex())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::ReplaceXRegWithYReg(int start, int end)
|
bool NativeCodeBasicBlock::ReplaceXRegWithYReg(int start, int end)
|
||||||
{
|
{
|
||||||
for (int i = start; i < end; i++)
|
for (int i = start; i < end; i++)
|
||||||
|
@ -10010,6 +10169,31 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
if (mIns.Size() >= 2)
|
||||||
|
{
|
||||||
|
int ns = mIns.Size();
|
||||||
|
const NativeCodeInstruction& ins(mIns[ns - 2]);
|
||||||
|
|
||||||
|
if (ins.mType == ASMIT_STA && ins.mMode == ASMIM_ZERO_PAGE && mTrueJump && mFalseJump && !mIns[ns-1].ChangesAccu() && !mIns[ns-1].UsesZeroPage(ins.mAddress))
|
||||||
|
{
|
||||||
|
if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1)
|
||||||
|
{
|
||||||
|
mTrueJump->mIns.Insert(0, ins);
|
||||||
|
mIns.Remove(ns - 2);
|
||||||
|
mTrueJump->mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mFalseJump->mEntryRequiredRegs[ins.mAddress] && !mTrueJump->mEntryRequiredRegs[ins.mAddress] && mFalseJump->mEntryBlocks.Size() == 1)
|
||||||
|
{
|
||||||
|
mFalseJump->mIns.Insert(0, ins);
|
||||||
|
mIns.Remove(ns - 2);
|
||||||
|
mFalseJump->mEntryRequiredRegs += CPU_REG_A;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump)
|
if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump)
|
||||||
{
|
{
|
||||||
|
@ -12078,6 +12262,38 @@ bool NativeCodeBasicBlock::ReverseLoadCommutativeOpUp(int aload, int aop)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveLoadShiftRotateUp(int at)
|
||||||
|
{
|
||||||
|
int j = at - 1;
|
||||||
|
while (j > 0)
|
||||||
|
{
|
||||||
|
if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at + 0].mAddress)
|
||||||
|
{
|
||||||
|
if (mIns[j].mLive & LIVE_CPU_REG_C)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mIns.Insert(j + 1, mIns[at + 2]); // ROR ZP
|
||||||
|
mIns.Insert(j + 1, mIns[at + 2]); // LSR
|
||||||
|
|
||||||
|
mIns[at + 2].mType = ASMIT_NOP; mIns[at + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[at + 3].mType = ASMIT_NOP; mIns[at + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[at + 4].mType = ASMIT_NOP; mIns[at + 4].mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[j].ChangesZeroPage(mIns[at + 0].mAddress))
|
||||||
|
return false;
|
||||||
|
if (mIns[j].ChangesZeroPage(mIns[at + 2].mAddress))
|
||||||
|
return false;
|
||||||
|
if (mIns[j].UsesZeroPage(mIns[at + 2].mAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::MoveLoadAddZPStoreUp(int at)
|
bool NativeCodeBasicBlock::MoveLoadAddZPStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at - 1;
|
int j = at - 1;
|
||||||
|
@ -12831,7 +13047,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
{
|
{
|
||||||
if ((mIns[sz - 3].mType == ASMIT_INC || mIns[sz - 3].mType == ASMIT_DEC) && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
if ((mIns[sz - 3].mType == ASMIT_INC || mIns[sz - 3].mType == ASMIT_DEC) && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
||||||
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) &&
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) &&
|
||||||
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS || mBranch == ASMIT_BNE))
|
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS || mBranch == ASMIT_BNE))
|
||||||
{
|
{
|
||||||
// check for usage of Y register
|
// check for usage of Y register
|
||||||
|
@ -12841,6 +13057,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
int limit = mIns[sz - 1].mAddress;
|
int limit = mIns[sz - 1].mAddress;
|
||||||
int yinc = 0, xinc = 0;
|
int yinc = 0, xinc = 0;
|
||||||
|
|
||||||
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_X)
|
||||||
|
xother = true;
|
||||||
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_Y)
|
||||||
|
yother = true;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 3; i++)
|
for (int i = 0; i < sz - 3; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_TAY)
|
if (mIns[i].mType == ASMIT_TAY)
|
||||||
|
@ -13123,7 +13344,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
}
|
}
|
||||||
else if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
else if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
||||||
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) &&
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) &&
|
||||||
mBranch == ASMIT_BCC)
|
mBranch == ASMIT_BCC)
|
||||||
{
|
{
|
||||||
// check for usage of Y register
|
// check for usage of Y register
|
||||||
|
@ -13132,6 +13353,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
int lreg = mIns[sz - 1].mAddress;
|
int lreg = mIns[sz - 1].mAddress;
|
||||||
int zreg = mIns[sz - 3].mAddress;
|
int zreg = mIns[sz - 3].mAddress;
|
||||||
|
|
||||||
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_X)
|
||||||
|
xother = true;
|
||||||
|
if (mIns[sz - 1].mLive & LIVE_CPU_REG_Y)
|
||||||
|
yother = true;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 3; i++)
|
for (int i = 0; i < sz - 3; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == lreg && mIns[i].ChangesAddress())
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == lreg && mIns[i].ChangesAddress())
|
||||||
|
@ -14405,6 +14631,14 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
if (MoveLoadAddZPStoreUp(i))
|
if (MoveLoadAddZPStoreUp(i))
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
(mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL) && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
(mIns[i + 2].mType == ASMIT_ROL || mIns[i + 2].mType == ASMIT_ROR) && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
if (MoveLoadShiftRotateUp(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -15367,6 +15601,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 1].mAddress++;
|
mIns[i + 1].mAddress++;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_ROL && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 1].mType == ASMIT_AND && mIns[i + 1].mMode == ASMIM_IMMEDIATE && !(mIns[i + 1].mAddress & 0x01) && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_ASL;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_ROR && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 1].mType == ASMIT_AND && mIns[i + 1].mMode == ASMIM_IMMEDIATE && !(mIns[i + 1].mAddress & 0x80) && !(mIns[i + 1].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LSR;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -16276,6 +16524,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_ROL && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 2].mType == ASMIT_AND && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mAddress & 0x03) && !(mIns[i + 2].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_ASL;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_ROR && mIns[i + 0].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LSR && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 2].mType == ASMIT_AND && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mAddress & 0xc0) && !(mIns[i + 2].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LSR;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -17198,6 +17462,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
if (pass == 0 &&
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_LOWER) &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress &&
|
||||||
|
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
|
||||||
|
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 &&
|
||||||
|
!(mIns[i + 6].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (CheckGlobalAddressSumYPointer(mIns[i + 3].mAddress, i + 7, -1))
|
||||||
|
{
|
||||||
|
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_LDA;
|
||||||
|
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
proc->ResetPatched();
|
||||||
|
if (PatchGlobalAddressSumYPointer(mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress))
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (mIns[i + 0].mType == ASMIT_CLC &&
|
if (mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -18617,6 +18910,10 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (mEntryBlock->ForwardZpYIndex())
|
if (mEntryBlock->ForwardZpYIndex())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->ForwardZpXIndex())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
if (!changed && step < 6)
|
if (!changed && step < 6)
|
||||||
{
|
{
|
||||||
step++;
|
step++;
|
||||||
|
|
|
@ -228,6 +228,7 @@ public:
|
||||||
bool MoveLoadAddImmStoreUp(int at);
|
bool MoveLoadAddImmStoreUp(int at);
|
||||||
bool MoveCLCLoadAddZPStoreUp(int at);
|
bool MoveCLCLoadAddZPStoreUp(int at);
|
||||||
bool MoveLoadAddZPStoreUp(int at);
|
bool MoveLoadAddZPStoreUp(int at);
|
||||||
|
bool MoveLoadShiftRotateUp(int at);
|
||||||
bool MoveCLCLoadAddZPStoreDown(int at);
|
bool MoveCLCLoadAddZPStoreDown(int at);
|
||||||
bool FindDirectAddressSumY(int at, int reg, int& apos, int& breg);
|
bool FindDirectAddressSumY(int at, int reg, int& apos, int& breg);
|
||||||
bool PatchDirectAddressSumY(int at, int reg, int apos, int breg);
|
bool PatchDirectAddressSumY(int at, int reg, int apos, int breg);
|
||||||
|
@ -249,6 +250,7 @@ public:
|
||||||
bool ReplaceXRegWithYReg(int start, int end);
|
bool ReplaceXRegWithYReg(int start, int end);
|
||||||
|
|
||||||
bool ForwardZpYIndex(void);
|
bool ForwardZpYIndex(void);
|
||||||
|
bool ForwardZpXIndex(void);
|
||||||
|
|
||||||
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
|
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.4.99");
|
strcpy(strProductVersion, "1.4.100");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,4,99,0
|
FILEVERSION 1,4,100,0
|
||||||
PRODUCTVERSION 1,4,99,0
|
PRODUCTVERSION 1,4,100,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.4.99.0"
|
VALUE "FileVersion", "1.4.100.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.4.99.0"
|
VALUE "ProductVersion", "1.4.100.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -3945,15 +3945,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{39622A78-2972-4EF3-9E08-A2E1ECE24245}"
|
"ProductCode" = "8:{45A17741-A124-4021-8E20-83D28F7D4E81}"
|
||||||
"PackageCode" = "8:{0520CCC0-4961-4AC1-AABA-1471E1EC2D80}"
|
"PackageCode" = "8:{54019CFF-F2E1-43D2-A310-75724CBE2F2C}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.4.99"
|
"ProductVersion" = "8:1.4.100"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue