From 48f97b6e60fc96f314210117be75ebf217b526a2 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 31 Mar 2022 18:16:31 +0200 Subject: [PATCH] Optimize compare to boolean variable --- oscar64/InterCode.cpp | 8 ++ oscar64/NativeCodeGenerator.cpp | 152 +++++++++++++++++++++++++++++-- oscar64/NativeCodeGenerator.h | 2 +- oscar64/oscar64.cpp | 2 +- oscar64/oscar64.rc | 8 +- oscar64setup/oscar64setup.vdproj | 6 +- 6 files changed, 163 insertions(+), 15 deletions(-) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 91c2dc4..63ce20e 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4684,6 +4684,14 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void) if (cins->mSrc[0].IsUnsigned() && cins->mSrc[1].IsUnsigned()) cins->mOperator = IA_CMPLEU; break; + case IA_CMPGS: + if (cins->mSrc[0].IsUnsigned() && cins->mSrc[1].IsUnsigned()) + cins->mOperator = IA_CMPGU; + break; + case IA_CMPGES: + if (cins->mSrc[0].IsUnsigned() && cins->mSrc[1].IsUnsigned()) + cins->mOperator = IA_CMPGEU; + break; } } } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index e391b46..7a7305c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -974,7 +974,7 @@ bool NativeCodeInstruction::IsSame(const NativeCodeInstruction& ins) const return false; } -bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins) const +bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY) const { if (ins.mMode == ASMIM_ZERO_PAGE) { @@ -999,7 +999,12 @@ bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins) c else if (ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) { if (mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) - return mLinkerObject == ins.mLinkerObject; + { + if (mLinkerObject != ins.mLinkerObject) + return false; + else + return mMode != ins.mMode || !sameXY || mAddress == ins.mAddress; + } else return mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_INDIRECT_X; } @@ -7190,6 +7195,23 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, treg + 1)); } } +#if 1 + else if (shift == 6) + { + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, sreg + 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0xc0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); + } +#endif else if (shift == 7) { int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; @@ -12377,7 +12399,7 @@ bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at) } if (mIns[j].ChangesZeroPage(mIns[at].mAddress)) return false; - if (mIns[j].MayBeSameAddress(mIns[at + 1])) + if (mIns[j].MayBeSameAddress(mIns[at + 1], true)) return false; if (mIns[at + 1].mMode == ASMIM_ABSOLUTE_X && mIns[j].ChangesXReg()) return false; @@ -12782,9 +12804,9 @@ bool NativeCodeBasicBlock::MoveLoadAddImmStoreAbsXUp(int at) { if (mIns[j].ChangesXReg()) break; - if (mIns[j].MayBeSameAddress(mIns[at + 3])) + if (mIns[j].MayBeSameAddress(mIns[at + 3], true)) break; - if (mIns[j].MayBeSameAddress(mIns[at + 0]) && mIns[j].ChangesAddress()) + if (mIns[j].MayBeSameAddress(mIns[at + 0], true) && mIns[j].ChangesAddress()) break; if (!(mIns[j - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z))) @@ -15635,6 +15657,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mVisited = true; +#if 1 #if 1 // move load store pairs up to initial store @@ -16185,6 +16208,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } #endif +#endif + #if 1 bool progress = false; do { @@ -17206,10 +17231,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass #endif else if ( mIns[i + 0].mType == ASMIT_TAX && - !mIns[i + 1].ChangesXReg() && + mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED && + mIns[i + 2].mType == ASMIT_TXA && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Z | LIVE_CPU_REG_X))) + { + mIns[i + 0].mType = ASMIT_CMP; mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mAddress = 0x80; + mIns[i + 0].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_TAX && + !mIns[i + 1].ChangesXReg() && !mIns[i + 1].ChangesAccu() && mIns[i + 2].mType == ASMIT_TXA && !(mIns[i + 2].mLive & LIVE_CPU_REG_Z)) { mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 1].mLive |= LIVE_CPU_REG_A; progress = true; } else if ( @@ -17232,6 +17269,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 1].mLive |= LIVE_CPU_REG_A; progress = true; } + else if ( mIns[i + 0].mType == ASMIT_SEC && mIns[i + 1].mType == ASMIT_TXA && @@ -19003,6 +19041,106 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } while (progress); + int sz = mIns.Size(); +#if 1 + if (sz >= 2 && + mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && + mIns[sz - 1].mType == ASMIT_CMP) + { + if (mBranch == ASMIT_BNE) + { + if (mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCC) + { + mTrueJump = mTrueJump->mTrueJump; + changed = true; + } + else if (mTrueJump->mIns.Size() == 0 && mTrueJump->mBranch == ASMIT_BCS) + { + mTrueJump = mTrueJump->mFalseJump; + changed = true; + } + } + else if (mBranch == ASMIT_BEQ) + { + if (mFalseJump->mIns.Size() == 0 && mFalseJump->mBranch == ASMIT_BCS) + { + mFalseJump = mFalseJump->mTrueJump; + changed = true; + } + else if (mFalseJump->mIns.Size() == 0 && mFalseJump->mBranch == ASMIT_BCC) + { + mFalseJump = mFalseJump->mFalseJump; + changed = true; + } + } + } +#endif +#if 1 + else if (sz >= 2 && + mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 && + mIns[sz - 1].mType == ASMIT_ROL && mIns[sz - 1].mMode == ASMIM_IMPLIED && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + if (mBranch == ASMIT_BNE) + { + mBranch = ASMIT_BCS; + mIns.SetSize(sz - 2); + changed = true; + } + else if (mBranch == ASMIT_BEQ) + { + mBranch = ASMIT_BCC; + mIns.SetSize(sz - 2); + changed = true; + } + } +#endif +#if 1 + if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && + mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 && + mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE && + mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE) + { + if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mBranch = ASMIT_JMP; + mTrueJump = mTrueJump->mTrueJump; + mFalseJump = nullptr; + changed = true; + } + else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mBranch = ASMIT_JMP; + mTrueJump = mTrueJump->mTrueJump; + mFalseJump = nullptr; + changed = true; + } + else if (mBranch == ASMIT_BCS && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1)); + mBranch = ASMIT_JMP; + mTrueJump = mTrueJump->mTrueJump; + mFalseJump = nullptr; + changed = true; + } + else if (mBranch == ASMIT_BCC && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 1)); + mBranch = ASMIT_JMP; + mTrueJump = mTrueJump->mTrueJump; + mFalseJump = nullptr; + changed = true; + } + } +#endif + #endif if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer(proc, pass)) @@ -20186,12 +20324,14 @@ void NativeCodeProcedure::Optimize(void) #endif #endif +#if 1 if (step == 5) { ResetVisited(); if (mEntryBlock->AlternateXYUsage()) changed = true; } +#endif #if 1 ResetVisited(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 430108c..b7a15db 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -109,7 +109,7 @@ public: bool ChangesGlobalMemory(void) const; bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; bool MayBeChangedOnAddress(const NativeCodeInstruction& ins) const; - bool MayBeSameAddress(const NativeCodeInstruction& ins) const; + bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const; bool IsSame(const NativeCodeInstruction& ins) const; bool IsCommutative(void) const; bool IsShift(void) const; diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index d34c9ec..0aa2066 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.5.108"); + strcpy(strProductVersion, "1.5.109"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 30f4fcb..ccdff99 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,108,0 - PRODUCTVERSION 1,5,108,0 + FILEVERSION 1,5,109,0 + PRODUCTVERSION 1,5,109,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.5.108.0" + VALUE "FileVersion", "1.5.109.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.5.108.0" + VALUE "ProductVersion", "1.5.109.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index d10ccfb..577446d 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -4023,15 +4023,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{EE66F8BE-2269-4D71-A6A6-CC21A650858D}" - "PackageCode" = "8:{AAC14556-801D-484D-8285-9DE33FBBA6FE}" + "ProductCode" = "8:{5BB56FF9-6768-4927-AF3F-EE7248AAF646}" + "PackageCode" = "8:{BBAC5D24-DB07-4725-AEA9-031CB1236496}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.5.108" + "ProductVersion" = "8:1.5.109" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"