Extend static stack allocation to zero page spilling
This commit is contained in:
parent
b356f726a4
commit
3351ee81cc
|
@ -2432,7 +2432,40 @@ L1: iny
|
||||||
|
|
||||||
__asm inp_copyl
|
__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)
|
#pragma bytecode(BC_COPY_LONG, inp_copyl)
|
||||||
|
|
|
@ -1209,7 +1209,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block->PutCode(generator, BC_COPY_LONG);
|
block->PutCode(generator, BC_COPY_LONG);
|
||||||
block->PutByte(uint8(mValue));
|
block->PutWord(uint16(mValue));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,8 @@ bool Compiler::GenerateCode(void)
|
||||||
else
|
else
|
||||||
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
|
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mGlobalAnalyzer->CheckInterrupt();
|
||||||
mGlobalAnalyzer->AutoInline();
|
mGlobalAnalyzer->AutoInline();
|
||||||
//mGlobalAnalyzer->DumpCallGraph();
|
//mGlobalAnalyzer->DumpCallGraph();
|
||||||
|
|
||||||
|
|
|
@ -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_ANALYZING = (1ULL << 35);
|
||||||
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
|
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
|
||||||
static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37);
|
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;
|
class Declaration;
|
||||||
|
|
|
@ -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)
|
void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
|
||||||
{
|
{
|
||||||
if (dec->mFlags & DTF_FUNC_ANALYZING)
|
if (dec->mFlags & DTF_FUNC_ANALYZING)
|
||||||
|
@ -198,6 +225,9 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
|
||||||
dec->mFlags |= DTF_ANALYZED;
|
dec->mFlags |= DTF_ANALYZED;
|
||||||
dec->mFlags |= DTF_FUNC_INTRSAVE;
|
dec->mFlags |= DTF_FUNC_INTRSAVE;
|
||||||
|
|
||||||
|
if (dec->mFlags & DTF_INTERRUPT)
|
||||||
|
dec->mFlags |= DTF_FUNC_INTRCALLED;
|
||||||
|
|
||||||
if ((dec->mFlags & DTF_INTRINSIC) && !dec->mValue)
|
if ((dec->mFlags & DTF_INTRINSIC) && !dec->mValue)
|
||||||
dec->mFlags |= DTF_FUNC_CONSTEXPR;
|
dec->mFlags |= DTF_FUNC_CONSTEXPR;
|
||||||
else if (dec->mFlags & DTF_DEFINED)
|
else if (dec->mFlags & DTF_DEFINED)
|
||||||
|
|
|
@ -13,6 +13,7 @@ public:
|
||||||
void DumpCallGraph(void);
|
void DumpCallGraph(void);
|
||||||
void AutoInline(void);
|
void AutoInline(void);
|
||||||
void CheckFastcall(Declaration* procDec);
|
void CheckFastcall(Declaration* procDec);
|
||||||
|
void CheckInterrupt(void);
|
||||||
|
|
||||||
void AnalyzeProcedure(Expression* exp, Declaration* procDec);
|
void AnalyzeProcedure(Expression* exp, Declaration* procDec);
|
||||||
void AnalyzeAssembler(Expression* exp, Declaration* procDec);
|
void AnalyzeAssembler(Expression* exp, Declaration* procDec);
|
||||||
|
|
|
@ -10166,7 +10166,8 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
||||||
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
||||||
mIdent(ident), mLinkerObject(linkerObject),
|
mIdent(ident), mLinkerObject(linkerObject),
|
||||||
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
|
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();
|
mID = mModule->mProcedures.Size();
|
||||||
mModule->mProcedures.Push(this);
|
mModule->mProcedures.Push(this);
|
||||||
|
@ -11018,7 +11019,7 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->CheckStaticStack())
|
if (!mInterruptCalled && mEntryBlock->CheckStaticStack())
|
||||||
{
|
{
|
||||||
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
|
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
|
||||||
mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent, LST_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();
|
ResetVisited();
|
||||||
mEntryBlock->CollectStaticStack(mLinkerObject, mLocalVars);
|
mEntryBlock->CollectStaticStack(mLinkerObject, mLocalVars);
|
||||||
}
|
}
|
||||||
|
@ -11069,6 +11072,8 @@ void InterCodeProcedure::Close(void)
|
||||||
BuildTraces(false, false);
|
BuildTraces(false, false);
|
||||||
DisassembleDebug("Final Merged basic blocks");
|
DisassembleDebug("Final Merged basic blocks");
|
||||||
|
|
||||||
|
if (mSaveTempsLinkerObject && mTempSize > 16)
|
||||||
|
mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
|
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
|
||||||
|
|
|
@ -499,7 +499,8 @@ public:
|
||||||
GrowingTypeArray mTemporaries;
|
GrowingTypeArray mTemporaries;
|
||||||
GrowingIntArray mTempOffset, mTempSizes;
|
GrowingIntArray mTempOffset, mTempSizes;
|
||||||
int mTempSize, mCommonFrameSize, mCallerSavedTemps;
|
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;
|
GrowingInterCodeProcedurePtrArray mCalledFunctions;
|
||||||
|
|
||||||
InterCodeModule * mModule;
|
InterCodeModule * mModule;
|
||||||
|
@ -511,7 +512,7 @@ public:
|
||||||
Location mLocation;
|
Location mLocation;
|
||||||
const Ident * mIdent, * mSection;
|
const Ident * mIdent, * mSection;
|
||||||
|
|
||||||
LinkerObject * mLinkerObject;
|
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
|
||||||
|
|
||||||
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
||||||
~InterCodeProcedure(void);
|
~InterCodeProcedure(void);
|
||||||
|
|
|
@ -3544,6 +3544,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
if (dec->mFlags & DTF_HWINTERRUPT)
|
if (dec->mFlags & DTF_HWINTERRUPT)
|
||||||
proc->mHardwareInterrupt = true;
|
proc->mHardwareInterrupt = true;
|
||||||
|
|
||||||
|
if (dec->mFlags & DTF_FUNC_INTRCALLED)
|
||||||
|
proc->mInterruptCalled = true;
|
||||||
|
|
||||||
if (dec->mBase->mFlags & DTF_FASTCALL)
|
if (dec->mBase->mFlags & DTF_FASTCALL)
|
||||||
{
|
{
|
||||||
proc->mFastCallProcedure = true;
|
proc->mFastCallProcedure = true;
|
||||||
|
|
|
@ -5719,6 +5719,10 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
||||||
int size = ins->mConst.mOperandSize;
|
int size = ins->mConst.mOperandSize;
|
||||||
int msize = 4;
|
int msize = 4;
|
||||||
|
|
||||||
|
uint32 flags = NCIF_LOWER | NCIF_UPPER;
|
||||||
|
if (ins->mVolatile)
|
||||||
|
flags |= NCIF_VOLATILE;
|
||||||
|
|
||||||
if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
|
if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
|
||||||
msize = 8;
|
msize = 8;
|
||||||
else if (nproc->mGenerator->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE)
|
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++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 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_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + i, ins->mSrc[0].mLinkerObject, flags));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -5751,8 +5755,8 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
|
||||||
this->Close(lblock, nullptr, ASMIT_JMP);
|
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_LDA, ASMIM_ABSOLUTE_Y, ins->mSrc[0].mIntConst - index, ins->mSrc[0].mLinkerObject, flags));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg));
|
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_INY, ASMIM_IMPLIED));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, (index + size) & 255));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, (index + size) & 255));
|
||||||
lblock->Close(lblock, eblock, ASMIT_BNE);
|
lblock->Close(lblock, eblock, ASMIT_BNE);
|
||||||
|
@ -5760,6 +5764,95 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
||||||
return eblock;
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -5903,32 +5996,67 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
else
|
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* lblock = nproc->AllocateBlock();
|
||||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||||
|
|
||||||
if (size < 128)
|
if (size < 128)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
|
block->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
|
||||||
this->Close(lblock, nullptr, ASMIT_JMP);
|
block->Close(lblock, nullptr, ASMIT_JMP);
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
lblock->Close(lblock, eblock, ASMIT_BPL);
|
lblock->Close(lblock, eblock, ASMIT_BPL);
|
||||||
}
|
}
|
||||||
else if (size <= 256)
|
else if (size <= 256)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
|
block->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
|
||||||
this->Close(lblock, nullptr, ASMIT_JMP);
|
block->Close(lblock, nullptr, ASMIT_JMP);
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
lblock->Close(lblock, eblock, ASMIT_BNE);
|
lblock->Close(lblock, eblock, ASMIT_BNE);
|
||||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
|
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg, nullptr, flags));
|
||||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
|
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)
|
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
@ -23238,7 +23414,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
mIndex = proc->mID;
|
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;
|
int commonFrameSize = proc->mCommonFrameSize;
|
||||||
|
|
||||||
mStackExpand = tempSave + proc->mLocalSize;
|
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));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
ignoreExpandCommonFrame = true;
|
ignoreExpandCommonFrame = true;
|
||||||
|
|
||||||
if (tempSave)
|
if (proc->mSaveTempsLinkerObject)
|
||||||
|
SaveTempsToStack(tempSave);
|
||||||
|
else if (tempSave)
|
||||||
{
|
{
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||||
if (tempSave == 1)
|
if (tempSave == 1)
|
||||||
|
@ -23413,6 +23591,8 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (proc->mSaveTempsLinkerObject)
|
||||||
|
SaveTempsToStack(tempSave);
|
||||||
}
|
}
|
||||||
else
|
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_SBC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
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_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
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_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
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));
|
||||||
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 (mStackExpand > 0)
|
||||||
{
|
{
|
||||||
if (tempSave)
|
if (proc->mSaveTempsLinkerObject)
|
||||||
|
LoadTempsFromStack(tempSave);
|
||||||
|
else if (tempSave)
|
||||||
{
|
{
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||||
if (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_BCC, ASMIM_RELATIVE, 2));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
}
|
}
|
||||||
|
else if (proc->mSaveTempsLinkerObject)
|
||||||
|
LoadTempsFromStack(tempSave);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
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_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
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_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
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));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
|
|
@ -390,6 +390,8 @@ class NativeCodeProcedure
|
||||||
void ResetVisited(void);
|
void ResetVisited(void);
|
||||||
void ResetPatched(void);
|
void ResetPatched(void);
|
||||||
|
|
||||||
|
void SaveTempsToStack(int tempSave);
|
||||||
|
void LoadTempsFromStack(int tempSave);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeGenerator
|
class NativeCodeGenerator
|
||||||
|
|
Loading…
Reference in New Issue