Optimize single use of global variables in function
This commit is contained in:
parent
756245694f
commit
fbdb513697
|
@ -114,6 +114,9 @@ rem @echo off
|
|||
@call :test structmembertest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test structarraycopy.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test randsumtest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
|
||||
struct Point
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
|
||||
Point tcorners[8], pcorners[8];
|
||||
|
||||
int bm_line(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void drawCube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
bm_line();
|
||||
if (!(i & 2))
|
||||
bm_line();
|
||||
if (!(i & 4))
|
||||
bm_line();
|
||||
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
tcorners[i].x = (i + 1) * 3;
|
||||
tcorners[i].y = (i + 1) * 7;
|
||||
}
|
||||
|
||||
drawCube();
|
||||
|
||||
int sum = 0;
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
sum += pcorners[i].x;
|
||||
sum -= tcorners[i].y;
|
||||
}
|
||||
|
||||
return sum + 144;
|
||||
}
|
|
@ -10,6 +10,8 @@ static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020;
|
|||
static const uint64 COPT_OPTIMIZE_AUTO_UNROLL = 0x00000040;
|
||||
static const uint64 COPT_OPTIMIZE_CONST_EXPRESSIONS = 0x00000080;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 0x00000100;
|
||||
|
||||
static const uint64 COPT_TARGET_PRG = 0x100000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT512 = 0x400000000ULL;
|
||||
|
@ -24,7 +26,7 @@ static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE |
|
|||
|
||||
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
|
|
|
@ -690,6 +690,42 @@ bool NativeCodeInstruction::UsesZeroPage(int address) const
|
|||
return true;
|
||||
else if (mMode == ASMIM_INDIRECT_Y && (mAddress == address || mAddress + 1 == address))
|
||||
return true;
|
||||
else if (mType == ASMIT_JSR)
|
||||
{
|
||||
if (address >= BC_REG_ACCU && address < BC_REG_ACCU + 4)
|
||||
return true;
|
||||
if (address >= BC_REG_WORK && address < BC_REG_WORK + 4)
|
||||
return true;
|
||||
|
||||
if (mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
|
||||
if (mFlags & NCIF_USE_ZP_32_X)
|
||||
{
|
||||
if (address >= mParam && address < mParam + 4)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mFlags & NCIF_FEXEC)
|
||||
{
|
||||
if (address >= BC_REG_FPARAMS && address < BC_REG_FPARAMS_END)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mLinkerObject)
|
||||
{
|
||||
for (int i = 0; i < mLinkerObject->mNumTemporaries; i++)
|
||||
{
|
||||
if (address >= mLinkerObject->mTemporaries[i] && address < mLinkerObject->mTemporaries[i] + mLinkerObject->mTempSizes[i])
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -778,6 +814,20 @@ bool NativeCodeInstruction::ChangesAccu(void) const
|
|||
|
||||
|
||||
|
||||
bool NativeCodeInstruction::UsesAddress(void) const
|
||||
{
|
||||
if (mMode != ASMIM_IMPLIED)
|
||||
{
|
||||
return
|
||||
mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR ||
|
||||
mType == ASMIT_LDA || mType == ASMIT_LDX || mType == ASMIT_LDY ||
|
||||
mType == ASMIT_CMP || mType == ASMIT_CPX || mType == ASMIT_CPY ||
|
||||
mType == ASMIT_ADC || mType == ASMIT_SBC || mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::ChangesAddress(void) const
|
||||
{
|
||||
if (mMode != ASMIM_IMPLIED)
|
||||
|
@ -4897,7 +4947,14 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
|||
int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp], dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
|
||||
int size = ins->mConst.mOperandSize;
|
||||
if (size < 4)
|
||||
int msize = 4;
|
||||
|
||||
if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
|
||||
msize = 8;
|
||||
else if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE)
|
||||
msize = 2;
|
||||
|
||||
if (size <= msize)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
|
@ -9559,6 +9616,33 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
|||
pblock->mIns.Push(mIns[0]);
|
||||
mIns.Remove(0);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mIns[0].mType == ASMIT_LDX && mIns[0].mMode == ASMIM_ZERO_PAGE && !(mIns[0].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
if (lblock->mIns[ls - 2].mType == ASMIT_LDA && lblock->mIns[ls - 2].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 2].mAddress == mIns[0].mAddress &&
|
||||
lblock->mIns[ls - 1].mType == ASMIT_CMP && !(lblock->mIns[ls - 1].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
lblock->mIns[ls - 2].mType = ASMIT_LDX; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_X;
|
||||
lblock->mIns[ls - 1].mType = ASMIT_CPX; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_X;
|
||||
|
||||
pblock->mIns.Push(mIns[0]);
|
||||
mIns.Remove(0);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mIns[0].mType == ASMIT_LDA && mIns[0].mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
if (lblock->mIns[ls - 2].mType == ASMIT_LDA && lblock->mIns[ls - 2].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 2].mAddress == mIns[0].mAddress &&
|
||||
lblock->mIns[ls - 1].mType == ASMIT_CMP)
|
||||
{
|
||||
pblock->mIns.Push(mIns[0]);
|
||||
mIns.Remove(0);
|
||||
|
||||
lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_A;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -9737,6 +9821,103 @@ bool NativeCodeBasicBlock::FindImmediateStore(int at, int reg, const NativeCodeI
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains)
|
||||
{
|
||||
if (!mPatched)
|
||||
{
|
||||
mPatched = true;
|
||||
|
||||
if (at == 0)
|
||||
{
|
||||
if (!mEntryRequiredRegs[reg])
|
||||
return true;
|
||||
|
||||
if (mNumEntries > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
while (at < mIns.Size())
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[at]);
|
||||
|
||||
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||
{
|
||||
if (ins.UsesAddress())
|
||||
{
|
||||
if (ins.ChangesAddress())
|
||||
return false;
|
||||
return !(ins.mLive & LIVE_MEM);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else if (ins.mType == ASMIT_JSR)
|
||||
{
|
||||
if (ins.mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
if (ins.UsesZeroPage(reg))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress + 1 == reg))
|
||||
return false;
|
||||
else if (ins.ChangesZeroPage(reg))
|
||||
return true;
|
||||
else if (ains.MayBeChangedOnAddress(ins))
|
||||
return false;
|
||||
|
||||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoad(reg, 0, ains))
|
||||
return false;
|
||||
if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoad(reg, 0, ains))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mPatched)
|
||||
{
|
||||
mPatched = true;
|
||||
|
||||
if (at == 0 && !mEntryRequiredRegs[reg])
|
||||
return false;
|
||||
|
||||
while (at < mIns.Size())
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[at]);
|
||||
|
||||
if (ins.mMode == ASMIM_ZERO_PAGE && ins.mAddress == reg)
|
||||
{
|
||||
if (ins.UsesAddress())
|
||||
{
|
||||
assert(!(ins.mLive & LIVE_MEM));
|
||||
ins.CopyMode(ains);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
at++;
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->PatchSingleUseGlobalLoad(reg, 0, ains))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->PatchSingleUseGlobalLoad(reg, 0, ains))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yval)
|
||||
{
|
||||
|
@ -9744,6 +9925,15 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
{
|
||||
mPatched = true;
|
||||
|
||||
if (at == 0)
|
||||
{
|
||||
if (!mEntryRequiredRegs[reg] && !mEntryRequiredRegs[reg + 1])
|
||||
return true;
|
||||
|
||||
if (mNumEntries > 1)
|
||||
yval = -1;
|
||||
}
|
||||
|
||||
while (at < mIns.Size())
|
||||
{
|
||||
NativeCodeInstruction& ins(mIns[at]);
|
||||
|
@ -9764,6 +9954,12 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
yval = (yval + 1) & 255;
|
||||
else if (ins.mType == ASMIT_DEY && yval >= 0)
|
||||
yval = (yval - 1) & 255;
|
||||
else if (ins.mType == ASMIT_JSR)
|
||||
{
|
||||
if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1))
|
||||
return false;
|
||||
yval = -1;
|
||||
}
|
||||
else if (ins.ChangesYReg())
|
||||
yval = -1;
|
||||
|
||||
|
@ -9786,6 +9982,8 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(int reg, int at, int yv
|
|||
if (!mPatched)
|
||||
{
|
||||
mPatched = true;
|
||||
if (at == 0 && !mEntryRequiredRegs[reg] && !mEntryRequiredRegs[reg + 1])
|
||||
return false;
|
||||
|
||||
while (at < mIns.Size())
|
||||
{
|
||||
|
@ -10838,6 +11036,10 @@ bool NativeCodeBasicBlock::MoveLoadStoreOutOfXYRangeUp(int at)
|
|||
return false;
|
||||
if (mIns[j].ChangesAddress() && mIns[j].SameEffectiveAddress(mIns[at + 1]))
|
||||
return false;
|
||||
if (mIns[at + 1].mMode == ASMIM_ABSOLUTE_X && mIns[j].ChangesXReg())
|
||||
return false;
|
||||
if (mIns[at + 1].mMode == ASMIM_ABSOLUTE_Y && mIns[j].ChangesYReg())
|
||||
return false;
|
||||
|
||||
if (mIns[j].mType == ASMIT_LDA)
|
||||
{
|
||||
|
@ -10973,33 +11175,55 @@ bool NativeCodeBasicBlock::MoveStoreXUp(int at)
|
|||
{
|
||||
bool done = false;
|
||||
|
||||
int n = 0, inc = 0;;
|
||||
int reg = mIns[at].mAddress;
|
||||
|
||||
while (at > 0)
|
||||
{
|
||||
if (mIns[at - 1].ChangesXReg() || mIns[at - 1].mType == ASMIT_STX)
|
||||
return done;
|
||||
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
|
||||
if (mIns[at - 1].mType == ASMIT_INX)
|
||||
{
|
||||
if ((mIns[at - 1].mMode == ASMIM_ZERO_PAGE || mIns[at - 1].mMode == ASMIM_INDIRECT_Y) && mIns[at - 1].mAddress == mIns[at].mAddress)
|
||||
n++;
|
||||
inc++;
|
||||
}
|
||||
else if (mIns[at - 1].mType == ASMIT_DEX)
|
||||
{
|
||||
n++;
|
||||
inc--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mIns[at - 1].mType == ASMIT_LDX || mIns[at - 1].mType == ASMIT_TAX)
|
||||
return done;
|
||||
if (mIns[at - 1].mMode == ASMIM_INDIRECT_Y && mIns[at - 1].mAddress + 1 == mIns[at].mAddress)
|
||||
else if (mIns[at - 1].ChangesXReg() || mIns[at - 1].mType == ASMIT_STX)
|
||||
return done;
|
||||
else if (mIns[at + n].mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
if ((mIns[at - 1].mMode == ASMIM_ZERO_PAGE || mIns[at - 1].mMode == ASMIM_INDIRECT_Y) && mIns[at - 1].mAddress == reg)
|
||||
return done;
|
||||
if (mIns[at - 1].mMode == ASMIM_INDIRECT_Y && mIns[at - 1].mAddress + 1 == reg)
|
||||
return done;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mIns[at - 1].mMode == ASMIM_ABSOLUTE && mIns[at - 1].mLinkerObject == mIns[at].mLinkerObject && mIns[at - 1].mAddress == mIns[at].mAddress)
|
||||
if (mIns[at - 1].mMode == ASMIM_ABSOLUTE && mIns[at - 1].mLinkerObject == mIns[at + n].mLinkerObject && mIns[at - 1].mAddress == mIns[at + n].mAddress)
|
||||
return done;
|
||||
else if ((mIns[at - 1].mMode == ASMIM_ABSOLUTE_X || mIns[at - 1].mMode == ASMIM_ABSOLUTE_Y) && mIns[at - 1].mLinkerObject == mIns[at].mLinkerObject)
|
||||
else if ((mIns[at - 1].mMode == ASMIM_ABSOLUTE_X || mIns[at - 1].mMode == ASMIM_ABSOLUTE_Y) && mIns[at - 1].mLinkerObject == mIns[at + n].mLinkerObject)
|
||||
return done;
|
||||
}
|
||||
|
||||
mIns[at].mLive |= mIns[at - 1].mLive;
|
||||
|
||||
NativeCodeInstruction ins = mIns[at - 1];
|
||||
mIns[at - 1] = mIns[at];
|
||||
mIns[at] = ins;
|
||||
at--;
|
||||
if (ins.mMode == ASMIM_ABSOLUTE_X)
|
||||
ins.mAddress -= inc;
|
||||
|
||||
for (int i = 0; i <= n; i++)
|
||||
mIns[at - 1 + i] = mIns[at + i];
|
||||
mIns[at + n] = ins;
|
||||
done = true;
|
||||
}
|
||||
at--;
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
@ -13857,8 +14081,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
#if 1
|
||||
for (int i = 0; i + 2 < mIns.Size(); i++)
|
||||
{
|
||||
if ((mIns[i + 0].mType == ASMIT_TAX || mIns[i + 0].mType == ASMIT_TAY) &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||
if (mIns[i + 0].mType == ASMIT_TAX &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_A)))
|
||||
{
|
||||
if (MoveLoadStoreOutOfXYRangeUp(i))
|
||||
changed = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_TAY &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ABSOLUTE_X || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_A)))
|
||||
{
|
||||
if (MoveLoadStoreOutOfXYRangeUp(i))
|
||||
|
@ -15790,6 +16022,41 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
progress = true;
|
||||
}
|
||||
#endif
|
||||
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 <= 2 &&
|
||||
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_INX; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
|
||||
if (mIns[i + 2].mAddress == 2)
|
||||
mIns[i + 2].mType = ASMIT_INX;
|
||||
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;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_TXA &&
|
||||
mIns[i + 1].mType == ASMIT_SEC &&
|
||||
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||
mIns[i + 3].mType == ASMIT_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;
|
||||
if (mIns[i + 2].mAddress == 2)
|
||||
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;
|
||||
progress = true;
|
||||
}
|
||||
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_TYA &&
|
||||
mIns[i + 1].mType == ASMIT_CLC &&
|
||||
|
@ -16183,6 +16450,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
}
|
||||
}
|
||||
#endif
|
||||
if (i + 1 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE &&
|
||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (CheckSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i]))
|
||||
{
|
||||
proc->ResetPatched();
|
||||
if (PatchSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i]))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i + 5 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
|
@ -16221,7 +16504,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
|
||||
|
||||
proc->ResetPatched();
|
||||
progress = PatchGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress);
|
||||
if (PatchGlobalAddressSumYPointer(mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress))
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
bool LoadsAccu(void) const;
|
||||
bool ChangesAccuAndFlag(void) const;
|
||||
bool ChangesAddress(void) const;
|
||||
bool UsesAddress(void) const;
|
||||
bool ChangesAccu(void) const;
|
||||
bool UsesAccu(void) const;
|
||||
bool ChangesCarry(void) const;
|
||||
|
@ -273,6 +274,9 @@ public:
|
|||
|
||||
bool CheckGlobalAddressSumYPointer(int reg, int at, int yval);
|
||||
bool PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject * lobj, int address);
|
||||
|
||||
bool CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains);
|
||||
bool PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains);
|
||||
};
|
||||
|
||||
class NativeCodeProcedure
|
||||
|
|
|
@ -330,59 +330,53 @@ struct Enemy
|
|||
int px;
|
||||
byte py;
|
||||
sbyte dx;
|
||||
byte n;
|
||||
} enemies[5];
|
||||
|
||||
int spx = 40;
|
||||
int vpx = 16;
|
||||
int ax = 0;
|
||||
char spy = 100;
|
||||
char fdelay = 0;
|
||||
int spx = 40;
|
||||
int vpx = 16;
|
||||
int ax = 0;
|
||||
char spy = 100;
|
||||
char fdelay = 0;
|
||||
char edelay = 5;
|
||||
char ecount = 0;
|
||||
|
||||
void enemies_move(void)
|
||||
{
|
||||
bool elive = false;
|
||||
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
if (enemies[i].n)
|
||||
if (enemies[i].dx)
|
||||
{
|
||||
enemies[i].n--;
|
||||
enemies[i].px += enemies[i].dx;
|
||||
|
||||
int rx = enemies[i].px - spx;
|
||||
if (enemies[i].dx < 0)
|
||||
if (rx < -192 || rx >= 480)
|
||||
{
|
||||
if (rx < -24)
|
||||
enemies[i].n = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rx > 320)
|
||||
enemies[i].n = 0;
|
||||
enemies[i].dx = 0;
|
||||
ecount--;
|
||||
}
|
||||
|
||||
spr_move(2 + i, rx + 24, enemies[i].py + 50);
|
||||
|
||||
elive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!elive)
|
||||
{
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
sbyte v = 4 + (rand() & 1);
|
||||
enemies[i].py = 20 + 30 * i;
|
||||
enemies[i].dx = vpx < 0 ? v : -v;
|
||||
enemies[i].px = (vpx < 0 ? spx - 56 : spx + 320) + (rand() & 31);
|
||||
enemies[i].n = 100;
|
||||
void enemies_spwan(void)
|
||||
{
|
||||
char u = rand();
|
||||
|
||||
int rx = enemies[i].px - spx;
|
||||
char e = ecount;
|
||||
|
||||
spr_set(2 + i, true, rx + 24, enemies[i].py + 50, 96, VCOL_YELLOW, true, false, false);
|
||||
}
|
||||
}
|
||||
__assume(e < 5);
|
||||
|
||||
sbyte v = 1 + (u & 3);
|
||||
enemies[ecount].py = 20 + 30 * e;
|
||||
enemies[ecount].dx = vpx < 0 ? v : -v;
|
||||
enemies[ecount].px = (vpx < 0 ? spx - 56 : spx + 320) + ((u >> 1) & 31);
|
||||
|
||||
int rx = enemies[ecount].px - spx;
|
||||
|
||||
spr_set(2 + ecount, true, rx + 24, enemies[ecount].py + 50, vpx < 0 ? 97 : 96, VCOL_YELLOW, true, false, false);
|
||||
ecount++;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
@ -430,7 +424,7 @@ int main(void)
|
|||
|
||||
spr_set(0, true, 160, 100, 64, VCOL_BLUE, true, false, false);
|
||||
spr_set(7, true, 160, 100, 64 + 16, VCOL_MED_GREY, true, false, false);
|
||||
vic.spr_priority = 2;
|
||||
vic.spr_priority = 0x80;
|
||||
|
||||
vpx = 2;
|
||||
for(;;)
|
||||
|
@ -497,15 +491,23 @@ int main(void)
|
|||
vic.color_border++;
|
||||
vic_waitLine(82);
|
||||
vic.color_border++;
|
||||
tiles_draw(spx);
|
||||
tiles_draw(spx & 4095);
|
||||
vic.color_border--;
|
||||
if (edelay)
|
||||
{
|
||||
edelay--;
|
||||
if (edelay < 5)
|
||||
enemies_spwan();
|
||||
}
|
||||
else
|
||||
{
|
||||
enemies_move();
|
||||
if (!ecount)
|
||||
edelay = 64 + (rand() & 63);
|
||||
}
|
||||
vic.color_border--;
|
||||
|
||||
spx += vpx >> 1;
|
||||
|
||||
|
||||
spx &= 4095;
|
||||
spx += vpx >> 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue