From e27075955df81a6104eb65aaf4b35253493402cc Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 12 Feb 2025 15:12:06 +0100 Subject: [PATCH] Optimize enums in bitfield usage --- oscar64/Compression.cpp | 2 +- oscar64/InterCode.cpp | 39 +++++++++++++++++++++++++++++++- oscar64/NativeCodeGenerator.cpp | 40 +++++++++++++++++++++++++++++++-- oscar64/Preprocessor.cpp | 2 +- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/oscar64/Compression.cpp b/oscar64/Compression.cpp index 64045f9..23fa6b5 100644 --- a/oscar64/Compression.cpp +++ b/oscar64/Compression.cpp @@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size) while (pi < 127 && pos < size) { int bi = pi, bj = 0; - for (int i = 1; i < (pos < 255 ? pos : 255); i++) + for (int i = 1; i <= (pos < 255 ? pos : 255); i++) { int j = 0; while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j]) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 73cb0c7..d5ce452 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -21227,6 +21227,43 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati CheckFinalLocal(); #endif + // Bubble up unrelated instructions + i = mInstructions.Size() - 2; + while (i >= 0) + { + if (mInstructions[i]->mCode == IC_LOAD || + mInstructions[i]->mCode == IC_UNARY_OPERATOR || + mInstructions[i]->mCode == IC_CONVERSION_OPERATOR || + mInstructions[i]->mCode == IC_BINARY_OPERATOR && (mInstructions[i]->mSrc[0].mTemp < 0 || mInstructions[i]->mSrc[1].mTemp < 0)) + { + InterInstruction* ins(mInstructions[i]); + + if (mInstructions[i + 1]->mCode == IC_CONSTANT && CanSwapInstructions(ins, mInstructions[i + 1])) + { + if (mInstructions[i + 2]->mNumOperands >= 1 && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal || + mInstructions[i + 2]->mNumOperands == 2 && mInstructions[i + 2]->mSrc[1].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[1].mFinal) + { + SwapInstructions(ins, mInstructions[i + 1]); + mInstructions[i] = mInstructions[i + 1]; + mInstructions[i + 1] = ins; + } + } + } + i--; + } + +#if 1 + do {} while (PeepholeReplaceOptimization(staticVars, staticProcs)); +#endif + + limit = mInstructions.Size() - 1; + if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH) + { + limit--; + if (limit > 0 && mInstructions[limit]->mCode == IC_RELATIONAL_OPERATOR) + limit--; + } + #if 1 i = limit; while (i >= 0) @@ -23226,7 +23263,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "shipyard_navigate"); + CheckFunc = !strcmp(mIdent->mString, "test_char_fit"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 891fa1a..660a38b 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -23750,6 +23750,7 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) if (mTrueJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && mTrueJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mFalseJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && !mFalseJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mTrueJump->mEntryRequiredRegs[CPU_REG_C] && + !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1) { mTrueJump->mEntryRequiredRegs += mIns[i + 1].mAddress; @@ -23769,6 +23770,7 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) else if (mFalseJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && mFalseJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mTrueJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && !mTrueJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C] && + !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && mFalseJump->mNumEntries == 1) { mFalseJump->mEntryRequiredRegs += mIns[i + 1].mAddress; @@ -23808,6 +23810,7 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) if (mTrueJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && mTrueJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mFalseJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && !mFalseJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mTrueJump->mEntryRequiredRegs[CPU_REG_C] && + !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && mTrueJump->mNumEntries == 1) { mTrueJump->mEntryRequiredRegs += mIns[i + 1].mAddress; @@ -23825,6 +23828,7 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) else if (mFalseJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && mFalseJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mTrueJump->mEntryRequiredRegs[mIns[i + 3].mAddress] && !mTrueJump->mEntryRequiredRegs[mIns[i + 6].mAddress] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C] && + !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && mFalseJump->mNumEntries == 1) { mFalseJump->mEntryRequiredRegs += mIns[i + 1].mAddress; @@ -42879,6 +42883,11 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen else carrySet = false; } + + else if (mEntryBlocks[i]->mBranch == ASMIT_BEQ && mEntryBlocks[i]->mTrueJump == this && mEntryBlocks[i]->mIns.Size() > 0 && mEntryBlocks[i]->mIns.Last().mType == ASMIT_CMP) + carryClear = false; + else if (mEntryBlocks[i]->mBranch == ASMIT_BNE && mEntryBlocks[i]->mFalseJump == this && mEntryBlocks[i]->mIns.Size() > 0 && mEntryBlocks[i]->mIns.Last().mType == ASMIT_CMP) + carryClear = false; else carryClear = carrySet = false; } @@ -44433,6 +44442,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate1(int i, int pass) mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED;; return true; } + else if (mIns[i].mType == ASMIT_CMP && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0x00 && (mIns[i].mLive & LIVE_CPU_REG_Z) == 0) + { + mIns[i].mType = ASMIT_SEC; mIns[i].mMode = ASMIM_IMPLIED;; + return true; + } else if (mIns[i].mType == ASMIT_ROR && mIns[i].mMode == ASMIM_IMPLIED && (mIns[i].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0) { mIns[i].mType = ASMIT_LSR; @@ -44590,6 +44604,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate2(int i, int pass) mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; return true; } + else if (mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 && mIns[i].ChangesAccuAndFlag()) + { + mIns[i + 0].mLive |= (mIns[i + 1].mLive & LIVE_CPU_REG_Z); + mIns[i + 1].mType = ASMIT_SEC; mIns[i + 1].mMode = ASMIM_IMPLIED; + return true; + } else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 1].mType == ASMIT_CMP && !(mIns[i + 1].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A))) { @@ -50776,6 +50796,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerExits(int pass) #if 1 int sz = mIns.Size(); + if (sz >= 1 && (mIns[sz - 1].mType == ASMIT_SEC || mIns[sz - 1].mType == ASMIT_CLC) && mExitRequiredRegs[CPU_REG_C]) + { + if (mTrueJump && mTrueJump->mIns.Size() == 1 && mTrueJump->mNumEntries == 1 && mTrueJump->mIns[0].mType == mIns[sz - 1].mType) + { + mTrueJump->mIns[0].mType = ASMIT_NOP; + mTrueJump->mEntryRequiredRegs += CPU_REG_C; + changed = true; + } + if (mFalseJump && mFalseJump->mIns.Size() == 1 && mFalseJump->mNumEntries == 1 && mFalseJump->mIns[0].mType == mIns[sz - 1].mType) + { + mFalseJump->mIns[0].mType = ASMIT_NOP; + mFalseJump->mEntryRequiredRegs += CPU_REG_C; + changed = true; + } + } + if (sz >= 2 && mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && mIns[sz - 1].mType == ASMIT_CMP) @@ -52657,7 +52693,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mIdent->mString, "renderTileScroll"); + CheckFunc = !strcmp(mIdent->mString, "bar"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -53632,6 +53668,7 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->PeepHoleOptimizer(step)) changed = true; #endif + if (step == 2) { ResetVisited(); @@ -53775,7 +53812,6 @@ void NativeCodeProcedure::Optimize(void) ResetVisited(); if (mEntryBlock->PropagateSinglePath()) changed = true; - } #if _DEBUG diff --git a/oscar64/Preprocessor.cpp b/oscar64/Preprocessor.cpp index ec1b83b..67714c2 100644 --- a/oscar64/Preprocessor.cpp +++ b/oscar64/Preprocessor.cpp @@ -44,7 +44,7 @@ bool SourceFile::ReadLineLZO(char* line, ptrdiff_t limit) while (pi < 127 && mPos < mFill) { int bi = pi, bj = 0; - for (int i = 1; i < mPos; i++) + for (int i = 1; i <= (mPos < 255 ? mPos : 255); i++) { int j = 0; while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])