diff --git a/include/fixmath.c b/include/fixmath.c index 70cf017..87fbfc3 100644 --- a/include/fixmath.c +++ b/include/fixmath.c @@ -680,17 +680,21 @@ __native unsigned long ldiv16f16(unsigned long x, unsigned long y) __native long ldiv16f16s(long x, long y) { + bool sign = false; if (x < 0) { - if (y < 0) - return ldiv16f16(-x, -y); - else - return -ldiv16f16(-x, y); + x = -x; + sign = true; } - else if (y < 0) + if (y < 0) { - return -ldiv16f16(x, -y); + y = -y; + sign = !sign; } + + x = ldiv16f16(x, y); + if (sign) + return -x; else - return ldiv16f16(x, y); + return x; } diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c5503f1..a609bc4 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -9137,6 +9137,10 @@ bool InterCodeBasicBlock::RemoveUnusedIndirectStoreInstructions(void) stores.Push(ins); } } + else if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) + { + stores.SetSize(0); + } else { int j = 0; @@ -11406,30 +11410,33 @@ bool InterCodeBasicBlock::MergeCommonPathInstructions(void) if (mTrueJump->CanMoveInstructionBeforeBlock(ti) && mFalseJump->CanMoveInstructionBeforeBlock(fi)) { int tindex = mInstructions.Size() - 1; - if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp && - CanSwapInstructions(mInstructions[tindex - 1], tins)) -// CanBypassUp(tins, mInstructions[tindex - 1])) - tindex--; - - mInstructions.Insert(tindex, tins); - tindex++; - if (tins->mDst.mTemp != -1) + if (mInstructions[tindex]->mCode != IC_BRANCH || tins->mDst.mTemp != mInstructions[tindex]->mSrc[0].mTemp) { - if (fins->mDst.mTemp != tins->mDst.mTemp) + if (mInstructions.Size() >= 2 && mInstructions[tindex - 1]->mDst.mTemp == mInstructions[tindex]->mSrc[0].mTemp && + CanSwapInstructions(mInstructions[tindex - 1], tins)) + // CanBypassUp(tins, mInstructions[tindex - 1])) + tindex--; + + mInstructions.Insert(tindex, tins); + tindex++; + if (tins->mDst.mTemp != -1) { - InterInstruction* nins = new InterInstruction(tins->mLocation, IC_LOAD_TEMPORARY); - nins->mDst.mTemp = fins->mDst.mTemp; - nins->mDst.mType = fins->mDst.mType; - nins->mSrc[0].mTemp = tins->mDst.mTemp; - nins->mSrc[0].mType = tins->mDst.mType; - assert(nins->mSrc[0].mTemp >= 0); - mFalseJump->mInstructions.Insert(0, nins); - fi++; + if (fins->mDst.mTemp != tins->mDst.mTemp) + { + InterInstruction* nins = new InterInstruction(tins->mLocation, IC_LOAD_TEMPORARY); + nins->mDst.mTemp = fins->mDst.mTemp; + nins->mDst.mType = fins->mDst.mType; + nins->mSrc[0].mTemp = tins->mDst.mTemp; + nins->mSrc[0].mType = tins->mDst.mType; + assert(nins->mSrc[0].mTemp >= 0); + mFalseJump->mInstructions.Insert(0, nins); + fi++; + } } + mTrueJump->mInstructions.Remove(ti); + mFalseJump->mInstructions.Remove(fi); + changed = true; } - mTrueJump->mInstructions.Remove(ti); - mFalseJump->mInstructions.Remove(fi); - changed = true; } } } @@ -18163,6 +18170,8 @@ void InterCodeProcedure::RemoveUnusedStoreInstructions(InterMemory paramMemory) ResetVisited(); mEntryBlock->RemoveUnusedIndirectStoreInstructions(); + + DisassembleDebug("RemoveUnusedIndirectStoreInstructions"); } } @@ -18538,7 +18547,9 @@ void InterCodeProcedure::PropagateConstOperationsUp(void) ResetVisited(); if (mEntryBlock->SplitSingleBranchUseConst()) changed = true; - + + DisassembleDebug("SplitSingleBranchUseConst"); + ResetVisited(); if (mEntryBlock->CommonTailCodeMerge()) { @@ -18546,6 +18557,8 @@ void InterCodeProcedure::PropagateConstOperationsUp(void) BuildDataFlowSets(); } + DisassembleDebug("CommonTailCodeMerge"); + ResetVisited(); mEntryBlock->BuildConstTempSets(); @@ -18594,7 +18607,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "interpret_expression"); + CheckFunc = !strcmp(mIdent->mString, "parse_expression"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 194253d..4f2e47b 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -20,6 +20,8 @@ static const uint32 LIVE_CPU_REG_X = 0x00000002; static const uint32 LIVE_CPU_REG_Y = 0x00000004; static const uint32 LIVE_CPU_REG_C = 0x00000008; static const uint32 LIVE_CPU_REG_Z = 0x00000010; +static const uint32 LIVE_CPU_REG = 0x0000001f; + static const uint32 LIVE_MEM = 0x00000020; static const uint32 LIVE_ALL = 0x000000ff; @@ -1542,8 +1544,15 @@ bool NativeCodeInstruction::MayBeMovedBefore(const NativeCodeInstruction& ins) return false; if (RequiresCarry() && ins.ChangesCarry() || ins.RequiresCarry() && ChangesCarry()) return false; - - if ((ins.mLive & LIVE_CPU_REG_Z) && ChangesZFlag()) + if ((mLive & LIVE_CPU_REG_A) && ins.ChangesAccu()) + return false; + if ((mLive & LIVE_CPU_REG_X) && ins.ChangesXReg()) + return false; + if ((mLive & LIVE_CPU_REG_Y) && ins.ChangesYReg()) + return false; + if ((mLive & LIVE_CPU_REG_C) && ins.ChangesCarry()) + return false; + if ((mLive & LIVE_CPU_REG_Z) && ins.ChangesZFlag()) return false; return true; @@ -19674,6 +19683,35 @@ bool NativeCodeBasicBlock::CanForward16BitAddSubImmediate(int sreg, int dreg, in return false; } +bool NativeCodeBasicBlock::CanForwardLoadStore(const NativeCodeInstruction& lins, const NativeCodeInstruction& sins, int& index) const +{ + int i = mIns.Size() - 1; + while (i > 0) + { + if (lins.MayBeChangedOnAddress(mIns[i])) + return false; + if (mIns[i].MayBeSameAddress(sins)) + { + index = i - 1; + if (mIns[i].mType == ASMIT_STA && mIns[i - 1].mType == ASMIT_LDA && !(mIns[i].mLive & LIVE_CPU_REG_A) || + mIns[i].mType == ASMIT_STX && mIns[i - 1].mType == ASMIT_LDX && !(mIns[i].mLive & LIVE_CPU_REG_X) || + mIns[i].mType == ASMIT_STY && mIns[i - 1].mType == ASMIT_LDY && !(mIns[i].mLive & LIVE_CPU_REG_Y)) + { + if (!(mIns[i].mLive & LIVE_CPU_REG_Z) && mIns[i].SameEffectiveAddress(sins) && mIns[i - 1].SameEffectiveAddress(lins)) + return true; + } + return false; + } + if (mIns[i].mType == ASMIT_JSR) + return false; + if (sins.MayBeChangedOnAddress(mIns[i])) + return false; + i--; + } + + return false; +} + bool NativeCodeBasicBlock::CanForwardZPMove(int saddr, int daddr, int & index) const { int i = mIns.Size() - 1; @@ -20627,6 +20665,51 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool } } } +#if 1 + if (!changed && !mEntryRequiredRegs[CPU_REG_Z] && (!mEntryRequiredRegs[CPU_REG_A] || !mEntryRequiredRegs[CPU_REG_X] || !mEntryRequiredRegs[CPU_REG_Y])) + { + for (int i = eb->mIns.Size() - 1; i > 0; i--) + { + if ((eb->mIns[i - 1].mType == ASMIT_LDA && eb->mIns[i - 0].mType == ASMIT_STA || + eb->mIns[i - 1].mType == ASMIT_LDX && eb->mIns[i - 0].mType == ASMIT_STX || + eb->mIns[i - 1].mType == ASMIT_LDY && eb->mIns[i - 0].mType == ASMIT_STY) && + (eb->mIns[i - 1].mMode == ASMIM_ZERO_PAGE || eb->mIns[i - 1].mMode == ASMIM_ABSOLUTE) && + (eb->mIns[i - 0].mMode == ASMIM_ZERO_PAGE || eb->mIns[i - 0].mMode == ASMIM_ABSOLUTE)) + { + int j = 0; + while (j < mEntryBlocks.Size() && mEntryBlocks[j]->CanForwardLoadStore(eb->mIns[i - 1], eb->mIns[i - 0], mEntryBlocks[j]->mTemp)) + j++; + + if (j == mEntryBlocks.Size()) + { + const InterInstruction* iins(eb->mIns[i].mIns); + + if (!mEntryRequiredRegs[CPU_REG_A]) + { + mIns.Insert(0, NativeCodeInstruction(iins, ASMIT_LDA, eb->mIns[i - 1])); + mIns.Insert(1, NativeCodeInstruction(iins, ASMIT_STA, eb->mIns[i])); + changed = true; + } + else if (!mEntryRequiredRegs[CPU_REG_X]) + { + mIns.Insert(0, NativeCodeInstruction(iins, ASMIT_LDX, eb->mIns[i - 1])); + mIns.Insert(1, NativeCodeInstruction(iins, ASMIT_STX, eb->mIns[i])); + changed = true; + } + else if (!mEntryRequiredRegs[CPU_REG_Y]) + { + mIns.Insert(0, NativeCodeInstruction(iins, ASMIT_LDY, eb->mIns[i - 1])); + mIns.Insert(1, NativeCodeInstruction(iins, ASMIT_STY, eb->mIns[i])); + changed = true; + } + + for (int j = 0; j < mEntryBlocks.Size(); j++) + mEntryBlocks[j]->mIns.Remove(mEntryBlocks[j]->mTemp, 2); + } + } + } + } +#endif } if (mEntryBlocks.Size() >= 1) @@ -21918,6 +22001,246 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool return changed; } +bool NativeCodeBasicBlock::MayBeMovedBeforeBlock(int at) +{ + int i = at; + while (i > 0) + { + i--; + if (!mIns[at].MayBeMovedBefore(mIns[i])) + return false; + } + + return true; +} + +bool NativeCodeBasicBlock::SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end) +{ + uint32 changes = 0; + uint32 requires = 0; + + for (int i = start; i < end; i++) + { + const NativeCodeInstruction& ins(block->mIns[i]); + if (ins.RequiresAccu() && !(changes & LIVE_CPU_REG_A)) requires |= LIVE_CPU_REG_A; + if (ins.RequiresXReg() && !(changes & LIVE_CPU_REG_X)) requires |= LIVE_CPU_REG_X; + if (ins.RequiresYReg() && !(changes & LIVE_CPU_REG_Y)) requires |= LIVE_CPU_REG_Y; + if (ins.RequiresCarry() && !(changes & LIVE_CPU_REG_C)) requires |= LIVE_CPU_REG_C; + if (ins.ChangesAccu()) changes |= LIVE_CPU_REG_A; + if (ins.ChangesXReg()) changes |= LIVE_CPU_REG_X; + if (ins.ChangesYReg()) changes |= LIVE_CPU_REG_Y; + if (ins.ChangesCarry()) changes |= LIVE_CPU_REG_C; + if (ins.ChangesZFlag()) changes |= LIVE_CPU_REG_Z; + } + + uint32 live = 0; + if (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) + live |= LIVE_CPU_REG_C; + if (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE || mBranch == ASMIT_BMI || mBranch == ASMIT_BPL) + live |= LIVE_CPU_REG_Z; + if (mExitRequiredRegs[CPU_REG_A]) + live |= LIVE_CPU_REG_A; + if (mExitRequiredRegs[CPU_REG_X]) + live |= LIVE_CPU_REG_X; + if (mExitRequiredRegs[CPU_REG_Y]) + live |= LIVE_CPU_REG_Y; + if (mExitRequiredRegs[CPU_REG_C]) + live |= LIVE_CPU_REG_C; + + int at = mIns.Size(); + while (at > 0) + { + if (live & changes) + { + at--; + const NativeCodeInstruction& ins(mIns[at]); + if (ins.ChangesAccu()) + { + if (requires & LIVE_CPU_REG_A) + return false; + live &= ~LIVE_CPU_REG_A; + } + if (ins.ChangesXReg()) + { + if (requires & LIVE_CPU_REG_X) + return false; + live &= ~LIVE_CPU_REG_X; + } + if (ins.ChangesYReg()) + { + if (requires & LIVE_CPU_REG_Y) + return false; + live &= ~LIVE_CPU_REG_Y; + } + if (ins.ChangesCarry()) + { + if (requires & LIVE_CPU_REG_C) + return false; + live &= ~LIVE_CPU_REG_C; + } + if (ins.ChangesZFlag()) live &= ~LIVE_CPU_REG_Z; + + if (ins.RequiresAccu()) + live |= LIVE_CPU_REG_A; + if (ins.RequiresXReg()) + live |= LIVE_CPU_REG_X; + if (ins.RequiresYReg()) + live |= LIVE_CPU_REG_Y; + if (ins.RequiresCarry()) + live |= LIVE_CPU_REG_C; + } + else + { + for (int i = start; i < end; i++) + { + for (int j = at; j < mIns.Size(); j++) + { + if (block->mIns[i].MayBeChangedOnAddress(mIns[j]) || mIns[j].MayBeChangedOnAddress(block->mIns[i])) + return false; + } + } + + for (int i = start; i < end; i++) + { + mIns.Insert(at, block->mIns[i]); + mIns[at].mLive |= live; + at++; + } + return true; + } + } + + return false; +} + +bool NativeCodeBasicBlock::MayBeMovedBeforeBlock(int start, int end) +{ + uint32 changes = 0; + uint32 requires = 0; + + if (start == 0) + return true; + + for (int i = start; i < end; i++) + { + const NativeCodeInstruction& ins(mIns[i]); + if (ins.RequiresAccu() && !(changes & LIVE_CPU_REG_A)) requires |= LIVE_CPU_REG_A; + if (ins.RequiresXReg() && !(changes & LIVE_CPU_REG_X)) requires |= LIVE_CPU_REG_X; + if (ins.RequiresYReg() && !(changes & LIVE_CPU_REG_Y)) requires |= LIVE_CPU_REG_Y; + if (ins.RequiresCarry() && !(changes & LIVE_CPU_REG_C)) requires |= LIVE_CPU_REG_C; + if (ins.ChangesAccu()) changes |= LIVE_CPU_REG_A; + if (ins.ChangesXReg()) changes |= LIVE_CPU_REG_X; + if (ins.ChangesYReg()) changes |= LIVE_CPU_REG_Y; + if (ins.ChangesCarry()) changes |= LIVE_CPU_REG_C; + if (ins.ChangesZFlag()) changes |= LIVE_CPU_REG_Z; + } + + for (int i = 0; i < start; i++) + { + const NativeCodeInstruction& ins(mIns[i]); + if (ins.ChangesAccu() && (requires & LIVE_CPU_REG_A)) + return false; + if (ins.ChangesXReg() && (requires & LIVE_CPU_REG_X)) + return false; + if (ins.ChangesYReg() && (requires & LIVE_CPU_REG_Y)) + return false; + if (ins.ChangesCarry() && (requires & LIVE_CPU_REG_C)) + return false; + + for (int j = start; j < end; j++) + { + if (mIns[i].MayBeChangedOnAddress(mIns[j]) || mIns[j].MayBeChangedOnAddress(mIns[i])) + return false; + } + } + + return true; +} + +bool NativeCodeBasicBlock::JoinCommonBranchCodeSequences(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + if (mTrueJump && mFalseJump && mTrueJump->mIns.Size() > 0 && mFalseJump->mIns.Size() > 0 && + mTrueJump != this && mFalseJump != this && + mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1) + { + int i = 0; + while (i < mTrueJump->mIns.Size()) + { + int j = 0; + while (j < mFalseJump->mIns.Size() && !mFalseJump->mIns[j].IsSame(mTrueJump->mIns[i])) + j++; + if (j < mFalseJump->mIns.Size()) + { + int n = 0; + while (i + n < mTrueJump->mIns.Size() && j + n < mFalseJump->mIns.Size() && ((mTrueJump->mIns[i + n].mLive & LIVE_CPU_REG) || (mFalseJump->mIns[j + n].mLive & LIVE_CPU_REG))) + n++; + + if (i + n < mTrueJump->mIns.Size() && j + n < mFalseJump->mIns.Size()) + { + if (mTrueJump->MayBeMovedBeforeBlock(i, i + n + 1) && mFalseJump->MayBeMovedBeforeBlock(j, j + n + 1)) + { + if (SafeInjectSequenceFromBack(mTrueJump, i, i + n + 1)) + { + for (int k = 0; k < i; k++) + mTrueJump->mIns[k].mLive |= mTrueJump->mIns[i].mLive; + for (int k = 0; k < j; k++) + mFalseJump->mIns[k].mLive |= mFalseJump->mIns[j].mLive; + if (mTrueJump->mIns[i].mLive & LIVE_CPU_REG_A) + { + mTrueJump->mEntryRequiredRegs += CPU_REG_A; + mFalseJump->mEntryRequiredRegs += CPU_REG_A; + } + if (mTrueJump->mIns[i].mLive & LIVE_CPU_REG_X) + { + mTrueJump->mEntryRequiredRegs += CPU_REG_X; + mFalseJump->mEntryRequiredRegs += CPU_REG_X; + } + if (mTrueJump->mIns[i].mLive & LIVE_CPU_REG_Y) + { + mTrueJump->mEntryRequiredRegs += CPU_REG_Y; + mFalseJump->mEntryRequiredRegs += CPU_REG_Y; + } + if (mTrueJump->mIns[i].mLive & LIVE_CPU_REG_C) + { + mTrueJump->mEntryRequiredRegs += CPU_REG_C; + mFalseJump->mEntryRequiredRegs += CPU_REG_C; + } + + mTrueJump->mIns.Remove(i, n + 1); + mFalseJump->mIns.Remove(j, n + 1); + changed = true; + } + else + i++; + } + else + i++; + } + else + i++; + } + else + i++; + } + } + + CheckLive(); + + if (mTrueJump && mTrueJump->JoinCommonBranchCodeSequences()) + changed = true; + if (mFalseJump && mFalseJump->JoinCommonBranchCodeSequences()) + changed = true; + } + + return changed; +} + void NativeCodeBasicBlock::DoCrossBlockAShortcut(int addr) { mExitRequiredRegs += CPU_REG_A; @@ -23457,15 +23780,18 @@ bool NativeCodeBasicBlock::PatchCrossBlock16BitFloodExit(const NativeCodeBasicBl { NativeCodeInstruction& ins(mIns[at]); - if (ins.mAddress == dreg) + if (ins.mMode == ASMIM_ZERO_PAGE || ins.mMode == ASMIM_ZERO_PAGE_X || ins.mMode == ASMIM_ZERO_PAGE_Y || ins.mMode == ASMIM_INDIRECT_X || ins.mMode == ASMIM_INDIRECT_Y) { - ins.mAddress = sreg; - changed = true; - } - else if (ins.mAddress == dreg + 1) - { - ins.mAddress = sreg + 1; - changed = true; + if (ins.mAddress == dreg) + { + ins.mAddress = sreg; + changed = true; + } + else if (ins.mAddress == dreg + 1) + { + ins.mAddress = sreg + 1; + changed = true; + } } at--; @@ -26862,6 +27188,54 @@ bool NativeCodeBasicBlock::MoveZeroPageCrossBlockUp(int at, const NativeCodeInst } +bool NativeCodeBasicBlock::ShortcutCrossBlockCondition(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + int sz = mIns.Size(); + if (sz > 0 && mIns[sz - 1].mType == ASMIT_LDA && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && !mFalseJump) + { + if (mTrueJump->mIns.Size() == 2 && mTrueJump->mIns[0].mType == ASMIT_STA && + mTrueJump->mIns[1].mType == ASMIT_ORA && mTrueJump->mIns[1].mMode == ASMIM_IMMEDIATE && mTrueJump->mIns[1].mAddress == 0 && + (mTrueJump->mBranch == ASMIT_BEQ || mTrueJump->mBranch == ASMIT_BNE)) + { + mIns.Push(mTrueJump->mIns[0]); + + mTrueJump->mNumEntries--; + mTrueJump->mEntryBlocks.Remove(mTrueJump->mEntryBlocks.IndexOf(this)); + if (mTrueJump->mBranch == ASMIT_BEQ) + { + if (mIns[sz - 1].mAddress == 0) + mTrueJump = mTrueJump->mTrueJump; + else + mTrueJump = mTrueJump->mFalseJump; + } + else + { + if (mIns[sz - 1].mAddress != 0) + mTrueJump = mTrueJump->mTrueJump; + else + mTrueJump = mTrueJump->mFalseJump; + } + mTrueJump->mNumEntries++; + mTrueJump->mEntryBlocks.Push(this); + changed = true; + } + } + + if (mTrueJump && mTrueJump->ShortcutCrossBlockCondition()) + changed = true; + if (mFalseJump && mFalseJump->ShortcutCrossBlockCondition()) + changed = true; + } + + return changed; +} + bool NativeCodeBasicBlock::ShortcutCrossBlockMoves(NativeCodeProcedure* proc) { bool changed = false; @@ -40445,6 +40819,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_LDA && + mIns[i + 1].mType == ASMIT_STA && + mIns[i + 2].mType == ASMIT_CLC && + mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 255 && + mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)) && + HasAsmInstructionMode(ASMIT_DEC, mIns[i + 0].mMode)) + { + mIns[i + 4].mType = ASMIT_DEC; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + progress = true; } #endif @@ -42803,7 +43191,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "dungeon_init"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -43711,6 +44099,14 @@ void NativeCodeProcedure::Optimize(void) changed = true; } #endif + + if (step > 6 && !changed) + { + ResetVisited(); + if (mEntryBlock->ShortcutCrossBlockCondition()) + changed = true; + } + #if _DEBUG ResetVisited(); mEntryBlock->CheckBlocks(true); @@ -43731,6 +44127,16 @@ void NativeCodeProcedure::Optimize(void) changed = true; } + if (step > 2 && !changed) + { + ResetVisited(); + if (mEntryBlock->JoinCommonBranchCodeSequences()) + { + changed = true; + BuildDataFlowSets(); + } + } + if (step > 4) { ResetVisited(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index b94d19c..86d6be8 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -459,6 +459,7 @@ public: bool MoveZeroPageCrossBlockUp(int at, const NativeCodeInstruction & lins, const NativeCodeInstruction & sins); bool ShortcutCrossBlockMoves(NativeCodeProcedure* proc); + bool ShortcutCrossBlockCondition(void); bool CanReplaceYRegWithXReg(int start, int end); bool CanReplaceXRegWithYReg(int start, int end); @@ -518,6 +519,11 @@ public: bool HasTailSTY(int& addr, int& index) const; bool HasTailSTAX16(int& addr, int& index0) const; + bool MayBeMovedBeforeBlock(int at); + bool MayBeMovedBeforeBlock(int start, int end); + bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end); + bool JoinCommonBranchCodeSequences(void); + bool CanJoinEntryLoadStoreZP(int saddr, int daddr); bool DoJoinEntryLoadStoreZP(int saddr, int daddr); bool JoinEntryLoadStoreZP(void); @@ -621,8 +627,8 @@ public: bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex); bool PropagateCommonSubExpression(void); - bool ForwardAbsoluteLoadStores(void); bool CanForwardZPMove(int saddr, int daddr, int & index) const; + bool CanForwardLoadStore(const NativeCodeInstruction & lins, const NativeCodeInstruction & sins, int& index) const; bool Is16BitAddSubImmediate(int at, int& sreg, int &dreg, int& offset) const; bool CanForward16BitAddSubImmediate(int sreg, int dreg, int offset, int & index) const;