diff --git a/include/opp/string.cpp b/include/opp/string.cpp index 86308ce..e167149 100644 --- a/include/opp/string.cpp +++ b/include/opp/string.cpp @@ -69,7 +69,8 @@ string::string(const char * s, char size) { cstr = malloc(char(size + 2)); cstr[0] = size; - smemcpy(cstr + 1, s, size + 1); + smemcpy(cstr + 1, s, size); + cstr[size + 1] = 0; } else cstr = nullptr; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1e92d7c..930f34f 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -14997,6 +14997,8 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar ; else if (lins->mSrc[1].mTemp < 0 || IsLoopInvariantTemp(lins->mSrc[1].mTemp, body)) { + assert(IsIntegerType(lins->mDst.mType)); + int s = indexScale[lins->mSrc[0].mTemp]; mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, lins); @@ -15017,6 +15019,39 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar indexScale[ains->mDst.mTemp] = s; + modified = true; + continue; + } + } + else if ((lins->mOperator == IA_ADD || lins->mOperator == IA_SUB) && lins->mSrc[1].mTemp >= 0 && lins->mSrc[1].mTemp != lins->mDst.mTemp && + indexScale[lins->mSrc[1].mTemp] != 0 && IsSingleLoopAssign(i, this, body)) + { + if (i + 1 < mInstructions.Size() && mInstructions[i + 1]->mCode == IC_LEA && mInstructions[i + 1]->mSrc[0].mTemp == lins->mDst.mTemp) + ; + else if (lins->mSrc[0].mTemp < 0 || IsLoopInvariantTemp(lins->mSrc[0].mTemp, body)) + { + assert(IsIntegerType(lins->mDst.mType)); + + int s = indexScale[lins->mSrc[1].mTemp]; + + mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, lins); + mLoopPrefix->mExitRequiredTemps += lins->mDst.mTemp; + mEntryRequiredTemps += lins->mDst.mTemp; + tail->mExitRequiredTemps += lins->mDst.mTemp; + tail->mEntryRequiredTemps += lins->mDst.mTemp; + mInstructions.Remove(i); + + InterInstruction* ains = new InterInstruction(lins->mLocation, IC_BINARY_OPERATOR); + ains->mOperator = IA_ADD; + ains->mDst = lins->mDst; + ains->mSrc[1] = lins->mDst; + ains->mSrc[0].mType = lins->mDst.mType; + ains->mSrc[0].mTemp = -1; + ains->mSrc[0].mIntConst = s; + tail->AppendBeforeBranch(ains); + + indexScale[ains->mDst.mTemp] = s; + modified = true; continue; } @@ -21882,7 +21917,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "REUArray::CacheNode::*CacheNode"); + CheckFunc = !strcmp(mIdent->mString, "test"); CheckCase = false; mEntryBlock = mBlocks[0]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b177492..abcbaa9 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -25429,6 +25429,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool { ts = mEntryBlocks[i]->mIns.Size(); mEntryBlocks[i]->mIns[ts - 1].mType = ASMIT_LDA; + mEntryBlocks[i]->mIns[ts - 1].mLive |= LIVE_CPU_REG_C; mEntryBlocks[i]->mIns[ts - 2].mType = ASMIT_NOP; mEntryBlocks[i]->mIns[ts - 2].mMode = ASMIM_IMPLIED; mEntryBlocks[i]->mExitRequiredRegs += addr; @@ -31050,7 +31051,7 @@ bool NativeCodeBasicBlock::MoveLoadStoreOutOfXYRangeUp(int at) bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at) { int j = at - 1; - while (j > 0) + while (j >= 0) { if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress) { @@ -50513,7 +50514,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc = proc; mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "shot_add"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "sformat"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -51183,6 +51184,52 @@ bool NativeCodeProcedure::MapFastParamsToTemps(void) } } + NativeCodeBasicBlock* block = mEntryBlock; + while (block && block->mIns.Size() == 0 && !block->mFalseJump) + block = block->mTrueJump; + + if (block && block->mNumEntries == 1) + { + used.Clear(); + modified.Clear(); + + NumberSet tpairs(256), aliased(256); + + for (int i = 1; i < 256; i++) + { + if (alias[i] != i) + aliased += alias[i]; + } + + ResetVisited(); + if (block->mTrueJump) + block->mTrueJump->CollectZeroPageUsage(used, modified, tpairs); + if (block->mFalseJump) + block->mFalseJump->CollectZeroPageUsage(used, modified, tpairs); + + for (int i = 0; i + 1 < block->mIns.Size(); i++) + { + if (block->mIns[i + 0].mType == ASMIT_LDA && block->mIns[i + 0].mMode == ASMIM_ZERO_PAGE && block->mIns[i + 0].mAddress >= BC_REG_FPARAMS && block->mIns[i + 0].mAddress < BC_REG_FPARAMS_END && + block->mIns[i + 1].mType == ASMIT_STA && block->mIns[i + 1].mMode == ASMIM_ZERO_PAGE && block->mIns[i + 1].mAddress > BC_REG_TMP && !used[block->mIns[i + 0].mAddress] && + !aliased[block->mIns[i + 0].mAddress]) + { + if (!block->ReferencesZeroPage(block->mIns[i + 0].mAddress, i + 1) && !block->ReferencesZeroPage(block->mIns[i + 1].mAddress, 0, i)) + { + alias[block->mIns[i + 1].mAddress] = block->mIns[i + 0].mAddress; + aliased += block->mIns[i + 0].mAddress; + } + } + } + + for (int i = 1; i < 255; i++) + { + if ((pairs[i ] && alias[i + 1] != alias[i] + 1) || + (pairs[i - 1] && alias[i - 1] + 1 != alias[i] )) + alias[i] = i; + } + } + + ResetVisited(); return mEntryBlock->RemapZeroPage(alias); }