Extend static stack allocation to zero page spilling

This commit is contained in:
drmortalwombat 2022-05-22 13:22:36 +02:00
parent b356f726a4
commit 3351ee81cc
11 changed files with 311 additions and 38 deletions

View File

@ -2432,7 +2432,40 @@ L1: iny
__asm inp_copyl
{
jmp startup.exec
lda (ip), y
sta tmp
iny
lda (ip), y
tax
sty tmpy
beq W1
ldy #0
Loop1:
lda (accu), y
sta (addr), y
iny
bne Loop1
inc accu + 1
inc addr + 1
dex
bne Loop1
W1:
ldy tmp
beq W2
dey
beq W3
Loop2:
lda (accu), y
sta (addr), y
dey
bne Loop2
W3:
lda (accu), y
sta (addr), y
W2:
ldy tmpy
jmp startup.yexec
}
#pragma bytecode(BC_COPY_LONG, inp_copyl)

View File

@ -1209,7 +1209,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
else
{
block->PutCode(generator, BC_COPY_LONG);
block->PutByte(uint8(mValue));
block->PutWord(uint16(mValue));
}
break;

View File

@ -232,6 +232,8 @@ bool Compiler::GenerateCode(void)
else
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
}
mGlobalAnalyzer->CheckInterrupt();
mGlobalAnalyzer->AutoInline();
//mGlobalAnalyzer->DumpCallGraph();

View File

@ -79,8 +79,9 @@ static const uint64 DTF_FUNC_RECURSIVE = (1ULL << 34);
static const uint64 DTF_FUNC_ANALYZING = (1ULL << 35);
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37);
static const uint64 DTF_FUNC_INTRCALLED = (1ULL << 38);
static const uint64 DTF_VAR_ALIASING = (1ULL << 37);
static const uint64 DTF_VAR_ALIASING = (1ULL << 39);
class Declaration;

View File

@ -181,6 +181,33 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec)
}
}
void GlobalAnalyzer::CheckInterrupt(void)
{
bool changed = false;
do
{
changed = false;
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* f = mFunctions[i];
if (f->mFlags & DTF_FUNC_INTRCALLED)
{
for (int j = 0; j < f->mCalled.Size(); j++)
{
Declaration* cf = f->mCalled[j];
if (!(cf->mFlags & DTF_FUNC_INTRCALLED))
{
cf->mFlags |= DTF_FUNC_INTRCALLED;
changed = true;
}
}
}
}
} while (changed);
}
void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
{
if (dec->mFlags & DTF_FUNC_ANALYZING)
@ -198,6 +225,9 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
dec->mFlags |= DTF_ANALYZED;
dec->mFlags |= DTF_FUNC_INTRSAVE;
if (dec->mFlags & DTF_INTERRUPT)
dec->mFlags |= DTF_FUNC_INTRCALLED;
if ((dec->mFlags & DTF_INTRINSIC) && !dec->mValue)
dec->mFlags |= DTF_FUNC_CONSTEXPR;
else if (dec->mFlags & DTF_DEFINED)

View File

@ -13,6 +13,7 @@ public:
void DumpCallGraph(void);
void AutoInline(void);
void CheckFastcall(Declaration* procDec);
void CheckInterrupt(void);
void AnalyzeProcedure(Expression* exp, Declaration* procDec);
void AnalyzeAssembler(Expression* exp, Declaration* procDec);

View File

@ -10166,7 +10166,8 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
mIdent(ident), mLinkerObject(linkerObject),
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false)
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false),
mSaveTempsLinkerObject(nullptr)
{
mID = mModule->mProcedures.Size();
mModule->mProcedures.Push(this);
@ -11018,7 +11019,7 @@ void InterCodeProcedure::Close(void)
#if 1
ResetVisited();
if (mEntryBlock->CheckStaticStack())
if (!mInterruptCalled && mEntryBlock->CheckStaticStack())
{
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent, LST_STATIC_STACK);
@ -11035,6 +11036,8 @@ void InterCodeProcedure::Close(void)
}
}
mSaveTempsLinkerObject = mModule->mLinker->AddObject(mLocation, mIdent, mLinkerObject->mStackSection, LOT_BSS);
ResetVisited();
mEntryBlock->CollectStaticStack(mLinkerObject, mLocalVars);
}
@ -11069,6 +11072,8 @@ void InterCodeProcedure::Close(void)
BuildTraces(false, false);
DisassembleDebug("Final Merged basic blocks");
if (mSaveTempsLinkerObject && mTempSize > 16)
mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
}
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)

View File

@ -499,7 +499,8 @@ public:
GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure, mInterrupt, mHardwareInterrupt, mCompiled;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled;
GrowingInterCodeProcedurePtrArray mCalledFunctions;
InterCodeModule * mModule;
@ -511,7 +512,7 @@ public:
Location mLocation;
const Ident * mIdent, * mSection;
LinkerObject * mLinkerObject;
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
~InterCodeProcedure(void);

View File

