diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 59a1115..74233f8 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -6820,18 +6820,26 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray case IA_EXT8TO16U: case IA_EXT8TO32U: vr = ins->mSrc[0].mRange; - if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < 0 || vr.mMaxValue > 255 || vr.mMinValue < 0 || - vr.mMinState != IntegerValueRange::S_BOUND) + if (vr.mMaxState != IntegerValueRange::S_UNKNOWN && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinValue > 0) { vr.mMaxState = IntegerValueRange::S_BOUND; vr.mMaxValue = 255; - vr.mMinState = IntegerValueRange::S_BOUND; - vr.mMinValue = 0; } - if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < 0 || vr.mMinValue > 255) + else { - vr.mMinState = IntegerValueRange::S_BOUND; - vr.mMinValue = 0; + if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < 0 || vr.mMaxValue > 255 || vr.mMinValue < 0 || + vr.mMinState != IntegerValueRange::S_BOUND) + { + vr.mMaxState = IntegerValueRange::S_BOUND; + vr.mMaxValue = 255; + vr.mMinState = IntegerValueRange::S_BOUND; + vr.mMinValue = 0; + } + if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < 0 || vr.mMinValue > 255) + { + vr.mMinState = IntegerValueRange::S_BOUND; + vr.mMinValue = 0; + } } break; case IA_EXT16TO32U: @@ -7700,7 +7708,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray if (s0 < 0) { mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); - mTrueValueRange[s1].LimitMin(0); + mTrueValueRange[s1].LimitMinWeak(0); if (mFalseValueRange[s1].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[s1].mMinValue >= 0) { @@ -7710,7 +7718,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND) { mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1); - mTrueValueRange[s1].LimitMin(0); + mTrueValueRange[s1].LimitMinWeak(0); if (mFalseValueRange[s1].mMinState == IntegerValueRange::S_BOUND && mFalseValueRange[s1].mMinValue >= 0) { @@ -17276,7 +17284,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "test"); mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index de61ba9..59faa84 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -12791,6 +12791,16 @@ bool NativeCodeBasicBlock::MergeSameBlocks(NativeCodeProcedure* nproc) { mVisited = true; + if (this == mProc->mEntryBlock && mSameBlock && mIns.Size() > 1) + { + mTrueJump = mSameBlock; + mFalseJump = nullptr; + mBranch = ASMIT_JMP; + mIns.SetSize(0); + changed = true; + mSameBlock = nullptr; + } + if (mTrueJump && mTrueJump->mSameBlock) { mTrueJump = mTrueJump->mSameBlock; @@ -15796,9 +15806,9 @@ bool NativeCodeBasicBlock::CanHoistStore(const NativeCodeInstruction& ains) cons return true; } -bool NativeCodeBasicBlock::CanBytepassLoad(const NativeCodeInstruction& ains) const +bool NativeCodeBasicBlock::CanBytepassLoad(const NativeCodeInstruction& ains, int from) const { - for (int i = 0; i < mIns.Size(); i++) + for (int i = from; i < mIns.Size(); i++) { if (ains.MayBeChangedOnAddress(mIns[i])) return false; @@ -15849,7 +15859,7 @@ bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc) sz--; if (sz >= 0 && mIns[sz].mType == ASMIT_LDY && (mIns[sz].mMode == ASMIM_ZERO_PAGE || mIns[sz].mMode == ASMIM_ABSOLUTE) && !(mIns[sz].mLive & LIVE_CPU_REG_Z)) { - if (mTrueJump->CanBytepassLoad(mIns[sz]) && mFalseJump->CanBytepassLoad(mIns[sz])) + if (this->CanBytepassLoad(mIns[sz], sz + 1) && mTrueJump->CanBytepassLoad(mIns[sz]) && mFalseJump->CanBytepassLoad(mIns[sz])) { mTrueJump->mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[sz].mIns, ASMIT_LDY, mIns[sz])); changed = true; @@ -15864,7 +15874,7 @@ bool NativeCodeBasicBlock::SimplifyDiamond(NativeCodeProcedure* proc) sz--; if (sz >= 0 && mIns[sz].mType == ASMIT_LDX && (mIns[sz].mMode == ASMIM_ZERO_PAGE || mIns[sz].mMode == ASMIM_ABSOLUTE) && !(mIns[sz].mLive & LIVE_CPU_REG_Z)) { - if (mTrueJump->CanBytepassLoad(mIns[sz]) && mFalseJump->CanBytepassLoad(mIns[sz])) + if (this->CanBytepassLoad(mIns[sz], sz + 1) && mTrueJump->CanBytepassLoad(mIns[sz]) && mFalseJump->CanBytepassLoad(mIns[sz])) { mTrueJump->mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[sz].mIns, ASMIT_LDX, mIns[sz])); changed = true; @@ -17535,6 +17545,34 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc) } + if (mIns.Size() >= 2 && mFalseJump && mBranch == ASMIT_BMI) + { + int sz = mIns.Size(); + if (mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && + mIns[sz - 1].mType == ASMIT_SBC && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0) + { + if (mExitRequiredRegs[CPU_REG_Z]) + { + if (mFalseJump->mIns.Size() == 0 && mFalseJump->mBranch == ASMIT_BNE) + { + mFalseJump = mFalseJump->mFalseJump; + changed = true; + } + else if (mFalseJump->mIns.Size() == 0 && mFalseJump->mBranch == ASMIT_BEQ) + { + mFalseJump = mFalseJump->mTrueJump; + changed = true; + } + } + else if (!mExitRequiredRegs[CPU_REG_A]) + { + mBranch = ASMIT_BCC; + mIns.SetSize(sz - 2); + changed = true; + } + } + } + #if 1 if (mIns.Size() >= 1 && mFalseJump) { @@ -38685,6 +38723,33 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED; progress = true; } +#if 1 + else if ( + mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) && + (mIns[i + 1].mType == ASMIT_TAY || mIns[i + 1].mType == ASMIT_TAX) && + mIns[i + 2].mType == ASMIT_CLC && + mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && (mIns[i + 3].mAddress == 0xff || mIns[i + 3].mAddress == 0x01) && + mIns[i + 4].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 4]) && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + if (mIns[i + 1].mType == ASMIT_TAY) + { + mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y; + } + else + { + mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X; + } + + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + if (mIns[i + 3].mAddress == 0x01) + mIns[i + 4].mType = ASMIT_INC; + else + mIns[i + 4].mType = ASMIT_DEC; + progress = true; + } +#endif #endif } #endif diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index eb72c46..61a3687 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -575,7 +575,7 @@ public: bool SimplifyLoopEnd(NativeCodeProcedure* proc); bool CrossBlockStoreLoadBypass(NativeCodeProcedure* proc); - bool CanBytepassLoad(const NativeCodeInstruction& ains) const; + bool CanBytepassLoad(const NativeCodeInstruction& ains, int from = 0) const; bool CanHoistStore(const NativeCodeInstruction& ains) const; bool MoveAccuTrainUp(int at, int end);