From 8b63d5bb34b27949941eb0e4553c1ec73ed0f846 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 20 Feb 2022 14:12:01 +0100 Subject: [PATCH] Shortcut zero page register moves --- include/c64/vic.c | 2 + oscar64/NativeCodeGenerator.cpp | 148 ++++++++++++++++++++++++++++++++ oscar64/NativeCodeGenerator.h | 2 + samples/games/missile.c | 2 +- samples/memmap/easyflash.crt | Bin 114976 -> 114976 bytes 5 files changed, 153 insertions(+), 1 deletion(-) diff --git a/include/c64/vic.c b/include/c64/vic.c index b4fe164..21a8df3 100644 --- a/include/c64/vic.c +++ b/include/c64/vic.c @@ -40,6 +40,8 @@ void vic_setmode(VicMode mode, char * text, char * font) vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3; vic.ctrl2 = VIC_CTRL2_CSEL | VIC_CTRL2_MCM; break; + default: + __assume(false) } cia2.pra = (cia2.pra & 0xfc) | (((unsigned)text >> 14) ^ 0x03); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8b5d466..edc886a 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -10704,6 +10704,73 @@ bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at) return false; } +bool NativeCodeBasicBlock::ReplaceZeroPageUp(int at) +{ + int i = at - 1; + while (i >= 0) + { + if ((mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_STY) && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) + { + while (i < at) + { + if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) + mIns[i].mAddress = mIns[at + 1].mAddress; + i++; + } + + mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED; + mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED; + + return true; + } + + if (mIns[i].mType == ASMIT_JSR) + return false; + + if (mIns[i].ChangesZeroPage(mIns[at + 1].mAddress)) + return false; + if (mIns[i].UsesZeroPage(mIns[at + 1].mAddress)) + return false; + if (mIns[i].mMode == ASMIM_INDIRECT_Y && (mIns[i].mAddress == mIns[at].mAddress || mIns[i].mAddress + 1 == mIns[at].mAddress)) + return false; + + i--; + } + + return false; +} + + +bool NativeCodeBasicBlock::MoveLoadXUp(int at) +{ + int i = at - 1; + while (i >= 0) + { + if (mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) + { + mIns[i].mType = ASMIT_TAX; + mIns[i].mMode = ASMIM_IMPLIED; + mIns[at].mType = ASMIT_NOP; + mIns[at].mMode = ASMIM_IMPLIED; + while (i < at) + { + mIns[i].mLive |= LIVE_CPU_REG_X; + i++; + } + + return true; + } + + if (mIns[i].ChangesXReg() || (mIns[i].mLive & LIVE_CPU_REG_X) || mIns[i].UsesZeroPage(mIns[at].mAddress)) + return false; + + i--; + } + + return false; +} + + bool NativeCodeBasicBlock::MoveStoreXUp(int at) { bool done = false; @@ -11283,6 +11350,68 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc return true; } + if (sz >= 3 && mIns[0].mType == ASMIT_LDX && mIns[sz - 2].mType == ASMIT_LDA && mIns[0].SameEffectiveAddress(mIns[sz - 2]) && + mIns[sz - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, mIns[sz - 1].mMode) && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A)) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc); + + mIns[sz - 2].mType = ASMIT_LDX; + mIns[sz - 1].mType = ASMIT_CPX; + + prevBlock->mIns.Push(mIns[0]); + mIns.Remove(0); + return true; + } + + if (sz >= 2 && mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE) + { + int i = mIns.Size() - 1; + while (i > 0 && !mIns[i].ChangesYReg() && !mIns[i].ChangesZeroPage(mIns[0].mAddress)) + i--; + + if (i > 0 && + (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[0].mAddress) || + (mIns[i].mType == ASMIT_TAY && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress)) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc); + while (i < mIns.Size()) + { + mIns[i].mLive |= LIVE_CPU_REG_Y; + i++; + } + + prevBlock->mIns.Push(mIns[0]); + mIns.Remove(0); + return true; + } + } + + if (sz >= 2 && mIns[0].mType == ASMIT_LDX && mIns[0].mMode == ASMIM_ZERO_PAGE) + { + int i = mIns.Size() - 1; + while (i > 0 && !mIns[i].ChangesXReg() && !mIns[i].ChangesZeroPage(mIns[0].mAddress)) + i--; + + if (i > 0 && + (mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[0].mAddress) || + (mIns[i].mType == ASMIT_TAX && (mIns[i - 1].mType == ASMIT_LDA || mIns[i - 1].mType == ASMIT_STA) && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == mIns[0].mAddress)) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc); + while (i < mIns.Size()) + { + mIns[i].mLive |= LIVE_CPU_REG_X; + i++; + } + + prevBlock->mIns.Push(mIns[0]); + mIns.Remove(0); + return true; + } + } + int ai = 0; while (ai < mIns.Size() && !mIns[ai].ChangesAccu()) @@ -13033,6 +13162,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif +#if 1 + // replace zero page up + + for (int i = 1; i + 1 < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && 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)) && !(mIns[i + 0].mLive & LIVE_MEM)) + { + if (ReplaceZeroPageUp(i)) + changed = true; + } + } +#endif + + #if 1 // move load store pairs up to initial store @@ -13214,6 +13357,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) if (MoveStoreXUp(i)) changed = true; } + else if (mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM)) + { + if (MoveLoadXUp(i)) + changed = true; + } } #endif diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 6d20ca3..698f1a7 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -227,9 +227,11 @@ public: bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg); bool FindPageStartAddress(int at, int reg, int& addr); bool MoveStoreXUp(int at); + bool MoveLoadXUp(int at); bool MoveStoreHighByteDown(int at); bool MoveAddHighByteDown(int at); bool ReverseLoadCommutativeOpUp(int aload, int aop); + bool ReplaceZeroPageUp(int at); bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains); diff --git a/samples/games/missile.c b/samples/games/missile.c index 8c894aa..c07e529 100644 --- a/samples/games/missile.c +++ b/samples/games/missile.c @@ -833,7 +833,7 @@ int main(void) // Build to multicolor highres at top of screen rirq_build(&top, 3); - rirq_delay(&top, 9); + rirq_delay(&top, 10); rirq_write(&top, 1, &vic.ctrl1, VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3); rirq_write(&top, 2, &vic.memptr, 0x28); rirq_set(0, 57, &top); diff --git a/samples/memmap/easyflash.crt b/samples/memmap/easyflash.crt index 2d881414575a99ac77876fadb64eb0b55ed98eb3..438950c79ce5f1a81c0dd4bd05bcf89d6e253b4a 100644 GIT binary patch delta 481 zcmZ3`#J-@3eL}NRO{?Teo>nP~l{_zbKJc$v$*_Q7qU4DSzn@8+y70|nW&6vTiA#4f z)=Z9PG!U#+bv)wbHs*@WM(CpKF{GtR|~5 z*(!0Zl!l3%Wc>k0nazo(m1(E*h^*>+||MxxXyI})ePxsma%JplM2yB7ce delta 498 zcmZ3`#J-@3eL}O+gjUIwJgrg|D|ue>eBfWTl3@YEM9C8uem|2sb>W-E%Goa`OkBE? zal+(yMg#GQt-LFFTKN>5xmHeGz%)^LCC`b8$_n!)FJsIR;azFnD|lfgN3Ylgp9h>1 z>`t;=;F>JYWUJ4+QW{C(B;y6BfCNP4Nu~>{Rz@RKOs->6W((tKW!f1&c{x)QMv<6IIdKM_LG&obEHFyHkvk)I{?#X@3p^V2TKVeqk4C9eV