@ -3544,6 +3544,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
if (dec->mFlags & DTF_HWINTERRUPT)
proc->mHardwareInterrupt = true;
if (dec->mFlags & DTF_FUNC_INTRCALLED)
proc->mInterruptCalled = true;
if (dec->mBase->mFlags & DTF_FASTCALL)
{
proc->mFastCallProcedure = true;

View File

@ -5719,6 +5719,10 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
int size = ins->mConst.mOperandSize;
int msize = 4;
uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile)
flags |= NCIF_VOLATILE;
if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
msize = 8;
else if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE)
@ -5738,8 +5742,8 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
for (int i = 0; i < size; i++)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + i, ins->mSrc[0].mLinkerObject));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + i, ins->mSrc[0].mLinkerObject, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
}
return this;
@ -5751,8 +5755,8 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst - index, ins->mSrc[0].mLinkerObject));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst - index, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, (index + size) & 255));
lblock->Close(lblock, eblock, ASMIT_BNE);
@ -5760,6 +5764,95 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
return eblock;
}
}
else if ((ins->mSrc[0].mMemory == IM_GLOBAL || ins->mSrc[0].mMemory == IM_ABSOLUTE) && (ins->mSrc[1].mMemory == IM_GLOBAL || ins->mSrc[1].mMemory == IM_ABSOLUTE))
{
NativeCodeBasicBlock* block = this;
int offset = 0;
if (size >= 256)
{
block = nproc->AllocateBlock();
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
if (size > 256)
{
if (size < 512 && !(size & 1))
{
int step = size >> 1;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, step));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + step - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
lblock->Close(lblock, block, ASMIT_BNE);
return block;
}
else if (size < 1024 && !(size & 3))
{
int step = size >> 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, step));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + step - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + 2 * step - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 2 * step - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + 3 * step - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 3 * step - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
lblock->Close(lblock, block, ASMIT_BNE);
return block;
}
}
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
this->Close(lblock, nullptr, ASMIT_JMP);
while (offset + 255 < size)
{
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + offset, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset, ins->mSrc[1].mLinkerObject, flags));
offset += 256;
}
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
lblock->Close(lblock, block, ASMIT_BNE);
size &= 255;
}
if (size <= msize)
{
for (int i = 0; i < size; i++)
{
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + offset + i, ins->mSrc[0].mLinkerObject, flags));
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + offset + i, ins->mSrc[1].mLinkerObject, flags));
}
}
else
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
block->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size));
block->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst + offset - 1, ins->mSrc[0].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset - 1, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
lblock->Close(lblock, eblock, ASMIT_BNE);
block = eblock;
}
return block;
}
}
#endif
@ -5903,32 +5996,67 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
return this;
}
else
{
NativeCodeBasicBlock* block = this;
if (size >= 256)
{
block = nproc->AllocateBlock();
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* lblock2 = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
if (size >= 512)
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, size >> 8));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
lblock->Close(lblock, lblock2, ASMIT_BNE);
lblock2->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, sreg + 1));
lblock2->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1));
if (size >= 512)
{
lblock2->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
lblock2->Close(lblock, block, ASMIT_BNE);
}
else
lblock2->Close(block, nullptr, ASMIT_JMP);
size &= 0xff;
}
if (size > 0)
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
if (size < 128)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
block->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
block->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
lblock->Close(lblock, eblock, ASMIT_BPL);
}
else if (size <= 256)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
this->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
block->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
block->Close(lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
lblock->Close(lblock, eblock, ASMIT_BNE);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
}
return eblock;
block = eblock;
}
return block;
}
}
@ -23227,6 +23355,54 @@ void NativeCodeProcedure::CompressTemporaries(void)
}
}
void NativeCodeProcedure::SaveTempsToStack(int tempSave)
{
if (mInterProc->mSaveTempsLinkerObject)
{
assert(tempSave <= mInterProc->mSaveTempsLinkerObject->mSize);
if (tempSave > 3)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_X, 0, mInterProc->mSaveTempsLinkerObject));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
}
else if (tempSave > 0)
{
for (int i = 0; i < tempSave; i++)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + i));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, i, mInterProc->mSaveTempsLinkerObject));
}
}
}
}
void NativeCodeProcedure::LoadTempsFromStack(int tempSave)
{
if (mInterProc->mSaveTempsLinkerObject)
{
if (tempSave > 3)
{
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, 0, mInterProc->mSaveTempsLinkerObject));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
}
else if (tempSave > 0)
{
for (int i = 0; i < tempSave; i++)
{
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, i, mInterProc->mSaveTempsLinkerObject));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + i));
}
}
}
}
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
@ -23238,7 +23414,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mIndex = proc->mID;
int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
int tempSave = proc->mTempSize > 16 && !proc->mSaveTempsLinkerObject ? proc->mTempSize - 16 : 0;
int commonFrameSize = proc->mCommonFrameSize;
mStackExpand = tempSave + proc->mLocalSize;
@ -23378,7 +23554,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
ignoreExpandCommonFrame = true;
if (tempSave)
if (proc->mSaveTempsLinkerObject)
SaveTempsToStack(tempSave);
else if (tempSave)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
if (tempSave == 1)
@ -23413,6 +23591,8 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
}
}
}
else if (proc->mSaveTempsLinkerObject)
SaveTempsToStack(tempSave);
}
else
{
@ -23424,6 +23604,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
if (proc->mSaveTempsLinkerObject)
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
else
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
@ -23431,7 +23614,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
if (tempSave)
if (proc->mSaveTempsLinkerObject)
SaveTempsToStack(tempSave);
else if (tempSave)
{
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
@ -23493,7 +23678,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
if (mStackExpand > 0)
{
if (tempSave)
if (proc->mSaveTempsLinkerObject)
LoadTempsFromStack(tempSave);
else if (tempSave)
{
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
if (tempSave == 1)
@ -23535,9 +23722,15 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
}
else if (proc->mSaveTempsLinkerObject)
LoadTempsFromStack(tempSave);
}
else
{
if (proc->mSaveTempsLinkerObject)
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
else
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
@ -23545,7 +23738,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
if (tempSave)
if (proc->mSaveTempsLinkerObject)
LoadTempsFromStack(tempSave);
else if (tempSave)
{
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));

View File

@ -390,6 +390,8 @@ class NativeCodeProcedure
void ResetVisited(void);
void ResetPatched(void);
void SaveTempsToStack(int tempSave);
void LoadTempsFromStack(int tempSave);
};
class NativeCodeGenerator