diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1c8e28c..55b2367 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -71,6 +71,18 @@ void IntegerValueRange::LimitMax(int64 value) } } +void IntegerValueRange::LimitMinBound(int64 value) +{ + if (mMinState == S_BOUND && mMinValue < value) + mMinValue = value; +} + +void IntegerValueRange::LimitMaxBound(int64 value) +{ + if (mMaxState == S_BOUND && mMaxValue > value) + mMaxValue = value; +} + void IntegerValueRange::LimitMinWeak(int64 value) { if (mMinState == S_UNBOUND || mMinValue < value) @@ -5270,7 +5282,18 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray { case IC_LOAD: vr = ins->mDst.mRange; - +#if 1 + if (ins->mDst.mType == IT_INT8) + { + vr.LimitMin(-128); + vr.LimitMax(255); + } + else if (ins->mDst.mType == IT_INT16) + { + vr.LimitMin(-32768); + vr.LimitMax(65535); + } +#endif if (i > 0 && mInstructions[i - 1]->mCode == IC_LEA && mInstructions[i - 1]->mDst.mTemp == ins->mSrc[0].mTemp && mInstructions[i - 1]->mSrc[1].mTemp < 0 && mInstructions[i - 1]->mSrc[1].mMemory == IM_GLOBAL && (mInstructions[i - 1]->mSrc[1].mLinkerObject->mFlags & LOBJF_CONST)) @@ -5736,7 +5759,18 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray default: vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND; } - +#if 1 + if (ins->mDst.mType == IT_INT8) + { + vr.LimitMinBound(-128); + vr.LimitMaxBound(255); + } + else if (ins->mDst.mType == IT_INT16) + { + vr.LimitMinBound(-32768); + vr.LimitMaxBound(65535); + } +#endif ins->mDst.mRange = vr; #if 1 if (vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMinState == IntegerValueRange::S_BOUND && vr.mMaxValue == vr.mMinValue) @@ -12811,6 +12845,11 @@ void InterCodeProcedure::Close(void) DisassembleDebug("Estimated value range 2"); #endif + ResetVisited(); + mEntryBlock->SimplifyIntegerRangeRelops(); + + DisassembleDebug("Simplified range limited relational ops"); + #if 1 if (mModule->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL) { diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 7d663f0..3ad783e 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -159,6 +159,9 @@ public: void LimitMin(int64 value); void LimitMax(int64 value); + void LimitMinBound(int64 value); + void LimitMaxBound(int64 value); + void LimitMinWeak(int64 value); void LimitMaxWeak(int64 value); }; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 390eda8..9e3329a 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1159,6 +1159,12 @@ bool NativeCodeInstruction::IsShift(void) const return mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR; } +bool NativeCodeInstruction::IsShiftOrInc(void) const +{ + return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR;// || mType == ASMIT_ROL || mType == ASMIT_ROR; +} + + bool NativeCodeInstruction::IsCommutative(void) const { return mType == ASMIT_ADC || mType == ASMIT_AND || mType == ASMIT_ORA || mType == ASMIT_EOR; @@ -14269,6 +14275,46 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) CheckLive(); +#if 1 + if (mTrueJump && mFalseJump && mTrueJump->mEntryProvidedRegs.Size() && mFalseJump->mEntryRequiredRegs.Size()) + { + mTempRegs.Reset(mTrueJump->mEntryRequiredRegs.Size()); + + for (int i = mIns.Size() - 1; i >= 0; i--) + { + NativeCodeInstruction ins(mIns[i]); + + if (ins.mMode == ASMIM_ZERO_PAGE) + { + int addr = ins.mAddress; + + if (!mTempRegs[addr]) + { + if (ins.IsShiftOrInc() && !(ins.ChangesCarry() && (ins.mLive & LIVE_CPU_REG_C)) && !(ins.mLive & LIVE_CPU_REG_Z)) + { + if (mTrueJump->mEntryRequiredRegs[addr] && !mFalseJump->mEntryRequiredRegs[addr] && mTrueJump->mNumEntries == 1 && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] && !mTrueJump->mEntryRequiredRegs[CPU_REG_C] || + mFalseJump->mEntryRequiredRegs[addr] && !mTrueJump->mEntryRequiredRegs[addr] && mFalseJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C]) + { + if (mTrueJump->mEntryRequiredRegs[addr]) + mTrueJump->mIns.Insert(0, mIns[i]); + else + mFalseJump->mIns.Insert(0, mIns[i]); + mIns.Remove(i); + } + } + else + mTempRegs += addr; + } + } + else if (ins.mMode == ASMIM_INDIRECT_Y) + { + mTempRegs += ins.mAddress; + mTempRegs += ins.mAddress + 1; + } + } + } +#endif + #if 1 if (mTrueJump && mFalseJump && mTrueJump->mEntryProvidedRegs.Size() && mFalseJump->mEntryRequiredRegs.Size()) { diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 814b576..3d7dffc 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -138,6 +138,7 @@ public: bool IsSame(const NativeCodeInstruction& ins) const; bool IsCommutative(void) const; bool IsShift(void) const; + bool IsShiftOrInc(void) const; bool IsSimpleJSR(void) const; bool MayBeMovedBefore(const NativeCodeInstruction& ins); @@ -262,6 +263,7 @@ public: NumberSet mLocalRequiredRegs, mLocalProvidedRegs; NumberSet mEntryRequiredRegs, mEntryProvidedRegs; NumberSet mExitRequiredRegs, mExitProvidedRegs; + NumberSet mTempRegs; void BuildLocalRegSets(void); void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);