diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index f7680f5..581eca7 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -48,6 +48,7 @@ void Compiler::AddDefine(const Ident* ident, const char* value) bool Compiler::ParseSource(void) { mPreprocessor->mCompilerOptions = mCompilerOptions; + mLinker->mCompilerOptions = mCompilerOptions; CompilationUnit* cunit; while (mErrors->mErrorCount == 0 && (cunit = mCompilationUnits->PendingUnit())) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a98871e..6c60550 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -8712,6 +8712,17 @@ void InterCodeBasicBlock::PeepholeOptimization(void) int j = i; while (j > 0 && CanBypassLoadUp(ins, mInstructions[j - 1])) { + if (ins->mSrc[0].mFinal) + { + for (int k = 0; k < mInstructions[j - 1]->mNumOperands; k++) + { + if (mInstructions[j - 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp) + { + mInstructions[j - 1]->mSrc[k].mFinal = true; + ins->mSrc[0].mFinal = false; + } + } + } mInstructions[j] = mInstructions[j - 1]; j--; } @@ -8728,12 +8739,24 @@ void InterCodeBasicBlock::PeepholeOptimization(void) while (i >= 0) { // move non indirect loads down - if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8)) + if (mInstructions[i]->mCode == IC_LOAD && (mInstructions[i]->mSrc[0].mMemory != IM_INDIRECT || mInstructions[i]->mDst.mType != IT_INT8 || !mInstructions[i]->mSrc[0].mFinal)) { InterInstruction* ins(mInstructions[i]); int j = i; while (j < limit && CanBypassLoad(ins, mInstructions[j + 1])) { + if (!ins->mSrc[0].mFinal) + { + for (int k = 0; k < mInstructions[j + 1]->mNumOperands; k++) + { + if (mInstructions[j + 1]->mSrc[k].mTemp == ins->mSrc[0].mTemp && mInstructions[j + 1]->mSrc[k].mFinal) + { + mInstructions[j + 1]->mSrc[k].mFinal = false; + ins->mSrc[0].mFinal = true; + } + } + } + mInstructions[j] = mInstructions[j + 1]; j++; } @@ -8776,7 +8799,17 @@ void InterCodeBasicBlock::PeepholeOptimization(void) { if (i + 2 < mInstructions.Size()) { - if (mInstructions[i + 0]->mDst.mTemp >= 0 && + if (mInstructions[i + 0]->mCode == IC_LOAD && + mInstructions[i + 1]->mCode == IC_LOAD && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mSrc[0].mTemp && + mInstructions[i + 0]->mSrc[0].mIntConst > mInstructions[i + 1]->mSrc[0].mIntConst) + { + InterInstruction* ins(mInstructions[i + 0]); + mInstructions[i + 0] = mInstructions[i + 1]; + mInstructions[i + 1] = ins; + changed = true; + } + else if (mInstructions[i + 0]->mDst.mTemp >= 0 && mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && (mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal) { diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index e038f79..f7c5987 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -1,7 +1,7 @@ #include "Linker.h" #include #include - +#include "CompilerTypes.h" LinkerRegion::LinkerRegion(void) : mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } ) @@ -43,7 +43,7 @@ uint8* LinkerObject::AddSpace(int size) } Linker::Linker(Errors* errors) - : mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr) + : mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mCompilerOptions(COPT_DEFAULT) { for (int i = 0; i < 64; i++) { @@ -177,7 +177,7 @@ void Linker::ReferenceObject(LinkerObject* obj) } } -bool LinkerRegion::Allocate(LinkerObject* lobj) +bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj) { int i = 0; while (i < mFreeChunks.Size()) @@ -185,7 +185,9 @@ bool LinkerRegion::Allocate(LinkerObject* lobj) int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); int end = start + lobj->mSize; - if (end <= mFreeChunks[i].mEnd) + if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00)) + ; + else if (end <= mFreeChunks[i].mEnd) { lobj->mFlags |= LOBJF_PLACED; lobj->mAddress = start; @@ -217,6 +219,12 @@ bool LinkerRegion::Allocate(LinkerObject* lobj) int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); int end = start + lobj->mSize; + if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00)) + { + start = (start + 0x00ff) & 0xff00; + end = start + lobj->mSize; + } + if (end <= mEnd) { lobj->mFlags |= LOBJF_PLACED; @@ -294,7 +302,7 @@ void Linker::Link(void) for (int k = 0; k < lsec->mObjects.Size(); k++) { LinkerObject* lobj = lsec->mObjects[k]; - if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->Allocate(lobj) ) + if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->Allocate(this, lobj) ) { if (lsec->mType == LST_DATA) lrgn->mNonzero = lrgn->mUsed; diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 2c30e3c..abcc9f3 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -91,7 +91,7 @@ public: GrowingArray mFreeChunks; - bool Allocate(LinkerObject* obj); + bool Allocate(Linker * linker, LinkerObject* obj); void PlaceStackSection(LinkerSection* stackSection, LinkerSection* section); }; @@ -129,6 +129,7 @@ static const uint32 LOBJF_INLINE = 0x00000008; static const uint32 LOBJF_CONST = 0x00000010; static const uint32 LOBJF_RELEVANT = 0x00000020; static const uint32 LOBJF_STATIC_STACK = 0x00000040; +static const uint32 LOBJF_NO_CROSS = 0x00000080; class LinkerObject { @@ -187,6 +188,8 @@ public: bool WriteCrtFile(const char* filename); bool WriteBinFile(const char* filename); + uint64 mCompilerOptions; + GrowingArray mReferences; GrowingArray mRegions; GrowingArray mSections; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 3ba1d1b..d44e6fb 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -3029,6 +3029,9 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) rl.mRefObject = mLinkerObject; rl.mRefOffset = mAddress; + if (mLinkerObject) + mLinkerObject->mFlags |= LOBJF_NO_CROSS; + block->mRelocations.Push(rl); block->PutByte(0); } @@ -3058,6 +3061,9 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) rl.mOffset++; } + if (mode != ASMIM_ABSOLUTE) + mLinkerObject->mFlags |= LOBJF_NO_CROSS; + block->mRelocations.Push(rl); block->PutWord(0); } @@ -9656,6 +9662,15 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; changed = true; } + else if (yoffset == 1) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_DEY; mIns[i + 0].mMode = ASMIM_IMPLIED; + yoffset = 0; + changed = true; + } else if (yoffset == 2 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY) { for (int j = ypred; j < i; j++) @@ -9666,6 +9681,35 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; changed = true; } + else if (yoffset == 2 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEY; + changed = true; + } + else if (yoffset == 3 && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY && mIns[i + 2].mType == ASMIT_INY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_DEY; mIns[i + 2].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 3 && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_INY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_DEY; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; + yoffset = 2; + changed = true; + } else yoffset = 0; ypred = i; @@ -9744,7 +9788,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) } else if (mIns[i].mType == ASMIT_DEY) { - yoffset = (yoffset + 1) & 255; + yoffset = (yoffset - 1) & 255; } else if (mIns[i].ChangesYReg()) { @@ -9890,7 +9934,7 @@ bool NativeCodeBasicBlock::ForwardZpXIndex(bool full) } else if (mIns[i].mType == ASMIT_DEX) { - xoffset = (xoffset + 1) & 255; + xoffset = (xoffset - 1) & 255; } else if (mIns[i].ChangesXReg()) { @@ -10569,7 +10613,7 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::SplitMatchingTails(NativeCodeProced return nullptr; } -bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc) +bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops) { bool changed = false; @@ -10612,14 +10656,14 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc) NativeCodeBasicBlock* nblock = SplitMatchingTails(proc); if (nblock) { - if (nblock->JoinTailCodeSequences(proc)) + if (nblock->JoinTailCodeSequences(proc, loops)) changed = true; } } } #endif #if 1 - if (mIns.Size() >= 1 && mEntryBlocks.Size() == 2) + if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2) { NativeCodeBasicBlock* pblock = mEntryBlocks[0], * lblock = mEntryBlocks[1]; int ps = pblock->mIns.Size(), ls = lblock->mIns.Size(); @@ -10815,9 +10859,9 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc) } } #endif - if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc)) + if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc, loops)) changed = true; - if (mFalseJump && mFalseJump->JoinTailCodeSequences(proc)) + if (mFalseJump && mFalseJump->JoinTailCodeSequences(proc, loops)) changed = true; } @@ -10901,6 +10945,8 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* if (!mEntryRequiredRegs[reg]) return true; + assert(mNumEntries == mEntryBlocks.Size()); + if (mNumEntries > 1) { if (mLoopHead) @@ -11139,6 +11185,20 @@ bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) cons { if (this == block) return true; +#if 0 + if (mEntryBlocks.Size()) + { + if (mLoopHead) + return false; + + for (int i = 0; i < mEntryBlocks.Size(); i++) + if (!mEntryBlocks[i]->IsDominatedBy(block)) + return false; + return true; + } + + return false; +#else else { NativeCodeBasicBlock* dom = mDominator; @@ -11151,6 +11211,7 @@ bool NativeCodeBasicBlock::IsDominatedBy(const NativeCodeBasicBlock* block) cons return false; } +#endif } bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int at, int yval) @@ -11704,6 +11765,25 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to) } mIns.Remove(start); + return true; + } + else if (mIns[start].mType == ASMIT_LDA && mIns[start].mMode == ASMIM_ABSOLUTE_X && mIns[start + 1].ChangesAccu() && !mIns[start + 1].ChangesAddress() && !mIns[start + 1].RequiresYReg()) + { + + for (int i = from + 1; i < to; i++) + { + if (mIns[start].MayBeChangedOnAddress(mIns[i]) || mIns[start + 1].MayBeChangedOnAddress(mIns[i])) + return false; + } + + mIns.Remove(to); + for (int i = start; i < from; i++) + { + mIns.Insert(to, mIns[start]); + mIns.Remove(start); + } + mIns.Remove(start); + return true; } } @@ -14492,6 +14572,7 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo { block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED; } + block->mIns[i].mLive |= LIVE_CPU_REG_Y; } } } @@ -14559,6 +14640,7 @@ bool NativeCodeBasicBlock::OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCo { block->mIns[i].mType = ASMIT_NOP; block->mIns[i].mMode = ASMIM_IMPLIED; } + block->mIns[i].mLive |= LIVE_CPU_REG_X; } } } @@ -18917,146 +18999,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } #endif -#if 0 - if (i + 7 < mIns.Size()) - { - if ( - mIns[i + 0].mType == ASMIT_CLC && - mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && - mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && - mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && - mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && - mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && - - mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 && - mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM)) - { - for (int j = 0; j < 6; j++) - { - mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; - } - - if (mIns[i + 7].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 8].mLive |= LIVE_CPU_REG_Y; - } - - mIns[i + 6].mType = ASMIT_TAY; - mIns[i + 6].mMode = ASMIM_IMPLIED; - mIns[i + 7].mAddress = mIns[i + 1].mAddress; - progress = true; - } - } -#endif -#if 0 - if (i + 8 < mIns.Size()) - { - if ( - mIns[i + 0].mType == ASMIT_CLC && - mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && - mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && - mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && - mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && - mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && - !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 6].RequiresYReg() && - mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE && mIns[i + 7].mAddress == 0 && - mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 2].mAddress && !(mIns[i + 8].mLive & LIVE_MEM)) - { - for (int j = 0; j < 6; j++) - { - mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; - } - - if (mIns[i + 8].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 9, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 9].mLive |= LIVE_CPU_REG_Y; - } - - mIns[i + 0].mType = ASMIT_TAY; - mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 7].mType = ASMIT_NOP; mIns[i + 7].mMode = ASMIM_IMPLIED; - mIns[i + 8].mAddress = mIns[i + 1].mAddress; - progress = true; - } - } -#endif -#if 0 - if (i + 11 < mIns.Size()) - { - if ( - mIns[i + 0].mType == ASMIT_CLC && - mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && - mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && - mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && - mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && - mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && - !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 6].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 6].RequiresYReg() && - mIns[i + 7].mType == ASMIT_LDY && mIns[i + 7].mMode == ASMIM_IMMEDIATE && mIns[i + 7].mAddress == 0 && - mIns[i + 8].mMode == ASMIM_INDIRECT_Y && mIns[i + 8].mAddress == mIns[i + 2].mAddress && - !mIns[i + 9].ChangesZeroPage(mIns[i + 1].mAddress) && !mIns[i + 9].ChangesZeroPage(mIns[i + 1].mAddress + 1) && !mIns[i + 9].RequiresYReg() && - mIns[i + 10].mType == ASMIT_LDY && mIns[i + 10].mMode == ASMIM_IMMEDIATE && mIns[i + 10].mAddress == 1 && - mIns[i + 11].mMode == ASMIM_INDIRECT_Y && mIns[i + 11].mAddress == mIns[i + 2].mAddress && - !(mIns[i + 11].mLive & LIVE_MEM)) - { - for (int j = 0; j < 6; j++) - { - mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; - } - - if (mIns[i + 11].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 12, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 1)); - mIns[i + 12].mLive |= LIVE_CPU_REG_Y; - } - - mIns[i + 0].mType = ASMIT_TAY; - mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 7].mType = ASMIT_NOP; mIns[i + 7].mMode = ASMIM_IMPLIED; - mIns[i + 8].mAddress = mIns[i + 1].mAddress; - mIns[i + 10].mType = ASMIT_INY; mIns[i + 10].mMode = ASMIM_IMPLIED; - mIns[i + 11].mAddress = mIns[i + 1].mAddress; - progress = true; - } - } -#endif -#if 0 - if (i + 9 < mIns.Size()) - { - if ( - mIns[i + 0].mType == ASMIT_CLC && - mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && - mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && - mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && - mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && - mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && - - mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 && - mIns[i + 7].mType == ASMIT_LDA && mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && - !mIns[i + 8].ChangesYReg() && (mIns[i + 8].mMode == ASMIM_IMMEDIATE || mIns[i + 8].mMode == ASMIM_ZERO_PAGE && mIns[i + 8].mAddress != mIns[i + 2].mAddress && mIns[i + 8].mAddress != mIns[i + 1].mAddress) && - mIns[i + 9].mType == ASMIT_STA && mIns[i + 9].mMode == ASMIM_INDIRECT_Y && mIns[i + 9].mAddress == mIns[i + 2].mAddress && !(mIns[i + 9].mLive & LIVE_MEM) - ) - { - for(int j=0; j<6; j++) - { - mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; - } - - if (mIns[i + 9].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 10, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 10].mLive |= LIVE_CPU_REG_Y; - } - - mIns[i + 6].mType = ASMIT_TAY; - mIns[i + 6].mMode = ASMIM_IMPLIED; - mIns[i + 7].mAddress = mIns[i + 1].mAddress; - mIns[i + 9].mAddress = mIns[i + 1].mAddress; - progress = true; - } - } -#endif #endif #if 1 @@ -20179,8 +20121,16 @@ void NativeCodeProcedure::Optimize(void) mBlocks[i]->mFromJump = nullptr; mBlocks[i]->mDominator = nullptr; } + ResetEntryBlocks(); + mEntryBlock->CountEntries(nullptr); + + ResetVisited(); + mEntryBlock->CollectEntryBlocks(nullptr); + + mEntryBlock->BuildDominatorTree(nullptr); + #if 1 do { @@ -20246,7 +20196,7 @@ void NativeCodeProcedure::Optimize(void) if (step > 2) { ResetVisited(); - if (mEntryBlock->JoinTailCodeSequences(this)) + if (mEntryBlock->JoinTailCodeSequences(this, step > 3)) changed = true; } #endif diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index b7a15db..24a1361 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -283,7 +283,7 @@ public: NativeCodeBasicBlock * SplitMatchingTails(NativeCodeProcedure* proc); - bool JoinTailCodeSequences(NativeCodeProcedure* proc); + bool JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops); bool SameTail(const NativeCodeInstruction& ins) const; NativeRegisterDataSet mEntryRegisterDataSet;