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
|
@call :test structmembertest.c
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test structarraycopy.c
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :test randsumtest.c
|
@call :test randsumtest.c
|
||||||
@if %errorlevel% neq 0 goto :error
|
@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_AUTO_UNROLL = 0x00000040;
|
||||||
static const uint64 COPT_OPTIMIZE_CONST_EXPRESSIONS = 0x00000080;
|
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_PRG = 0x100000000ULL;
|
||||||
static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL;
|
static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL;
|
||||||
static const uint64 COPT_TARGET_CRT512 = 0x400000000ULL;
|
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_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;
|
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;
|
return true;
|
||||||
else if (mMode == ASMIM_INDIRECT_Y && (mAddress == address || mAddress + 1 == address))
|
else if (mMode == ASMIM_INDIRECT_Y && (mAddress == address || mAddress + 1 == address))
|
||||||
return true;
|
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
|
else
|
||||||
return false;
|
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
|
bool NativeCodeInstruction::ChangesAddress(void) const
|
||||||
{
|
{
|
||||||
if (mMode != ASMIM_IMPLIED)
|
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 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;
|
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++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
|
@ -9559,6 +9616,33 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc)
|
||||||
pblock->mIns.Push(mIns[0]);
|
pblock->mIns.Push(mIns[0]);
|
||||||
mIns.Remove(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;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9737,6 +9821,103 @@ bool NativeCodeBasicBlock::FindImmediateStore(int at, int reg, const NativeCodeI
|
||||||
return false;
|
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)
|
bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yval)
|
||||||
{
|
{
|
||||||
|
@ -9744,6 +9925,15 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
||||||
{
|
{
|
||||||
mPatched = true;
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
if (!mEntryRequiredRegs[reg] && !mEntryRequiredRegs[reg + 1])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mNumEntries > 1)
|
||||||
|
yval = -1;
|
||||||
|
}
|
||||||
|
|
||||||
while (at < mIns.Size())
|
while (at < mIns.Size())
|
||||||
{
|
{
|
||||||
NativeCodeInstruction& ins(mIns[at]);
|
NativeCodeInstruction& ins(mIns[at]);
|
||||||
|
@ -9764,6 +9954,12 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(int reg, int at, int yv
|
||||||
yval = (yval + 1) & 255;
|
yval = (yval + 1) & 255;
|
||||||
else if (ins.mType == ASMIT_DEY && yval >= 0)
|
else if (ins.mType == ASMIT_DEY && yval >= 0)
|
||||||
yval = (yval - 1) & 255;
|
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())
|
else if (ins.ChangesYReg())
|
||||||
yval = -1;
|
yval = -1;
|
||||||
|
|
||||||
|
@ -9786,6 +9982,8 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(int reg, int at, int yv
|
||||||
if (!mPatched)
|
if (!mPatched)
|
||||||
{
|
{
|
||||||
mPatched = true;
|
mPatched = true;
|
||||||
|
if (at == 0 && !mEntryRequiredRegs[reg] && !mEntryRequiredRegs[reg + 1])
|
||||||
|
return false;
|
||||||
|
|
||||||
while (at < mIns.Size())
|
while (at < mIns.Size())
|
||||||
{
|
{
|
||||||
|
@ -10838,6 +11036,10 @@ bool NativeCodeBasicBlock::MoveLoadStoreOutOfXYRangeUp(int at)
|
||||||
return false;
|
return false;
|
||||||
if (mIns[j].ChangesAddress() && mIns[j].SameEffectiveAddress(mIns[at + 1]))
|
if (mIns[j].ChangesAddress() && mIns[j].SameEffectiveAddress(mIns[at + 1]))
|
||||||
return false;
|
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)
|
if (mIns[j].mType == ASMIT_LDA)
|
||||||
{
|
{
|
||||||
|
@ -10973,32 +11175,54 @@ bool NativeCodeBasicBlock::MoveStoreXUp(int at)
|
||||||
{
|
{
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
int n = 0, inc = 0;;
|
||||||
|
int reg = mIns[at].mAddress;
|
||||||
|
|
||||||
while (at > 0)
|
while (at > 0)
|
||||||
{
|
{
|
||||||
if (mIns[at - 1].ChangesXReg() || mIns[at - 1].mType == ASMIT_STX)
|
if (mIns[at - 1].mType == ASMIT_INX)
|
||||||
return done;
|
|
||||||
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
|
|
||||||
{
|
{
|
||||||
if ((mIns[at - 1].mMode == ASMIM_ZERO_PAGE || mIns[at - 1].mMode == ASMIM_INDIRECT_Y) && mIns[at - 1].mAddress == mIns[at].mAddress)
|
n++;
|
||||||
return done;
|
inc++;
|
||||||
if (mIns[at - 1].mMode == ASMIM_INDIRECT_Y && mIns[at - 1].mAddress + 1 == mIns[at].mAddress)
|
}
|
||||||
return done;
|
else if (mIns[at - 1].mType == ASMIT_DEX)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
inc--;
|
||||||
}
|
}
|
||||||
else
|
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].mType == ASMIT_LDX || mIns[at - 1].mType == ASMIT_TAX)
|
||||||
return done;
|
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].ChangesXReg() || mIns[at - 1].mType == ASMIT_STX)
|
||||||
return done;
|
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 + 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 + n].mLinkerObject)
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
mIns[at].mLive |= mIns[at - 1].mLive;
|
||||||
|
|
||||||
|
NativeCodeInstruction ins = mIns[at - 1];
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
mIns[at].mLive |= mIns[at - 1].mLive;
|
|
||||||
|
|
||||||
NativeCodeInstruction ins = mIns[at - 1];
|
|
||||||
mIns[at - 1] = mIns[at];
|
|
||||||
mIns[at] = ins;
|
|
||||||
at--;
|
at--;
|
||||||
done = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return done;
|
return done;
|
||||||
|
@ -13857,8 +14081,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
#if 1
|
#if 1
|
||||||
for (int i = 0; i + 2 < mIns.Size(); i++)
|
for (int i = 0; i + 2 < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
if ((mIns[i + 0].mType == ASMIT_TAX || mIns[i + 0].mType == ASMIT_TAY) &&
|
if (mIns[i + 0].mType == ASMIT_TAX &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && (mIns[i + 1].mMode == ASMIM_ABSOLUTE || mIns[i + 1].mMode == ASMIM_ZERO_PAGE) &&
|
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)))
|
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))
|
if (MoveLoadStoreOutOfXYRangeUp(i))
|
||||||
|
@ -15790,6 +16022,41 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#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 (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TYA &&
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
mIns[i + 1].mType == ASMIT_CLC &&
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
@ -16183,6 +16450,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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 (i + 5 < mIns.Size())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -16221,7 +16504,8 @@ 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;
|
||||||
|
|
||||||
proc->ResetPatched();
|
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
|
#endif
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
bool LoadsAccu(void) const;
|
bool LoadsAccu(void) const;
|
||||||
bool ChangesAccuAndFlag(void) const;
|
bool ChangesAccuAndFlag(void) const;
|
||||||
bool ChangesAddress(void) const;
|
bool ChangesAddress(void) const;
|
||||||
|
bool UsesAddress(void) const;
|
||||||
bool ChangesAccu(void) const;
|
bool ChangesAccu(void) const;
|
||||||
bool UsesAccu(void) const;
|
bool UsesAccu(void) const;
|
||||||
bool ChangesCarry(void) const;
|
bool ChangesCarry(void) const;
|
||||||
|
@ -273,6 +274,9 @@ public:
|
||||||
|
|
||||||
bool CheckGlobalAddressSumYPointer(int reg, int at, int yval);
|
bool CheckGlobalAddressSumYPointer(int reg, int at, int yval);
|
||||||
bool PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject * lobj, int address);
|
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
|
class NativeCodeProcedure
|
||||||
|
|
|
@ -330,59 +330,53 @@ struct Enemy
|
||||||
int px;
|
int px;
|
||||||
byte py;
|
byte py;
|
||||||
sbyte dx;
|
sbyte dx;
|
||||||
byte n;
|
|
||||||
} enemies[5];
|
} enemies[5];
|
||||||
|
|
||||||
int spx = 40;
|
int spx = 40;
|
||||||
int vpx = 16;
|
int vpx = 16;
|
||||||
int ax = 0;
|
int ax = 0;
|
||||||
char spy = 100;
|
char spy = 100;
|
||||||
char fdelay = 0;
|
char fdelay = 0;
|
||||||
|
char edelay = 5;
|
||||||
|
char ecount = 0;
|
||||||
|
|
||||||
void enemies_move(void)
|
void enemies_move(void)
|
||||||
{
|
{
|
||||||
bool elive = false;
|
|
||||||
|
|
||||||
for(char i=0; i<5; i++)
|
for(char i=0; i<5; i++)
|
||||||
{
|
{
|
||||||
if (enemies[i].n)
|
if (enemies[i].dx)
|
||||||
{
|
{
|
||||||
enemies[i].n--;
|
|
||||||
enemies[i].px += enemies[i].dx;
|
enemies[i].px += enemies[i].dx;
|
||||||
|
|
||||||
int rx = enemies[i].px - spx;
|
int rx = enemies[i].px - spx;
|
||||||
if (enemies[i].dx < 0)
|
if (rx < -192 || rx >= 480)
|
||||||
{
|
{
|
||||||
if (rx < -24)
|
enemies[i].dx = 0;
|
||||||
enemies[i].n = 0;
|
ecount--;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (rx > 320)
|
|
||||||
enemies[i].n = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spr_move(2 + i, rx + 24, enemies[i].py + 50);
|
spr_move(2 + i, rx + 24, enemies[i].py + 50);
|
||||||
|
|
||||||
elive = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!elive)
|
void enemies_spwan(void)
|
||||||
{
|
{
|
||||||
for(char i=0; i<5; i++)
|
char u = rand();
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
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)
|
int main(void)
|
||||||
|
@ -430,7 +424,7 @@ int main(void)
|
||||||
|
|
||||||
spr_set(0, true, 160, 100, 64, VCOL_BLUE, true, false, false);
|
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);
|
spr_set(7, true, 160, 100, 64 + 16, VCOL_MED_GREY, true, false, false);
|
||||||
vic.spr_priority = 2;
|
vic.spr_priority = 0x80;
|
||||||
|
|
||||||
vpx = 2;
|
vpx = 2;
|
||||||
for(;;)
|
for(;;)
|
||||||
|
@ -497,15 +491,23 @@ int main(void)
|
||||||
vic.color_border++;
|
vic.color_border++;
|
||||||
vic_waitLine(82);
|
vic_waitLine(82);
|
||||||
vic.color_border++;
|
vic.color_border++;
|
||||||
tiles_draw(spx);
|
tiles_draw(spx & 4095);
|
||||||
vic.color_border--;
|
vic.color_border--;
|
||||||
enemies_move();
|
if (edelay)
|
||||||
|
{
|
||||||
|
edelay--;
|
||||||
|
if (edelay < 5)
|
||||||
|
enemies_spwan();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enemies_move();
|
||||||
|
if (!ecount)
|
||||||
|
edelay = 64 + (rand() & 63);
|
||||||
|
}
|
||||||
vic.color_border--;
|
vic.color_border--;
|
||||||
|
|
||||||
spx += vpx >> 1;
|
spx += vpx >> 2;
|
||||||
|
|
||||||
|
|
||||||
spx &= 4095;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue