Relax interrupt complexity limits for local variables on stack

This commit is contained in:
drmortalwombat 2025-05-24 20:48:04 +02:00
parent 0af17f0f40
commit 6076808f5e
3 changed files with 244 additions and 17 deletions

View File

@ -1486,7 +1486,21 @@ Declaration* Declaration::ConstCast(Declaration* ntype)
return pdec; return pdec;
} }
else if (mType == DT_VARIABLE_REF && mBase->mBase->mType == DT_TYPE_ARRAY) else if (mType == DT_VARIABLE_REF)
{
Declaration* vtype = mBase->mBase;
while (vtype && vtype->mType == DT_TYPE_STRUCT)
{
Declaration* dec = vtype->mParams;
while (dec && dec->mOffset != mOffset)
dec = dec->mNext;
if (dec)
vtype = dec->mBase;
else
vtype = nullptr;
}
if (vtype && vtype->mType == DT_TYPE_ARRAY)
{ {
Expression* ex = new Expression(mLocation, EX_VARIABLE); Expression* ex = new Expression(mLocation, EX_VARIABLE);
ex->mDecType = mBase->mBase; ex->mDecType = mBase->mBase;
@ -1503,6 +1517,9 @@ Declaration* Declaration::ConstCast(Declaration* ntype)
else else
return this; return this;
} }
else
return this;
}
else if (ntype->mType == DT_TYPE_INTEGER || ntype->mType == DT_TYPE_BOOL || ntype->mType == DT_TYPE_ENUM) else if (ntype->mType == DT_TYPE_INTEGER || ntype->mType == DT_TYPE_BOOL || ntype->mType == DT_TYPE_ENUM)
{ {
if (mType == DT_CONST_FLOAT) if (mType == DT_CONST_FLOAT)

View File

@ -40092,6 +40092,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
#endif #endif
CheckLive();
// Special case of 16 bit shift with unused upper byte result // Special case of 16 bit shift with unused upper byte result
if (mIns.Size() == 3 && mBranch == ASMIT_BNE && mTrueJump == this && !mFalseJump->mEntryRequiredRegs[CPU_REG_A] && if (mIns.Size() == 3 && mBranch == ASMIT_BNE && mTrueJump == this && !mFalseJump->mEntryRequiredRegs[CPU_REG_A] &&
mIns[0].mType == ASMIT_ASL && mIns[0].mMode == ASMIM_ZERO_PAGE && mIns[0].mType == ASMIT_ASL && mIns[0].mMode == ASMIM_ZERO_PAGE &&
@ -40114,6 +40116,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
changed = true; changed = true;
} }
CheckLive();
if (sz >= 2 && (mIns[0].mType == ASMIT_ASL || mIns[0].mType == ASMIT_LSR) && mIns[0].mMode == ASMIM_ZERO_PAGE && if (sz >= 2 && (mIns[0].mType == ASMIT_ASL || mIns[0].mType == ASMIT_LSR) && mIns[0].mMode == ASMIM_ZERO_PAGE &&
mIns[sz - 1].mType == ASMIT_LDA && mIns[sz - 1].SameEffectiveAddress(mIns[0])) mIns[sz - 1].mType == ASMIT_LDA && mIns[sz - 1].SameEffectiveAddress(mIns[0]))
@ -40140,6 +40143,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
} }
CheckLive();
if (sz >= 2 && (mIns[0].mType == ASMIT_DEC || mIns[0].mType == ASMIT_INC) && mIns[0].mMode == ASMIM_ZERO_PAGE && if (sz >= 2 && (mIns[0].mType == ASMIT_DEC || mIns[0].mType == ASMIT_INC) && mIns[0].mMode == ASMIM_ZERO_PAGE &&
mIns[1].mType == ASMIT_LDY && mIns[1].SameEffectiveAddress(mIns[0])) mIns[1].mType == ASMIT_LDY && mIns[1].SameEffectiveAddress(mIns[0]))
{ {
@ -40182,6 +40187,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
} }
CheckLive();
if (mIns.Size() > 0 && (mIns.Last().mType == ASMIT_DEX || mIns.Last().mType == ASMIT_DEC || mIns.Last().mType == ASMIT_CPX)) if (mIns.Size() > 0 && (mIns.Last().mType == ASMIT_DEX || mIns.Last().mType == ASMIT_DEC || mIns.Last().mType == ASMIT_CPX))
{ {
bool yzero = false; bool yzero = false;
@ -40278,7 +40285,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
mIns[i].mMode = ASMIM_IMPLIED; mIns[i].mMode = ASMIM_IMPLIED;
} }
mIns[i].mLive |= LIVE_CPU_REG_Y; mIns[i].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_A;
} }
int j = mIns.Size(); int j = mIns.Size();
while (j > 0 && (mIns[j - 1].mLive & LIVE_CPU_REG_Z)) while (j > 0 && (mIns[j - 1].mLive & LIVE_CPU_REG_Z))
@ -40290,6 +40297,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
} }
CheckLive();
sz = mIns.Size(); sz = mIns.Size();
if (sz >= 3 && if (sz >= 3 &&
mIns[0].mType == ASMIT_STA && mIns[0].mMode == ASMIM_ZERO_PAGE && mIns[0].mType == ASMIT_STA && mIns[0].mMode == ASMIM_ZERO_PAGE &&
@ -40334,6 +40343,8 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
CheckLive();
if (sz >= 3 && if (sz >= 3 &&
mIns[0].mType == ASMIT_TAY && mIns[0].mType == ASMIT_TAY &&
mIns[sz - 1].mType == ASMIT_CPX && mIns[sz - 2].mType == ASMIT_TXA && mIns[sz - 3].mType == ASMIT_INX && mIns[sz - 1].mType == ASMIT_CPX && mIns[sz - 2].mType == ASMIT_TXA && mIns[sz - 3].mType == ASMIT_INX &&
@ -55389,7 +55400,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
if (mInterProc->mInterrupt) if (mInterProc->mInterrupt)
{ {
if (!mNoFrame || mStackExpand > 0 || commonFrameSize > 0) if (!mNoFrame || commonFrameSize > 0)
mGenerator->mErrors->Error(mLocation, ERRR_INTERRUPT_TO_COMPLEX, "Function to complex for interrupt"); mGenerator->mErrors->Error(mLocation, ERRR_INTERRUPT_TO_COMPLEX, "Function to complex for interrupt");
ZeroPageSet zpLocal, zpGlobal; ZeroPageSet zpLocal, zpGlobal;
@ -55408,7 +55419,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_PHA)); mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_PHA));
} }
bool usesStack = false; bool usesStack = mStackExpand;
if (zpLocal[BC_REG_STACK]) if (zpLocal[BC_REG_STACK])
{ {
@ -55419,6 +55430,17 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
if (usesStack) if (usesStack)
{ {
if (mStackExpand)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_SEC, ASMIM_IMPLIED));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_SBC, ASMIM_IMMEDIATE, ((mStackExpand + commonFrameSize) >> 8) + 1));
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
else
mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); mEntryBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
} }
@ -55441,6 +55463,17 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
} }
if (usesStack) if (usesStack)
{ {
if (mStackExpand)
{
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_CLC, ASMIM_IMPLIED));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_ADC, ASMIM_IMMEDIATE, ((mStackExpand + commonFrameSize) >> 8) + 1));
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
else
mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); mExitBlock->mIns.Push(NativeCodeInstruction(mExitBlock->mBranchIns, ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
} }

View File

@ -3060,7 +3060,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
bool inlineCopy = true; bool inlineCopy = true;
bool inlineMove = true; bool inlineMove = true;
bool explicitDestructor = false; bool explicitDestructor = false;
bool canMoveConstruct = true;
const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");; const Ident* dtorident = pthis->mBase->mIdent->PreMangle("~");;
const Ident* ctorident = pthis->mBase->mIdent->PreMangle("+");; const Ident* ctorident = pthis->mBase->mIdent->PreMangle("+");;
@ -3131,8 +3131,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
{ {
simpleMove = false; simpleMove = false;
if (!(bcdec->mBase->mMoveConstructor->mBase->mFlags & DTF_REQUEST_INLINE)) if (!(bcdec->mBase->mMoveConstructor->mBase->mFlags & DTF_REQUEST_INLINE))
inlineCopy = false; inlineMove = false;
} }
else if (bcdec->mBase->mDestructor || bcdec->mBase->mDefaultConstructor || bcdec->mBase->mCopyConstructor)
canMoveConstruct = false;
if (bcdec->mBase->mCopyAssignment) if (bcdec->mBase->mCopyAssignment)
simpleAssignment = false; simpleAssignment = false;
bcdec = bcdec->mNext; bcdec = bcdec->mNext;
@ -3145,6 +3148,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
{ {
simpleCopy = false; simpleCopy = false;
simpleAssignment = false; simpleAssignment = false;
canMoveConstruct = false;
} }
Declaration* dec = pthis->mBase->mParams; Declaration* dec = pthis->mBase->mParams;
@ -3181,6 +3185,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
simpleAssignment = false; simpleAssignment = false;
if (bdec->mMoveConstructor) if (bdec->mMoveConstructor)
simpleMove = false; simpleMove = false;
else if (bdec->mDestructor || bdec->mDefaultConstructor || bdec->mCopyConstructor)
canMoveConstruct = false;
} }
if (dec->mValue) if (dec->mValue)
simpleConstructor = false; simpleConstructor = false;
@ -3438,6 +3444,177 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec->mFlags |= DTF_DEFINED; cdec->mFlags |= DTF_DEFINED;
} }
#if 0
if (!pthis->mBase->mMoveConstructor && !canMoveConstruct)
{
Declaration* ctdec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION);
ctdec->mSize = 0;
ctdec->mBase = TheVoidTypeDeclaration;
ctdec->mFlags |= DTF_DEFINED;
Declaration* adec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
adec->mVarIndex = 0;
adec->mOffset = 0;
adec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_RVALUEREF);
adec->mBase->mSize = 2;
adec->mBase->mBase = pthis->mBase;
adec->mBase->mFlags |= DTF_CONST | DTF_DEFINED;
adec->mSize = adec->mBase->mSize;
adec->mIdent = adec->mQualIdent = Ident::Unique("_");
ctdec->mParams = adec;
PrependThisArgument(ctdec, pthis);
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
cdec->mBase = ctdec;
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
if (inlineCopy)
cdec->mFlags |= DTF_REQUEST_INLINE;
cdec->mSection = mCodeSection;
if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE;
pthis->mBase->mMoveConstructor = cdec;
cdec->mIdent = ctorident;
cdec->mQualIdent = ctorqident;
cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions;
cdec->mVarIndex = -1;
if (explicitDestructor)
cdec->mFlags |= DTF_DEPRECATED;
cdec->mValue = new Expression(mScanner->mLocation, EX_VOID);
// Now add all the copying
Expression* pthisexp = new Expression(pthis->mLocation, EX_VARIABLE);
pthisexp->mDecType = pthis;
pthisexp->mDecValue = cdec->mBase->mParams;
Expression* thisexp = new Expression(mScanner->mLocation, EX_PREFIX);
thisexp->mToken = TK_MUL;
thisexp->mDecType = pthis->mBase;
thisexp->mLeft = pthisexp;
Expression* thatexp = new Expression(pthis->mLocation, EX_VARIABLE);
thatexp->mDecType = adec->mBase;
thatexp->mDecValue = cdec->mBase->mParams->mNext;
cdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
pthis->mBase->mMoveConstructor = AddMemberFunction(pthis->mBase, cdec);
if (pthis->mBase->mMoveConstructor == cdec)
{
Declaration* dec = pthis->mBase->mParams;
while (dec)
{
if (dec->mType == DT_ELEMENT)
{
Expression* lexp = new Expression(pthis->mLocation, EX_QUALIFY);
lexp->mLeft = thisexp;
lexp->mDecValue = dec;
lexp->mDecType = dec->mBase;
Expression* rexp = new Expression(pthis->mLocation, EX_QUALIFY);
rexp->mLeft = thatexp;
rexp->mDecValue = dec;
rexp->mDecType = dec->mBase;
Expression* mexp;
Declaration* bdec = dec->mBase;
while (bdec->mType == DT_TYPE_ARRAY)
bdec = bdec->mBase;
bdec = bdec->ToMutableType();
if (bdec->mType == DT_TYPE_STRUCT && bdec->mMoveConstructor)
{
Declaration* bpdec = bdec->BuildPointer(bdec->mLocation);
if (dec->mBase->mType == DT_TYPE_STRUCT)
{
Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX);
pexp->mLeft = lexp;
pexp->mToken = TK_BINARY_AND;
pexp->mDecType = bpdec;
Declaration* mdec = dec->mBase->mMoveConstructor;
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
cexp->mDecValue = mdec;
cexp->mDecType = cexp->mDecValue->mBase;
mexp = new Expression(mScanner->mLocation, EX_CALL);
mexp->mLeft = cexp;
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
mexp->mRight->mLeft = pexp;
mexp->mRight->mRight = rexp;
}
else
{
Expression* lpexp = new Expression(pthis->mLocation, EX_PREFIX);
lpexp->mLeft = lexp;
lpexp->mToken = TK_BINARY_AND;
lpexp->mDecType = bpdec;
Expression* rpexp = new Expression(pthis->mLocation, EX_PREFIX);
rpexp->mLeft = rexp;
rpexp->mToken = TK_BINARY_AND;
rpexp->mDecType = bpdec;
Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT);
cexp->mDecValue = bdec->mVectorMoveConstructor;
cexp->mDecType = cexp->mDecValue->mBase;
Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
ncdec->mBase = TheUnsignedIntTypeDeclaration;
ncdec->mInteger = dec->mSize / bdec->mSize;
mexp = new Expression(mScanner->mLocation, EX_CALL);
mexp->mLeft = cexp;
mexp->mRight = new Expression(mScanner->mLocation, EX_LIST);
mexp->mRight->mLeft = lpexp;
mexp->mRight->mRight = new Expression(mScanner->mLocation, EX_LIST);
mexp->mRight->mRight->mLeft = rpexp;
mexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT);
mexp->mRight->mRight->mRight->mDecType = ncdec->mBase;
mexp->mRight->mRight->mRight->mDecValue = ncdec;
}
}
else
{
mexp = new Expression(mScanner->mLocation, EX_INITIALIZATION);
mexp->mToken = TK_ASSIGN;
mexp->mLeft = lexp;
mexp->mRight = rexp;
mexp->mDecType = lexp->mDecType;
}
Declaration* mcdec = new Declaration(mScanner->mLocation, DT_CONST_CONSTRUCTOR);
mcdec->mIdent = mScanner->mTokenIdent;
mcdec->mValue = mexp;
cdec->mScope->Insert(dec->mIdent, mcdec);
}
dec = dec->mNext;
}
}
cdec->mFlags |= DTF_DEFINED;
}
#endif
} }
if (!simpleAssignment) if (!simpleAssignment)