From 5b50389340135d50488971df8a6705b086883b59 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 21 Jul 2024 21:43:59 +0200 Subject: [PATCH] Optimize 32bit shifts --- autotest/bitshifttest.c | 4 ++++ oscar64/InterCode.cpp | 2 +- oscar64/NativeCodeGenerator.cpp | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/autotest/bitshifttest.c b/autotest/bitshifttest.c index 63d914a..f54ea20 100644 --- a/autotest/bitshifttest.c +++ b/autotest/bitshifttest.c @@ -373,21 +373,25 @@ int main(void) shr16n(0xfedc, 0xfedc); shl32b(0x00000000UL, 0x00000000L); + shl32b(0x00000001UL, 0x00000001L); shl32b(0xffffffffUL, 0xffffffffL); shl32b(0x12345678UL, 0x12345678L); shl32b(0xfedcba98UL, 0xfedcba98L); shr32b(0x00000000UL, 0x00000000L); + shr32b(0x00000001UL, 0x00000001L); shr32b(0xffffffffUL, 0xffffffffL); shr32b(0x12345678UL, 0x12345678L); shr32b(0xfedcba98UL, 0xfedcba98L); shl32n(0x00000000UL, 0x00000000L); + shl32n(0x00000001UL, 0x00000001L); shl32n(0xffffffffUL, 0xffffffffL); shl32n(0x12345678UL, 0x12345678L); shl32n(0xfedcba98UL, 0xfedcba98L); shr32n(0x00000000UL, 0x00000000L); + shr32n(0x00000001UL, 0x00000001L); shr32n(0xffffffffUL, 0xffffffffL); shr32n(0x12345678UL, 0x12345678L); shr32n(0xfedcba98UL, 0xfedcba98L); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 9c19616..c83e6f5 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -15247,7 +15247,7 @@ void InterCodeBasicBlock::EliminateDoubleLoopCounter(void) { if (mEntryBlocks[i] != mLoopPrefix) { - if (!mEntryBlocks[i]->CollectLoopBody(this, body)) + if (!mEntryBlocks[i]->CollectLoopBodyRecursive(this, body)) innerLoop = false; } } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b93f323..6c1d4db 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -9823,6 +9823,39 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p return eblock; } } + else if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst == 1) + { + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* hblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 0x1f)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_TAX, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 0x10)); + this->Close(ins, lblock, hblock, ASMIT_BEQ); + + NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bitshift"))); + + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 8, frt.mLinkerObject)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset, frt.mLinkerObject)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + lblock->Close(ins, eblock, nullptr, ASMIT_JMP); + + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset - 16, frt.mLinkerObject)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset - 8, frt.mLinkerObject)); + hblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + hblock->Close(ins, eblock, nullptr, ASMIT_JMP); + + return eblock; + } else { NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); @@ -44931,6 +44964,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate3(int i, int pass) mIns[i + 2].mLive |= LIVE_CPU_REG_Y; return true; } + else if ( + mIns[i + 0].mType == ASMIT_STA && + mIns[i + 1].mType == ASMIT_STA && + mIns[i + 2].IsShift() && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_MEM))) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 2].mMode = ASMIM_IMPLIED; + return true; + } if ( mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&