diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 1588b1a..750805b 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -497,12 +497,19 @@ Expression* Expression::ToAlternateThis(Declaration* pthis, Declaration* nthis) Expression* right = mRight ? mRight->ToAlternateThis(pthis, nthis) : nullptr; Declaration* decType = mDecType, * decValue = mDecValue; - if (decType == pthis->mBase) - decType = nthis->mBase; - else if (decType == pthis->mBase->mBase) - decType = nthis->mBase->mBase; - if (decValue == pthis) - decValue = nthis; + Declaration* lp = pthis, * np = nthis; + while (lp) + { + if (decType == lp->mBase) + decType = np->mBase; + else if (decType == lp->mBase->mBase) + decType = np->mBase->mBase; + if (decValue == lp) + decValue = np; + + lp = lp->mNext; + np = np->mNext; + } if (mType == EX_QUALIFY && mLeft->mDecType != left->mDecType) { @@ -745,14 +752,29 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio ex->mDecType = mDecType; return ex; } - else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX && mLeft->mLeft->mType == EX_VARIABLE && (mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT) + else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX && + mLeft->mLeft->mType == EX_VARIABLE && mLeft->mLeft->mDecType->mType == DT_TYPE_ARRAY && + (mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT) { + Declaration* vdec = mLeft->mLeft->mDecValue; + Expression* ex = new Expression(mLocation, EX_VARIABLE); Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF); - dec->mFlags = mLeft->mLeft->mDecValue->mFlags; - dec->mBase = mLeft->mLeft->mDecValue; - dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; - dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; + + if (vdec->mType == DT_VARIABLE_REF) + { + dec->mFlags = vdec->mFlags; + dec->mBase = vdec->mBase; + dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; + dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize + vdec->mOffset; + } + else + { + dec->mFlags = vdec->mFlags; + dec->mBase = vdec; + dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; + dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; + } ex->mDecValue = dec; ex->mDecType = mLeft->mLeft->mDecType; return ex; @@ -2353,16 +2375,17 @@ Declaration* Declaration::ToAlternateThis(Declaration* pthis, int nthis) else { Declaration* nparam = ndec->mParams->Clone(); + Declaration* npp = nparam; + Declaration* kpp = ndec->mParams->mNext; + while (kpp) + { + npp->mNext = kpp->Clone(); + npp = npp->mNext; + kpp = npp->mNext; + } nparam->mBase = pthis; if (nthis == 2) - { - Declaration* nparam2 = ndec->mParams->mNext->Clone(); - nparam2->mBase = pthis; - nparam->mNext = nparam2; - nparam2->mNext = ndec->mParams->mNext->mNext; - } - else - nparam->mNext = ndec->mParams->mNext; + nparam->mNext->mBase = pthis; ndec->mParams = nparam; } return ndec; diff --git a/oscar64/GlobalOptimizer.cpp b/oscar64/GlobalOptimizer.cpp index 1f463a9..3d57a42 100644 --- a/oscar64/GlobalOptimizer.cpp +++ b/oscar64/GlobalOptimizer.cpp @@ -954,7 +954,9 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin break; case EX_BREAK: case EX_CONTINUE: + break; case EX_ASSUME: + return Analyze(exp->mLeft, procDec, ANAFL_RHS); break; case EX_TYPE: break; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a23317e..19be010 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -19557,6 +19557,73 @@ bool InterCodeBasicBlock::ShortLeaMerge(int& spareTemps) return changed; } +bool InterCodeBasicBlock::ShortLeaCleanup(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + if (!mLoopHead && mEntryBlocks.Size() > 1) + { + int k = 0; + while (k < mEntryBlocks.Size() && !mEntryBlocks[k]->mFalseJump) + k++; + + if (k == mEntryBlocks.Size()) + { + GrowingInstructionArray iins(nullptr); + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins = mInstructions[i]; + + int ttemp = -1; + if (ins->mCode == IC_STORE && ins->mSrc[1].mTemp >= 0) + ttemp = ins->mSrc[1].mTemp; + else if (ins->mCode == IC_LOAD && ins->mSrc[0].mTemp >= 0) + ttemp = ins->mSrc[0].mTemp; + + if (ttemp >= 0 && !IsTempModifiedInRange(0, i, ttemp)) + { + bool found = true; + bool shortlea = false, noshortlea = false; + + iins.SetSize(0); + for (int k = 0; k < mEntryBlocks.Size(); k++) + { + InterInstruction* sins = mEntryBlocks[k]->FindTempOrigin(ttemp); + if (ins->mCode == IC_STORE && sins && sins->mCode == IC_LEA && sins->mSrc[1].mTemp < 0 && sins->mSrc[0].IsUByte() && CanMoveInstructionBeforeBlock(i) && !mEntryBlocks[k]->mFalseJump) + shortlea = true; + else + noshortlea = true; + } + + if (shortlea && !noshortlea) + { + for (int k = 0; k < mEntryBlocks.Size(); k++) + { + mEntryBlocks[k]->AppendBeforeBranch(ins->Clone()); + if (ins->mDst.mTemp >= 0) + mEntryBlocks[k]->mExitRequiredTemps += ins->mDst.mTemp; + } + if (ins->mDst.mTemp >= 0) + mEntryRequiredTemps += ins->mDst.mTemp; + ins->mCode = IC_NONE; ins->mNumOperands = 0; + changed = true; + } + } + } + } + } + + if (mTrueJump && mTrueJump->ShortLeaCleanup()) changed = true; + if (mFalseJump && mFalseJump->ShortLeaCleanup()) changed = true; + } + + return changed; +} void InterCodeBasicBlock::CompactInstructions(void) { @@ -23366,7 +23433,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "test_char_fit"); + CheckFunc = !strcmp(mIdent->mString, "moveBy"); CheckCase = false; mEntryBlock = mBlocks[0]; @@ -24741,6 +24808,11 @@ bool InterCodeProcedure::ShortLeaMerge(FastNumberSet& activeSet) DisassembleDebug("ShortLeaMerge"); + ResetVisited(); + mEntryBlock->ShortLeaCleanup(); + + DisassembleDebug("ShortLeaCleanup"); + return n > 1; } diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index c2ff359..c424cad 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -664,6 +664,7 @@ public: void FollowJumps(void); bool ShortLeaMerge(int& spareTemps); + bool ShortLeaCleanup(void); bool IsEqual(const InterCodeBasicBlock* block) const; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 048b20d..52cf556 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -46194,6 +46194,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate3(int i, int pass) return true; } else if ( + pass >= 6 && mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_IMPLIED && mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1) @@ -52971,7 +52972,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mIdent->mString, "station_slider"); + CheckFunc = !strcmp(mIdent->mString, "moveBy"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks];