diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 2e39957..ece36fb 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -5622,10 +5622,10 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray IntegerValueRange tr; IntegerValueRange& sr(mLocalValueRange[ins->mSrc[0].mTemp]); - tr.mMinState = vr.mMaxState; - tr.mMinValue = -vr.mMaxValue; - tr.mMaxState = vr.mMinState; - tr.mMaxValue = -vr.mMinValue; + tr.mMinState = sr.mMaxState; + tr.mMinValue = -sr.mMaxValue; + tr.mMaxState = sr.mMinState; + tr.mMaxValue = -sr.mMinValue; vr = tr; } break; @@ -6294,6 +6294,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray mInstructions[sz - 1]->mSrc[0].mTemp == mInstructions[sz - 2]->mDst.mTemp && IsIntegerType(mInstructions[sz - 2]->mSrc[0].mType)) { int s1 = mInstructions[sz - 2]->mSrc[1].mTemp, s0 = mInstructions[sz - 2]->mSrc[0].mTemp; + int s1c = -1, s0c = -1; + + if (sz > 2 && mInstructions[sz - 3]->mCode == IC_CONVERSION_OPERATOR && mInstructions[sz - 3]->mOperator == IA_EXT8TO16S) + { + if (s1 == mInstructions[sz - 3]->mSrc[0].mTemp) + s1c = mInstructions[sz - 3]->mDst.mTemp; + if (s0 == mInstructions[sz - 3]->mSrc[0].mTemp) + s0c = mInstructions[sz - 3]->mDst.mTemp; + } switch (mInstructions[sz - 2]->mOperator) { @@ -6340,6 +6349,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); mFalseValueRange[s1].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[1].mType)); + + if (s1c >= 0) + { + mTrueValueRange[s1c].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1); + mTrueValueRange[s1c].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[1].mType)); + + mFalseValueRange[s1c].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst); + mFalseValueRange[s1c].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[1].mType)); + } } else if (s1 < 0) { @@ -6348,6 +6366,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray mFalseValueRange[s0].LimitMax(mInstructions[sz - 2]->mSrc[1].mIntConst); mFalseValueRange[s0].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[0].mType)); + + if (s0c >= 0) + { + mTrueValueRange[s0c].LimitMin(mInstructions[sz - 2]->mSrc[1].mIntConst + 1); + mTrueValueRange[s0c].LimitMaxWeak(SignedTypeMax(mInstructions[sz - 2]->mSrc[0].mType)); + + mFalseValueRange[s0c].LimitMax(mInstructions[sz - 2]->mSrc[1].mIntConst); + mFalseValueRange[s0c].LimitMinWeak(SignedTypeMin(mInstructions[sz - 2]->mSrc[0].mType)); + } } else { @@ -13998,6 +14025,8 @@ void InterCodeProcedure::Close(void) #if 1 BuildTraces(false); + PushSinglePathResultInstructions(); + ResetVisited(); if (mEntryBlock->MergeSameConditionTraces()) { @@ -14011,6 +14040,8 @@ void InterCodeProcedure::Close(void) CheckUsedDefinedTemps(); #endif + PeepholeOptimization(); + #if 1 RebuildIntegerRangeSet(); #endif diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a333c4b..599de54 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -20083,6 +20083,51 @@ bool NativeCodeBasicBlock::CombineImmediateADCUp(int at) return false; } +bool NativeCodeBasicBlock::MoveTXADCDown(int at) +{ + int i = at + 4; + while (i < mIns.Size()) + { + if (mIns[i].ChangesXReg()) + return false; + if (mIns[i].ReferencesZeroPage(mIns[at + 3].mAddress)) + return false; + + if (!(mIns[i].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z))) + { + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, mIns[at + 3].mAddress)); + + switch (mIns[at + 2].mAddress) + { + case -2: + case 254: + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_DEX)); + case -1: + case 255: + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_DEX)); + break; + case 2: + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_INX)); + case 1: + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_INX)); + break; + } + + while (i > at) + { + mIns[i].mLive |= LIVE_CPU_REG_X; + i--; + } + mIns.Remove(at, 4); + return true; + } + + i++; + } + + return false; +} + bool NativeCodeBasicBlock::CombineImmediateADCUpX(int at) { int i = at; @@ -22047,12 +22092,30 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc if (i == mIns.Size()) { int addr = mIns[ai].mAddress; - i = 0; - while (i < mIns.Size() && - (mIns[i].mMode != ASMIM_ZERO_PAGE || mIns[i].mAddress != addr || - mIns[i].mType == ASMIT_LDA || mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_INC || mIns[i].mType == ASMIT_DEC || mIns[i].mType == ASMIT_LDY)) - i++; - if (i == mIns.Size()) + bool fail = false, changey = false; + + for (int i = 0; i < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_LDY) + changey = false; + else if (mIns[i].ReferencesYReg() && changey) + { + fail = true; + break; + } + else if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == addr) + { + if (mIns[i].mType == ASMIT_STA || mIns[i].mType == ASMIT_INC || mIns[i].mType == ASMIT_DEC) + changey = true; + else if (mIns[i].mType != ASMIT_LDA) + { + fail = true; + break; + } + } + } + + if (!fail) { if (!prevBlock) return OptimizeSimpleLoopInvariant(proc); @@ -23322,7 +23385,6 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(NativeCodeProcedure* proc) } break; case ASMIT_LDA: - case ASMIT_STA: if (ins.mMode == ASMIM_ZERO_PAGE) { if (ins.mAddress == yreg && yoffset != 0) @@ -23336,6 +23398,20 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(NativeCodeProcedure* proc) zyreg[ins.mAddress]++; } break; + case ASMIT_STA: + if (ins.mMode == ASMIM_ZERO_PAGE) + { + if (ins.mAddress == yreg && (yoffset != 0 || (ins.mLive & LIVE_CPU_REG_Y))) + yreg = -2; + if (ins.mAddress == xreg && (xoffset != 0 || (ins.mLive & LIVE_CPU_REG_X))) + xreg = -2; + + if (zxreg[ins.mAddress] >= 0) + zxreg[ins.mAddress]++; + if (zyreg[ins.mAddress] >= 0) + zyreg[ins.mAddress]++; + } + break; case ASMIT_TYA: if (yoffset) yreg = -2; @@ -25789,6 +25865,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass CheckLive(); #endif + +#if 1 + for (int i = 0; i + 4 < mIns.Size(); i++) + { + if (mIns[i + 0].mType == ASMIT_TXA && + mIns[i + 1].mType == ASMIT_CLC && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress >= -2 && mIns[i + 2].mAddress <= 2 || mIns[i + 2].mAddress >= 254 && mIns[i + 2].mAddress < 256) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C))) + { + if (MoveTXADCDown(i)) + changed = true; + } + } + + CheckLive(); + +#endif + #if 1 bool progress = false; do { @@ -31515,7 +31609,6 @@ void NativeCodeProcedure::Optimize(void) changed = true; #endif - #if 1 if (step >= 3) { @@ -31535,6 +31628,7 @@ void NativeCodeProcedure::Optimize(void) } } + #if 1 if (step == 3) { @@ -31552,6 +31646,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } #endif + #if 1 if (step > 0) { @@ -31559,12 +31654,12 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->OptimizeSimpleLoop(this)) changed = true; - ResetVisited(); if (mEntryBlock->SimpleLoopReversal(this)) changed = true; } #endif + #if 1 ResetVisited(); if (mEntryBlock->MergeBasicBlocks()) @@ -31617,7 +31712,6 @@ void NativeCodeProcedure::Optimize(void) #endif - #if _DEBUG ResetVisited(); mEntryBlock->CheckBlocks(true); @@ -31875,6 +31969,7 @@ void NativeCodeProcedure::Optimize(void) printf("Opps\n"); } #endif + if (cnt > 200) { changed = false; @@ -31893,6 +31988,7 @@ void NativeCodeProcedure::Optimize(void) else cnt++; + } while (changed); #if 1 diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 8235ae6..47ff1c5 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -331,6 +331,7 @@ public: bool MoveASLMemUp(int start); bool CombineImmediateADCUp(int at); bool CombineImmediateADCUpX(int at); + bool MoveTXADCDown(int at); bool MoveZeroPageCrossBlockUp(int at, const NativeCodeInstruction & lins, const NativeCodeInstruction & sins); bool ShortcutCrossBlockMoves(NativeCodeProcedure* proc); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 4c1687f..adb6f21 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -74,7 +74,7 @@ int main2(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.12.174"); + strcpy(strProductVersion, "1.12.175"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 8f4f025..a2c6d08 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,12,174,0 - PRODUCTVERSION 1,12,174,0 + FILEVERSION 1,12,175,0 + PRODUCTVERSION 1,12,175,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.12.174.0" + VALUE "FileVersion", "1.12.175.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.12.174.0" + VALUE "ProductVersion", "1.12.175.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index f4cf023..8e3658c 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -4450,15 +4450,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{2FD4FD95-A0D1-4DC0-A9F4-DE9085C7F327}" - "PackageCode" = "8:{9C02A8C7-2D5F-4FAB-8185-219EDC622E4E}" + "ProductCode" = "8:{2D54553F-8D43-43A2-9E21-D8825A9DA799}" + "PackageCode" = "8:{32868128-65EE-44DF-B846-310909366FA6}" "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.12.174" + "ProductVersion" = "8:1.12.175" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/memmap/charsetload.d64 b/samples/memmap/charsetload.d64 index 97907ea..061786c 100644 Binary files a/samples/memmap/charsetload.d64 and b/samples/memmap/charsetload.d64 differ