diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 9f7e896..387ee77 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -6733,6 +6733,40 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void) } } +#if 1 + if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp && + mInstructions[sz - 2]->mSrc[0].mTemp >= 0 && mInstructions[sz - 2]->mSrc[1].mTemp >= 0) + { + if (mFalseJump->mNumEntries == 1 && mFalseJump->mInstructions.Size() == 2 && mFalseJump->mInstructions[1]->mCode == IC_BRANCH && + mFalseJump->mInstructions[0]->mCode == IC_RELATIONAL_OPERATOR && mFalseJump->mInstructions[0]->mDst.mTemp == mFalseJump->mInstructions[1]->mSrc[0].mTemp) + { + if (mInstructions[sz - 2]->mOperator == IA_CMPLS && mFalseJump->mInstructions[0]->mOperator == IA_CMPGS && + mInstructions[sz - 2]->mSrc[0].mTemp == mFalseJump->mInstructions[0]->mSrc[0].mTemp && + mInstructions[sz - 2]->mSrc[1].mTemp == mFalseJump->mInstructions[0]->mSrc[1].mTemp) + { + mFalseJump->mInstructions[0]->mOperator = IA_CMPNE; + } + else if (mInstructions[sz - 2]->mOperator == IA_CMPGS && mFalseJump->mInstructions[0]->mOperator == IA_CMPLS && + mInstructions[sz - 2]->mSrc[0].mTemp == mFalseJump->mInstructions[0]->mSrc[0].mTemp && + mInstructions[sz - 2]->mSrc[1].mTemp == mFalseJump->mInstructions[0]->mSrc[1].mTemp) + { + mFalseJump->mInstructions[0]->mOperator = IA_CMPNE; + } + else if (mInstructions[sz - 2]->mOperator == IA_CMPLS && mFalseJump->mInstructions[0]->mOperator == IA_CMPLS && + mInstructions[sz - 2]->mSrc[0].mTemp == mFalseJump->mInstructions[0]->mSrc[1].mTemp && + mInstructions[sz - 2]->mSrc[1].mTemp == mFalseJump->mInstructions[0]->mSrc[0].mTemp) + { + mFalseJump->mInstructions[0]->mOperator = IA_CMPNE; + } + else if (mInstructions[sz - 2]->mOperator == IA_CMPGS && mFalseJump->mInstructions[0]->mOperator == IA_CMPGS && + mInstructions[sz - 2]->mSrc[0].mTemp == mFalseJump->mInstructions[0]->mSrc[1].mTemp && + mInstructions[sz - 2]->mSrc[1].mTemp == mFalseJump->mInstructions[0]->mSrc[0].mTemp) + { + mFalseJump->mInstructions[0]->mOperator = IA_CMPNE; + } + } + } +#endif #if 1 for (int i = 0; i < sz; i++) @@ -8287,13 +8321,13 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVar mFalseValueRange.SetSize(num, false); mLocalValueRange.SetSize(num, false); mMemoryValueSize.SetSize(num, false); - mEntryMemoryValueSize.SetSize(num, true); - + mEntryMemoryValueSize.SetSize(num, false); +#if 0 if (mTrueJump && !mTrueJump->mVisited) mTrueJump->mMemoryValueSize.SetSize(num, true); if (mFalseJump && !mFalseJump->mVisited) mFalseJump->mMemoryValueSize.SetSize(num, true); - +#endif mEntryParamValueRange.SetSize(paramVars.Size(), false); mTrueParamValueRange.SetSize(paramVars.Size(), false); mFalseParamValueRange.SetSize(paramVars.Size(), false); @@ -18193,12 +18227,14 @@ void InterCodeBasicBlock::RemapActiveTemporaries(const FastNumberSet& set) GrowingIntegerValueRangeArray falseValueRange(mFalseValueRange); GrowingIntegerValueRangeArray localValueRange(mLocalValueRange); GrowingIntegerValueRangeArray reverseValueRange(mReverseValueRange); + GrowingArray memoryValueSize(mMemoryValueSize); mEntryValueRange.SetSize(set.Num(), true); mTrueValueRange.SetSize(set.Num(), true); mFalseValueRange.SetSize(set.Num(), true); mLocalValueRange.SetSize(set.Num(), true); mReverseValueRange.SetSize(set.Num(), true); + mMemoryValueSize.SetSize(set.Num(), true); for (int i = 0; i < set.Num(); i++) { @@ -18208,6 +18244,7 @@ void InterCodeBasicBlock::RemapActiveTemporaries(const FastNumberSet& set) mFalseValueRange[i] = falseValueRange[j]; mLocalValueRange[i] = localValueRange[j]; mReverseValueRange[i] = reverseValueRange[j]; + mMemoryValueSize[i] = memoryValueSize[j]; } if (mTrueJump) mTrueJump->RemapActiveTemporaries(set); diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 47786b2..a6618c7 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -366,7 +366,7 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L return obj; } -static bool Forwards(LinkerObject* pobj, LinkerObject* lobj) +bool Linker::Forwards(LinkerObject* pobj, LinkerObject* lobj) { if (lobj->mAlignment == 1 && pobj && lobj->mType == LOT_NATIVE_CODE && pobj->mType == LOT_NATIVE_CODE && lobj->mSection == pobj->mSection) { @@ -377,7 +377,8 @@ static bool Forwards(LinkerObject* pobj, LinkerObject* lobj) i++; if (i < pobj->mReferences.Size() && pobj->mReferences[i]->mRefObject == lobj && pobj->mReferences[i]->mRefOffset == 0) { - printf("Direct %s -> %s\n", pobj->mIdent->mString, lobj->mIdent->mString); + if (mCompilerOptions & COPT_VERBOSE2) + printf("Direct %s -> %s\n", pobj->mIdent->mString, lobj->mIdent->mString); pobj->mSuffixReference = i; @@ -442,7 +443,8 @@ void Linker::CombineSameConst(void) { sobj->mMapID = dobj->mMapID; changed = true; - if (dobj->mIdent && sobj->mIdent) + + if (dobj->mIdent && sobj->mIdent && (mCompilerOptions & COPT_VERBOSE2)) { printf("Match %s : %s\n", dobj->mIdent->mString, sobj->mIdent->mString); } diff --git a/oscar64/Linker.h b/oscar64/Linker.h index c55611b..3f8dc29 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -309,6 +309,7 @@ protected: NativeCodeDisassembler mNativeDisassembler; ByteCodeDisassembler mByteCodeDisassembler; + bool Forwards(LinkerObject* pobj, LinkerObject* lobj); void SortObjectsPartition(int l, int r); Errors* mErrors; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 85162fb..8e4b0c6 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -32727,6 +32727,39 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc } } + if (si + 2 < mIns.Size() && mIns[si].mType == ASMIT_LDX && mIns[si + 2].mType == ASMIT_STX && mIns[si].mMode == ASMIM_ZERO_PAGE && mIns[si + 2].mMode == ASMIM_ZERO_PAGE && mIns[si].mAddress == mIns[si + 2].mAddress && mIns[si + 1].mType == ASMIT_INX) + { + int i = 0; + while (i < si && !mIns[i].ChangesZeroPage(mIns[si].mAddress)) + i++; + + if (i == si) + { + i = si + 3; + while (i < mIns.Size() && !mIns[i].ChangesZeroPage(mIns[si].mAddress) && !mIns[i].ChangesXReg()) + i++; + + if (i == mIns.Size()) + { + if (!prevBlock) + return OptimizeSimpleLoopInvariant(proc, full); + + for(int i=0; imIns.Push(mIns[si]); + mIns.Remove(si); + + mEntryRequiredRegs += CPU_REG_X; + mExitRequiredRegs += CPU_REG_X; + + CheckLive(); + + return true; + } + } + } + if (si < ei && mIns[si].mType == ASMIT_LDX && mIns[si].mMode == ASMIM_ZERO_PAGE) { // Loads X once from zero page and never changes it again @@ -44148,6 +44181,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } } + else if (sz >= 4 && + mIns[sz - 4].mType == ASMIT_TXA && + mIns[sz - 3].mType == ASMIT_CLC && + mIns[sz - 2].mType == ASMIT_ADC && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0xff && + mIns[sz - 1].mType == ASMIT_TAX && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[CPU_REG_C]) + { + if (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) + { + mIns[sz - 4].mType = ASMIT_DEX; mIns[sz - 4].mLive |= LIVE_CPU_REG_X; + mIns[sz - 3].mType = ASMIT_NOP; mIns[sz - 3].mMode = ASMIM_IMPLIED; + mIns[sz - 2].mType = ASMIT_CPX; mIns[sz - 2].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_Z; + mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED; + + if (mBranch == ASMIT_BCC) + mBranch = ASMIT_BEQ; + else + mBranch = ASMIT_BNE; + + CheckLive(); + } + } + else if (sz >= 3 && mIns[sz - 3].mType == ASMIT_LDA && mIns[sz - 3].mMode == ASMIM_IMMEDIATE && mIns[sz - 3].mAddress == 0x00 && mIns[sz - 2].mType == ASMIT_ROL && mIns[sz - 2].mMode == ASMIM_IMPLIED &&