From 8ab46e29dd9fbda136eee61f187be1bf2d876bef Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 2 Dec 2023 10:58:20 +0100 Subject: [PATCH] Direct parameter forwarding --- oscar64/Declaration.cpp | 30 +++++++- oscar64/Declaration.h | 4 +- oscar64/GlobalAnalyzer.cpp | 79 ++++++++++++++------- oscar64/GlobalOptimizer.cpp | 43 +++++++++++- oscar64/InterCode.cpp | 2 +- oscar64/InterCodeGenerator.cpp | 53 ++++++++++++--- oscar64/Linker.cpp | 31 ++++++++- oscar64/NativeCodeGenerator.cpp | 117 ++++++++++++++++++++++++++++++-- oscar64/Parser.cpp | 2 +- 9 files changed, 310 insertions(+), 51 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 6b5f01e..071c898 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1,5 +1,6 @@ #include "Declaration.h" #include "Constexpr.h" +#include "Linker.h" #include DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name) @@ -451,10 +452,33 @@ Expression* Expression::LogicInvertExpression(void) } } -Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection) +Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection, Linker* linker) { - if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT) + if (mType == EX_PREFIX && mToken == TK_BANKOF && linker) { + LinkerRegion* rgn; + if (mLeft->mDecValue->mSection && (rgn = linker->FindRegionOfSection(mLeft->mDecValue->mSection))) + { + uint64 i = 0; + while (i < 64 && rgn->mCartridgeBanks != (1ULL << i)) + i++; + if (i < 64) + { + Expression* ex = new Expression(mLocation, EX_CONSTANT); + Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); + dec->mBase = TheUnsignedCharTypeDeclaration; + dec->mInteger = i; + ex->mDecValue = dec; + ex->mDecType = dec->mBase; + return ex; + } + } + + return this; + } + else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT) + { + if (mLeft->mDecValue->mType == DT_CONST_INTEGER) { switch (mToken) @@ -944,7 +968,7 @@ Declaration::Declaration(const Location& loc, DecType type) mConst(nullptr), mMutable(nullptr), mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr), mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr), - mVTable(nullptr), mTemplate(nullptr), + mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr), mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1), mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr), diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 0c066f2..4f3efa8 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -8,6 +8,7 @@ class LinkerObject; class LinkerSection; +class Linker; class Parser; enum DecType @@ -244,7 +245,7 @@ public: bool mConst; Expression* LogicInvertExpression(void); - Expression* ConstantFold(Errors * errors, LinkerSection* dataSection); + Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr); bool HasSideEffects(void) const; bool IsSame(const Expression* exp) const; @@ -268,6 +269,7 @@ public: Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment; Declaration * mVTable, * mClass, * mTemplate; + Declaration * mForwardParam, * mForwardCall; Expression* mValue, * mReturn; DeclarationScope* mScope; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 7e12f7b..9e0704f 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -305,7 +305,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) { CheckFastcall(vf, false); - int n = vf->mBase->mFastCallBase + vf->mBase->mFastCallSize; + int n = vf->mBase->mFastCallSize; if (n > nbase) nbase = n; } @@ -323,7 +323,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) // procDec->mBase->mFlags |= DTF_STACKCALL; cf = cf->mBase; - int n = cf->mFastCallBase + cf->mFastCallSize; + int n = cf->mFastCallSize; if (n > nbase) nbase = n; } @@ -359,7 +359,16 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) if (cf != maxf) { - cf->mParams = maxf->mParams; + Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams; + while (fp) + { + fp->mVarIndex = mp->mVarIndex; + fp = fp->mNext; + mp = mp->mNext; + } + + assert(!mp); + cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase; cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize; } @@ -373,9 +382,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) } procDec->mFastCallBase = nbase; - procDec->mFastCallSize = 0; + procDec->mFastCallSize = nbase; procDec->mBase->mFastCallBase = nbase; - procDec->mBase->mFastCallSize = 0; + procDec->mBase->mFastCallSize = nbase; procDec->mFlags &= ~DTF_FUNC_ANALYZING; @@ -390,7 +399,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) } else if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_DYNSTACK)) { - int nparams = 0, npalign = 0; + int nparams = nbase, npalign = 0; int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS; int fplimit = numfpzero; @@ -407,48 +416,66 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head) nparams += 2; } + int cnparams = nparams; Declaration* dec = procDec->mBase->mParams; while (dec) { // Check for parameter crossing boundary - if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero) + if (cnparams < numfpzero && cnparams + dec->mBase->mSize > numfpzero) { - npalign = numfpzero - (nbase + nparams); - nparams += npalign; + npalign = numfpzero - nparams; + cnparams += npalign; } - nparams += dec->mBase->mSize; + cnparams += dec->mBase->mSize; dec = dec->mNext; } - if (nbase + nparams <= fplimit) + if (cnparams <= fplimit) { + npalign = 0; + dec = procDec->mBase->mParams; + while (dec) + { + if (dec->mForwardParam && (dec->mForwardCall->mBase->mFlags & DTF_FASTCALL) && !(dec->mForwardCall->mFlags & DTF_INLINE)) + { + dec->mVarIndex = dec->mForwardParam->mVarIndex; + } + else + { + dec->mForwardParam = nullptr; + // Check for parameter crossing boundary + if (nparams < numfpzero && nparams + dec->mBase->mSize > numfpzero) + { + npalign = numfpzero - nparams; + nparams += npalign; + } + dec->mVarIndex = nparams; + nparams += dec->mBase->mSize; + } + dec = dec->mNext; + } + procDec->mFastCallBase = nbase; procDec->mFastCallSize = nparams; procDec->mBase->mFastCallBase = nbase; procDec->mBase->mFastCallSize = nparams; - // Align fast call parameters to avoid crossing the zero page boundary - if (npalign) - { - Declaration* dec = procDec->mBase->mParams; - while (dec) - { - if (nbase + dec->mVarIndex + dec->mBase->mSize > numfpzero) - dec->mVarIndex += npalign; - dec = dec->mNext; - } - } - procDec->mBase->mFlags |= DTF_FASTCALL; #if 0 - printf("FASTCALL %s\n", f->mIdent->mString); + printf("FASTCALL %s\n", f->mIdent->mString); #endif } else + { +// printf("STACKCALL %s, %d %d\n", procDec->mIdent->mString, cnparams, fplimit); procDec->mBase->mFlags |= DTF_STACKCALL; + } } else + { +// printf("STACKCALL %s, F%d\n", procDec->mIdent->mString, !!(procDec->mFlags& DTF_FUNC_VARIABLE)); procDec->mBase->mFlags |= DTF_STACKCALL; + } } } @@ -759,6 +786,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo return exp->mDecType; } + else if (exp->mToken == TK_BANKOF) + { + return TheUnsignedCharTypeDeclaration; + } else { procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; diff --git a/oscar64/GlobalOptimizer.cpp b/oscar64/GlobalOptimizer.cpp index 1b55005..a3bad8b 100644 --- a/oscar64/GlobalOptimizer.cpp +++ b/oscar64/GlobalOptimizer.cpp @@ -18,7 +18,9 @@ static const uint64 OPTF_VAR_CONST = (1ULL << 9); static const uint64 OPTF_VAR_NOCONST = (1ULL << 10); static const uint64 OPTF_SINGLE_RETURN = (1ULL << 11); static const uint64 OPTF_MULTI_RETURN = (1ULL << 12); - +static const uint64 OPTF_VAR_NO_FORWARD = (1UL << 13); +static const uint64 OPTF_SINGLE_CALL = (1ULL << 14); +static const uint64 OPTF_MULTI_CALL = (1ULL << 15); GlobalOptimizer::GlobalOptimizer(Errors* errors, Linker* linker) : mErrors(errors), mLinker(linker) @@ -45,6 +47,7 @@ void GlobalOptimizer::Reset(void) while (pdec) { pdec->mOptFlags = 0; + pdec->mForwardParam = nullptr; pdec = pdec->mNext; } } @@ -278,6 +281,17 @@ bool GlobalOptimizer::Optimize(void) if (CheckConstReturns(func->mValue)) changed = true; + if (func->mOptFlags & OPTF_MULTI_CALL) + { + Declaration* pdata = ftype->mParams; + while (pdata) + { + pdata->mForwardCall = nullptr; + pdata->mForwardParam = nullptr; + pdata = pdata->mNext; + } + } + if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL)) { if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference())) @@ -601,6 +615,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin if (flags & ANAFL_LHS) exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS; } + if (exp->mDecValue->mType == DT_ARGUMENT) + { + exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD; + exp->mDecValue->mForwardParam = nullptr; + exp->mDecValue->mForwardCall = nullptr; + } return exp->mDecValue; case EX_INITIALIZATION: case EX_ASSIGNMENT: @@ -679,6 +699,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin } else { + if (procDec->mOptFlags & OPTF_SINGLE_CALL) + procDec->mOptFlags |= OPTF_MULTI_CALL; + else + procDec->mOptFlags |= OPTF_SINGLE_CALL; RegisterCall(procDec, ldec); } @@ -771,7 +795,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED)) RegisterProc(Analyze(pex, procDec, 0)); else if (pdec && pdec->mBase->IsReference()) - RegisterProc(Analyze(pex, procDec, ANAFL_LHS | ANAFL_RHS)); + { + if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && pex->mDecValue->mBase->IsReference() && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD)) + { + pex->mDecValue->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS; + pex->mDecValue->mForwardParam = pdec; + pex->mDecValue->mForwardCall = ldec; + } + else + RegisterProc(Analyze(pex, procDec, ANAFL_LHS | ANAFL_RHS)); + } + else if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD)) + { + pex->mDecValue->mOptFlags |= OPTF_VAR_USED; + pex->mDecValue->mForwardParam = pdec; + pex->mDecValue->mForwardCall = ldec; + } else RegisterProc(Analyze(pex, procDec, ANAFL_RHS)); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1b8966b..d3dd0fc 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -3314,7 +3314,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta { for (int i = 0; i < staticVars.Size(); i++) { - if (staticVars[i]->mAliased && !providedVars[i]) + if (staticVars[i]->mAliased && !providedVars.RangeFilled(staticVars[i]->mByteIndex, staticVars[i]->mSize)) requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize); } } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 1212e85..82b5b2c 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2032,7 +2032,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else if (procType->mFlags & DTF_FASTCALL) { ins->mConst.mMemory = IM_FPARAM; - ins->mConst.mVarIndex += procType->mFastCallBase; +// ins->mConst.mVarIndex += procType->mFastCallBase; InitParameter(proc, dec, ins->mConst.mVarIndex); } else @@ -3505,7 +3505,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { ains->mConst.mMemory = IM_FFRAME; ains->mConst.mIntConst = 0; - ains->mConst.mVarIndex += ftype->mFastCallBase; +// ains->mConst.mVarIndex += ftype->mFastCallBase; } else ains->mConst.mMemory = IM_FRAME; @@ -3787,7 +3787,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else if (procType->mFlags & DTF_FASTCALL) { vins->mConst.mMemory = IM_FPARAM; - vins->mConst.mVarIndex += procType->mFastCallBase; +// vins->mConst.mVarIndex += procType->mFastCallBase; } else vins->mConst.mMemory = IM_PARAM; @@ -5181,15 +5181,48 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod { proc->mFastCallProcedure = true; - if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) + if (dec->mFastCallSize > 0) { proc->mFastCallBase = dec->mFastCallBase; - dec->mLinkerObject->mNumTemporaries = 1; - dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase; - if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) - dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize; - else - dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS - dec->mFastCallBase; + + if (dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS && dec->mFastCallSize > dec->mFastCallBase) + { + dec->mLinkerObject->mNumTemporaries = 1; + dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase; + if (dec->mFastCallSize < BC_REG_FPARAMS_END - BC_REG_FPARAMS) + dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize - dec->mFastCallBase; + else + dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - dec->mFastCallBase; + } + + Declaration* pdec = dec->mBase->mParams; + while (pdec) + { + int start = pdec->mVarIndex + BC_REG_FPARAMS, end = start + pdec->mSize; + if (start < BC_REG_FPARAMS_END) + { + if (end > BC_REG_FPARAMS_END) + end = BC_REG_FPARAMS_END; + + int i = 0; + while (i < dec->mLinkerObject->mNumTemporaries && (dec->mLinkerObject->mTemporaries[i] > end || dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < start)) + i++; + if (i < dec->mLinkerObject->mNumTemporaries) + { + if (dec->mLinkerObject->mTemporaries[i] > start) + dec->mLinkerObject->mTemporaries[i] = start; + if (dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < end) + dec->mLinkerObject->mTempSizes[i] = end - dec->mLinkerObject->mTemporaries[i]; + } + else + { + dec->mLinkerObject->mTemporaries[i] = start; + dec->mLinkerObject->mTempSizes[i] = end - start; + dec->mLinkerObject->mNumTemporaries++; + } + } + pdec = pdec->mNext; + } } else proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS; diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index f489308..6700c54 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -34,7 +34,7 @@ bool LinkerReference::operator==(const LinkerReference& ref) mFlags == ref.mFlags && mOffset == ref.mOffset && mRefOffset == ref.mRefOffset && - mObject->mMapID == ref.mObject->mMapID && +// mObject->mMapID == ref.mObject->mMapID && mRefObject->mMapID == ref.mRefObject->mMapID; } @@ -355,7 +355,7 @@ void Linker::CombineSameConst(void) if (i == sobj->mSize) { i = 0; - while (i < sobj->mReferences.Size() && sobj->mReferences[i] == dobj->mReferences[i]) + while (i < sobj->mReferences.Size() && *sobj->mReferences[i] == *dobj->mReferences[i]) i++; if (i == sobj->mReferences.Size()) { @@ -1246,6 +1246,8 @@ bool Linker::WriteCrtFile(const char* filename, uint16 id) bool Linker::WriteMapFile(const char* filename) { + bool banked = mCartridgeBankUsed[0]; + FILE* file; fopen_s(&file, filename, "wb"); if (file) @@ -1275,6 +1277,17 @@ bool Linker::WriteMapFile(const char* filename) if (obj->mFlags & LOBJF_REFERENCED) { + if (banked) + { + int k = 0; + while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k))) + k++; + if (k < 64) + fprintf(file, "%02x:", k); + else + fprintf(file, "--:"); + } + if (obj->mIdent) fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString); else @@ -1282,7 +1295,7 @@ bool Linker::WriteMapFile(const char* filename) } } - if (mCartridgeBankUsed[0]) + if (banked) { fprintf(file, "\nbanks\n"); @@ -1315,6 +1328,18 @@ bool Linker::WriteMapFile(const char* filename) for (int i = 0; i < so.Size(); i++) { const LinkerObject* obj = so[i]; + + if (banked) + { + int k = 0; + while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k))) + k++; + if (k < 64) + fprintf(file, "%02x:", k); + else + fprintf(file, "--:"); + } + fprintf(file, "%04x (%04x) : %s, %s:%s\n", obj->mAddress, obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString); } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 3c06645..af54e04 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -6377,6 +6377,66 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc return true; } +#if 1 + else if (rins1->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins0->mSrc[0].mMemory == IM_FPARAM) + { + if (rins1->mSrc[0].mTemp == wins->mSrc[1].mTemp && rins1->mSrc[0].mIntConst == wins->mSrc[1].mIntConst && rins1->mSrc[0].mStride == wins->mSrc[1].mStride && + wins->mSrc[0].mFinal && wins->mSrc[1].mFinal) + { + int size = InterTypeSize[oins->mDst.mType]; + + AsmInsType aop; + + switch (oins->mOperator) + { + case IA_ADD: + mIns.Push(NativeCodeInstruction(oins, ASMIT_CLC)); + aop = ASMIT_ADC; + break; + case IA_OR: + aop = ASMIT_ORA; + break; + case IA_XOR: + aop = ASMIT_EOR; + break; + case IA_AND: + aop = ASMIT_AND; + break; + default: + return false; + } + + int offset = int(wins->mSrc[1].mIntConst); + for (int i = 0; i < size; i++) + { + while (offset >= 256) + { + mIns.Push(NativeCodeInstruction(rins1, ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp] + 1)); + offset -= 256; + } + + mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDY, ASMIM_IMMEDIATE, offset)); + mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp])); + + mIns.Push(NativeCodeInstruction(oins, ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + rins0->mSrc[0].mVarIndex + int(rins0->mSrc[0].mIntConst) + i)); + + mIns.Push(NativeCodeInstruction(wins, ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp])); + + offset += wins->mSrc[1].mStride; + } + + return true; + } + + + return false; + } + else if (rins0->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins1->mSrc[0].mMemory == IM_FPARAM) + { + printf("OOpsie0\n"); + return false; + } +#endif else return false; } @@ -19561,6 +19621,8 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) mTempRegs += ins.mAddress; mTempRegs += ins.mAddress + 1; } + else if (ins.mType == ASMIT_JSR) + break; } } #endif @@ -26794,11 +26856,12 @@ bool NativeCodeBasicBlock::MoveLDXUp(int at) { if (ins.mLive & LIVE_CPU_REG_Z) return false; + ins.mLive |= LIVE_CPU_REG_A; mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAX)); mIns.Remove(at + 1); - while (i < at) + while (i <= at) { mIns[i].mLive |= LIVE_CPU_REG_X; i++; @@ -26825,11 +26888,12 @@ bool NativeCodeBasicBlock::MoveLDYUp(int at) { if (ins.mLive & LIVE_CPU_REG_Z) return false; + ins.mLive |= LIVE_CPU_REG_A; mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAY)); mIns.Remove(at + 1); - while (i < at) + while (i <= at) { mIns[i].mLive |= LIVE_CPU_REG_Y; i++; @@ -32931,6 +32995,9 @@ bool NativeCodeBasicBlock::OptimizeXYSimpleLoop(void) mIns.Insert(sz - 2, NativeCodeInstruction(mIns[i - 3].mIns, ASMIT_INX)); sz++; changed = true; + mEntryRequiredRegs += CPU_REG_X; + mExitRequiredRegs += CPU_REG_X; + pblock->mExitRequiredRegs += CPU_REG_X; } } } @@ -38371,7 +38438,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass else if ( mIns[i + 0].mType == ASMIT_STA && mIns[i + 1].IsShiftOrInc() && - mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && !mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) && !(mIns[i + 2].mLive & LIVE_CPU_REG_Z)) + mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && + !mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) && + !(mIns[i + 2].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mAddress == mIns[i + 2].mAddress || mIns[i + 1].mAddress == mIns[i + 2].mAddress + 1)) && + !(mIns[i + 2].mLive & LIVE_CPU_REG_Z)) { mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A; @@ -39451,6 +39521,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_LDX && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) && + mIns[i + 1].mType == ASMIT_STX && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) && + mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) && + !mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2])) + { + NativeCodeInstruction ins(mIns[i + 2]); + mIns.Remove(i + 2); + mIns.Insert(i, ins); + mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A; + mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_LDY && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) && + mIns[i + 1].mType == ASMIT_STY && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) && + mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) && + !mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2])) + { + NativeCodeInstruction ins(mIns[i + 2]); + mIns.Remove(i + 2); + mIns.Insert(i, ins); + mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A; + mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A; + progress = true; + } else if ( mIns[i + 0].ChangesAccuAndFlag() && (mIns[i + 1].mType == ASMIT_INC || mIns[i + 1].mType == ASMIT_DEC) && @@ -43527,7 +43623,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "valinc"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -44325,8 +44421,8 @@ void NativeCodeProcedure::Optimize(void) ResetVisited(); if (mEntryBlock->PeepHoleOptimizer(this, step)) changed = true; - #endif + if (step == 2) { ResetVisited(); @@ -44546,6 +44642,11 @@ void NativeCodeProcedure::Optimize(void) #endif } #endif +#if _DEBUG + ResetVisited(); + mEntryBlock->CheckBlocks(); +#endif + if (step > 4 && !changed) { @@ -44561,6 +44662,10 @@ void NativeCodeProcedure::Optimize(void) changed = true; } +#if _DEBUG + ResetVisited(); + mEntryBlock->CheckBlocks(); +#endif #if 1 if (step == 5 || step == 6) @@ -44921,7 +45026,7 @@ void NativeCodeProcedure::Optimize(void) if (step == 11) { - if (changed) + if (changed && cnt < 20) swappedXY = false; else if (!swappedXY) { diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index ca3e12a..b81861b 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -7233,7 +7233,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs) nexp->mDecType = nexp->mLeft->mDecType; } nexp = CheckOperatorOverload(nexp); - return nexp->ConstantFold(mErrors, mDataSection); + return nexp->ConstantFold(mErrors, mDataSection, mCompilationUnits->mLinker); } else return ParsePostfixExpression(lhs);