From 1f492e7820f58ecaf7d9d404c4c0141ee49cbdb6 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:57:01 +0200 Subject: [PATCH] Improve size optimization --- include/crt.c | 19 ++++---- oscar64/Disassembler.cpp | 2 +- oscar64/NativeCodeGenerator.cpp | 77 ++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/include/crt.c b/include/crt.c index f35c7dd..8750d5c 100644 --- a/include/crt.c +++ b/include/crt.c @@ -3067,9 +3067,7 @@ __asm fmul lda accu ora accu + 1 ora accu + 2 - bne W1 - sta accu + 3 - rts + beq E3 W1: lda tmp ora tmp + 1 @@ -3078,6 +3076,7 @@ W1: sta accu sta accu + 1 sta accu + 2 +E3: sta accu + 3 rts W2: @@ -3135,6 +3134,7 @@ INF: ora #$7f sta accu + 3 lda #$80 +E2: sta accu + 2 lda #$00 sta accu + 0 @@ -3158,11 +3158,8 @@ W8: rts ZERO: lda #0 - sta accu - sta accu + 1 - sta accu + 2 sta accu + 3 - rts + beq E2 } __asm inp_binop_mul_f32 @@ -4602,6 +4599,9 @@ loop: adc tmp + 1 sta tmp + 3 + // exit if overflowing memory + bcs hzempty + // Check if in range of current free block @@ -4618,7 +4618,10 @@ loop: lda accu ldx accu + 1 jmp loop - +hzempty: + lda #0 + sta accu + sta accu + 1 hempty: // no more heap blocks #ifdef HEAPCHECK diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index e3d0cd1..9bdc9fc 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -846,7 +846,7 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU); return buffer; } - else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 7) + else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 8) { sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK); return buffer; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index c308056..512863d 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -41198,6 +41198,45 @@ bool NativeCodeBasicBlock::BlockSizeCopyReduction(NativeCodeProcedure* proc, int } } + +#if 1 + if (si + 5 < mIns.Size() && + mIns[si + 0].mType == ASMIT_LDY && mIns[si + 0].mMode == ASMIM_IMMEDIATE && + mIns[si + 1].mType == ASMIT_STA && mIns[si + 1].mMode == ASMIM_INDIRECT_Y) + { + int i = 1; + while (si + 2 * i + 1 < mIns.Size() && + mIns[si + 2 * i + 0].mType == ASMIT_LDY && + mIns[si + 2 * i + 0].mMode == ASMIM_IMMEDIATE && + mIns[si + 2 * i + 0].mAddress == mIns[si + 0].mAddress + i && + mIns[si + 2 * i + 1].mType == ASMIT_STA && + mIns[si + 2 * i + 1].mMode == ASMIM_INDIRECT_Y && + mIns[si + 2 * i + 1].mAddress == mIns[si + 1].mAddress) + { + i++; + } + + if (i > 2) + { + int k = mIns[si + 0].mAddress + i - 1; + mIns[di + 0] = NativeCodeInstruction(mIns[si + 0].mIns, ASMIT_LDY, ASMIM_IMMEDIATE, mIns[si + 0].mAddress - 1); + mIns[di + 2] = mIns[si + 1]; + mIns[di + 1] = NativeCodeInstruction(mIns[si + 0].mIns, ASMIT_INY); + mIns[di + 3] = NativeCodeInstruction(mIns[si + 0].mIns, ASMIT_CPY, ASMIM_IMMEDIATE, k); + mIns[di + 4] = NativeCodeInstruction(mIns[si + 0].mIns, ASMIT_BNE, ASMIM_RELATIVE, -7); + di += 5; + si += 2 * i; + if (si == mIns.Size()) + { + mNDataSet.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; + mNDataSet.mRegs[CPU_REG_C].mValue = 1; + mNDataSet.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; + mNDataSet.mRegs[CPU_REG_Z].mValue = 0; + } + return true; + } + } +#endif } return false; @@ -41905,7 +41944,12 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen { if (mIns[i].mMode == ASMIM_IMMEDIATE) { - if (yimm && mIns[i].mAddress == ((yval + 1) & 0xff)) + if (yimm && mIns[i].mAddress == yval) + { + mIns[i].mType = ASMIT_NOP; + mIns[i].mMode = ASMIM_IMPLIED; + } + else if (yimm && mIns[i].mAddress == ((yval + 1) & 0xff)) { yval = mIns[i].mAddress; mIns[i].mType = ASMIT_INY; @@ -47557,6 +47601,35 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate5(int i, int pass) mIns[i + 4].mType = ASMIT_DEC; return true; } + else if ( + mIns[i + 0].mType == ASMIT_TXA && + mIns[i + 1].mType == ASMIT_STA && + mIns[i + 2].mType == ASMIT_CLC && + mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 1 && + mIns[i + 4].mType == ASMIT_TAX && !(mIns[i + 4].mLive & LIVE_CPU_REG_C)) + { + mIns[i + 0].mLive |= LIVE_CPU_REG_X; + mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mType = ASMIT_INX; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_Z; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + mIns[i + 4].mType = ASMIT_TXA; + return true; + } + else if ( + mIns[i + 0].mType == ASMIT_TXA && + mIns[i + 1].mType == ASMIT_STA && + mIns[i + 2].mType == ASMIT_SEC && + mIns[i + 3].mType == ASMIT_SBC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 1 && + mIns[i + 4].mType == ASMIT_TAX && !(mIns[i + 4].mLive & LIVE_CPU_REG_C)) + { + mIns[i + 0].mLive |= LIVE_CPU_REG_X; + mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mType = ASMIT_DEX; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_Z; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + mIns[i + 4].mType = ASMIT_TXA; + return true; + } + return false; } @@ -51327,7 +51400,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc = proc; mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "printf"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "setGameObjectTimedEdge_3"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks];