diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index ec2a52d..ca3e3f0 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2014,6 +2014,41 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte mSrc[0].mTemp = -1; return true; } + break; + case IC_BINARY_OPERATOR: + { + bool changed = false; + + for (int i = 0; i < 2; i++) + { + if (mSrc[i].mTemp >= 0 && ctemps[mSrc[i].mTemp]) + { + InterInstruction* ains = ctemps[mSrc[i].mTemp]; + mSrc[i] = ains->mConst; + mSrc[i].mType = ains->mDst.mType; + changed = true; + } + } + + if (changed) + { + this->ConstantFolding(); + return true; + } + } break; + + case IC_LEA: + if (mSrc[0].mTemp >= 0 && ctemps[mSrc[0].mTemp]) + { + InterInstruction* ains = ctemps[mSrc[0].mTemp]; + mSrc[0] = ains->mConst; + mSrc[0].mType = ains->mDst.mType; + + this->ConstantFolding(); + return true; + } + break; + } return false; @@ -3588,11 +3623,18 @@ void InterCodeBasicBlock::CollectConstTemps(GrowingInstructionPtrArray& ctemps, { mVisited = true; + GrowingInstructionPtrArray ltemps(nullptr); + for (i = 0; i < mInstructions.Size(); i++) { + mInstructions[i]->PropagateConstTemps(ltemps); + int ttemp = mInstructions[i]->mDst.mTemp; if (ttemp >= 0) { + if (mInstructions[i]->mCode == IC_CONSTANT) + ltemps[ttemp] = mInstructions[i]; + if (assignedTemps[ttemp]) ctemps[ttemp] = nullptr; else @@ -8288,12 +8330,14 @@ void InterCodeProcedure::Close(void) mEntryBlock->CollectEntryBlocks(nullptr); BuildDataFlowSets(); - TempForwarding(); - RemoveUnusedInstructions(); - DisassembleDebug("Removed unreachable branches"); BuildTraces(false); + DisassembleDebug("Rebuilt traces"); + + do { + TempForwarding(); + } while (GlobalConstantPropagation()); #endif diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a120bf9..0251910 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1956,6 +1956,19 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT break; } + if (mMode == ASMIM_ABSOLUTE_X && data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) + { + mMode = ASMIM_ABSOLUTE; + mAddress += data.mRegs[CPU_REG_X].mValue; + changed = true; + } + else if (mMode == ASMIM_ABSOLUTE_Y && data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) + { + mMode = ASMIM_ABSOLUTE; + mAddress += data.mRegs[CPU_REG_Y].mValue; + changed = true; + } + if (mMode == ASMIM_ZERO_PAGE) { switch (mType) @@ -12644,6 +12657,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; progress = true; } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED) + { + int aval = mIns[i + 0].mAddress << 1; + mIns[i + 0].mAddress = aval & 0xff; + if (aval & 0x100) + mIns[i + 1].mType = ASMIT_SEC; + else + mIns[i + 1].mType = ASMIT_CLC; + mIns[i + 1].mMode = ASMIM_IMPLIED; + progress = true; + } #if 1 else if ( mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && @@ -13995,6 +14019,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } } + if (i + 6 < mIns.Size()) + { + if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_LOWER) && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && + mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && + mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Y | LIVE_CPU_REG_Z))) + { + mIns[i + 1].mAddress = mIns[i + 4].mAddress = mIns[i + 1].mAddress + mIns[i + 2].mAddress + 256 * mIns[i + 5].mAddress; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED; + progress = true; + } + } + #if 1 if (i + 1 < mIns.Size() && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 1].mMode == ASMIM_INDIRECT_Y)