diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index b7ee445..b47295a 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -4,7 +4,7 @@ LinkerRegion::LinkerRegion(void) - : mSections(nullptr) + : mSections(nullptr), mFreeChunks(FreeChunk{ 0, 0 } ) {} LinkerSection::LinkerSection(void) @@ -176,6 +176,62 @@ void Linker::ReferenceObject(LinkerObject* obj) } } +bool LinkerRegion::Allocate(LinkerObject* lobj) +{ + int i = 0; + while (i < mFreeChunks.Size()) + { + int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); + int end = start + lobj->mSize; + + if (end <= mFreeChunks[i].mEnd) + { + lobj->mFlags |= LOBJF_PLACED; + lobj->mAddress = start; + lobj->mRegion = this; + + if (start == mFreeChunks[i].mStart) + { + if (end == mFreeChunks[i].mEnd) + mFreeChunks.Remove(i); + else + mFreeChunks[i].mStart = end; + } + else if (end == mFreeChunks[i].mEnd) + { + mFreeChunks[i].mEnd = start; + } + else + { + mFreeChunks.Insert(i + 1, FreeChunk{ end, mFreeChunks[i].mEnd } ); + mFreeChunks[i].mEnd = start; + } + + return true; + } + i++; + } + + int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); + int end = start + lobj->mSize; + + if (end <= mEnd) + { + lobj->mFlags |= LOBJF_PLACED; + lobj->mAddress = start; + lobj->mRegion = this; +#if 1 + if (start != mStart + mUsed) + mFreeChunks.Push( FreeChunk{ mStart + mUsed, start } ); +#endif + mUsed = end - mStart; + + return true; + } + + return false; +} + void Linker::Link(void) { if (mErrors->mErrorCount == 0) @@ -199,21 +255,18 @@ 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->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd) + if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->Allocate(lobj) ) { - lobj->mFlags |= LOBJF_PLACED; - lobj->mAddress = (lrgn->mStart + lrgn->mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); - lrgn->mUsed = lobj->mAddress + lobj->mSize - lrgn->mStart; - - lobj->mRegion = lrgn; - if (lsec->mType == LST_DATA) lrgn->mNonzero = lrgn->mUsed; - if (lobj->mAddress < lsec->mStart) - lsec->mStart = lobj->mAddress; - if (lobj->mAddress + lobj->mSize > lsec->mEnd) - lsec->mEnd = lobj->mAddress + lobj->mSize; + if (lobj->mAddress + lobj->mSize == lrgn->mStart + lrgn->mUsed) + { + if (lobj->mAddress < lsec->mStart) + lsec->mStart = lobj->mAddress; + if (lobj->mAddress + lobj->mSize > lsec->mEnd) + lsec->mEnd = lobj->mAddress + lobj->mSize; + } } } } diff --git a/oscar64/Linker.h b/oscar64/Linker.h index a829a23..7eb38eb 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -48,6 +48,15 @@ public: GrowingArray mSections; LinkerRegion(void); + + struct FreeChunk + { + int mStart, mEnd; + }; + + GrowingArray mFreeChunks; + + bool Allocate(LinkerObject* obj); }; static const uint32 LREF_LOWBYTE = 0x00000001; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index ae178b8..a717f7c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -9353,6 +9353,7 @@ bool NativeCodeBasicBlock::PatchAddressSumY(int at, int reg, int apos, int breg, } else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg) { + mIns[i].mFlags &= ~NCIF_YZERO; mIns[i].mAddress = breg; } } @@ -13026,17 +13027,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 2].mAddress = mIns[i + 0].mAddress; progress = true; } +#if 1 else if ( mIns[i + 0].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress == 1 || mIns[i + 2].mAddress == 2) && - mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 3].mAddress && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mType == ASMIT_TAY && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) { mIns[i + 0].mType = ASMIT_NOP; mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mFlags |= LIVE_CPU_REG_Y; mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mFlags |= LIVE_CPU_REG_Y; - mIns[i + 3].mType == ASMIT_STY; mIns[i + 3].mFlags |= LIVE_CPU_REG_Y; + mIns[i + 3].mType = ASMIT_STY; mIns[i + 3].mFlags |= LIVE_CPU_REG_Y; mIns[i + 4].mType = ASMIT_NOP; if (mIns[i + 2].mAddress == 2) { @@ -13045,6 +13047,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) progress = true; } +#endif #if 1 else if ( mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && @@ -14167,6 +14170,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } #endif +#if 1 if (step == 3) { ResetVisited(); @@ -14176,6 +14180,7 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->ReduceLocalYPressure()) changed = true; } +#endif #if 1 else if (step == 4) {