From e1736c8214e5b4e35f2f437da95a1a011fcc3048 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:02:25 +0100 Subject: [PATCH] Reverse shift with negated distance --- oscar64/InterCode.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 34ec8d7..ee20015 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -6358,6 +6358,20 @@ static bool ispow2(int64 v) return 0; } +static int binlog(int64 n) +{ + int k = -1; + + while (n) + { + n >>= 1; + k++; + } + + return k; +} + + void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle) { switch (ins->mCode) @@ -20552,6 +20566,61 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray } } } +#endif +#if 1 + if (i + 1 < mInstructions.Size()) + { + if (mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SUB && + mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_SHL && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && mInstructions[i + 1]->mSrc[0].IsUByte() && + mInstructions[i + 1]->mSrc[1].mTemp < 0 && ispow2(mInstructions[i + 1]->mSrc[1].mIntConst)) + { + int64 k = binlog(mInstructions[i + 1]->mSrc[1].mIntConst); + + if (mInstructions[i + 0]->mSrc[0].mTemp >= 0 && mInstructions[i + 0]->mSrc[1].mTemp < 0) + { + int64 s = mInstructions[i + 0]->mSrc[1].mIntConst; + mInstructions[i + 0]->mSrc[1] = mInstructions[i + 0]->mSrc[0]; + mInstructions[i + 0]->mSrc[0].mTemp = -1; + mInstructions[i + 0]->mSrc[0].mIntConst = mInstructions[i + 0]->mSrc[1].mRange.mMinValue; + mInstructions[i + 0]->mDst.mRange.SetLimit(0, mInstructions[i + 0]->mSrc[1].mRange.mMaxValue - mInstructions[i + 0]->mSrc[0].mIntConst); + mInstructions[i + 1]->mOperator = IA_SHR; + mInstructions[i + 1]->mSrc[0] = mInstructions[i + 0]->mDst; + int64 d = s - mInstructions[i + 0]->mSrc[0].mIntConst; + if (d < 0) + mInstructions[i + 1]->mSrc[1].mIntConst >>= -d; + else + mInstructions[i + 1]->mSrc[1].mIntConst <<= d; + changed = true; + } + } + if (mInstructions[i + 0]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 0]->mOperator == IA_SUB && + mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && mInstructions[i + 1]->mOperator == IA_SHR && + mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i + 0]->mDst.mTemp && mInstructions[i + 1]->mSrc[0].mFinal && mInstructions[i + 1]->mSrc[0].IsUByte() && + mInstructions[i + 1]->mSrc[1].mTemp < 0 && ispow2(mInstructions[i + 1]->mSrc[1].mIntConst)) + { + int64 k = binlog(mInstructions[i + 1]->mSrc[1].mIntConst); + + if (mInstructions[i + 0]->mSrc[0].mTemp >= 0 && mInstructions[i + 0]->mSrc[1].mTemp < 0) + { + int64 s = mInstructions[i + 0]->mSrc[1].mIntConst; + mInstructions[i + 0]->mSrc[1] = mInstructions[i + 0]->mSrc[0]; + mInstructions[i + 0]->mSrc[0].mTemp = -1; + mInstructions[i + 0]->mSrc[0].mIntConst = mInstructions[i + 0]->mSrc[1].mRange.mMinValue; + mInstructions[i + 0]->mDst.mRange.SetLimit(0, mInstructions[i + 0]->mSrc[1].mRange.mMaxValue - mInstructions[i + 0]->mSrc[0].mIntConst); + mInstructions[i + 1]->mOperator = IA_SHL; + mInstructions[i + 1]->mSrc[0] = mInstructions[i + 0]->mDst; + int64 d = s - mInstructions[i + 0]->mSrc[0].mIntConst; + if (d < 0) + mInstructions[i + 1]->mSrc[1].mIntConst <<= -d; + else + mInstructions[i + 1]->mSrc[1].mIntConst >>= d; + changed = true; + } + } + } + + #endif } @@ -22927,7 +22996,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "test"); CheckCase = false; mEntryBlock = mBlocks[0];