Reduce register spilling on function entry/exit
This commit is contained in:
parent
e057e24918
commit
42e4f483c1
|
@ -1,4 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
int asum(int a, int b)
|
int asum(int a, int b)
|
||||||
{
|
{
|
||||||
|
@ -30,11 +31,46 @@ int bsum(int a, int b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int b, t[10];
|
||||||
|
|
||||||
|
int bsome(int x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int qsum(int a, int (* c)(int))
|
||||||
|
{
|
||||||
|
char n = 0;
|
||||||
|
b = 0;
|
||||||
|
for(int i=0; i<a; i++)
|
||||||
|
{
|
||||||
|
int j = c((char)i);
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
clc
|
||||||
|
lda j
|
||||||
|
adc b
|
||||||
|
sta b
|
||||||
|
lda j + 1
|
||||||
|
adc b + 1
|
||||||
|
sta b + 1
|
||||||
|
}
|
||||||
|
t[n] += i;
|
||||||
|
n = (n + 1) & 7;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int x = asum(7007, 8008);
|
int x = asum(7007, 8008);
|
||||||
int y = bsum(4004, 9009);
|
int y = bsum(4004, 9009);
|
||||||
|
|
||||||
return (x == 7007 + 8008 && y == 4004 + 9009) ? 0 : -1;
|
assert(x == 7007 + 8008 && y == 4004 + 9009);
|
||||||
|
assert(qsum(10, bsome) == 45);
|
||||||
|
assert(qsum(200, bsome) == 19900);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,7 @@ bool Compiler::GenerateCode(void)
|
||||||
mGlobalAnalyzer->DumpCallGraph();
|
mGlobalAnalyzer->DumpCallGraph();
|
||||||
|
|
||||||
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
|
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
|
||||||
|
mNativeCodeGenerator->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
|
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
|
||||||
|
|
||||||
|
|
|
@ -2334,6 +2334,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
vins->mConst.mOperandSize = vdec->mSize;
|
vins->mConst.mOperandSize = vdec->mSize;
|
||||||
vins->mConst.mIntConst = vdec->mOffset;
|
vins->mConst.mIntConst = vdec->mOffset;
|
||||||
}
|
}
|
||||||
|
else if (vdec->mType == DT_VARIABLE)
|
||||||
|
{
|
||||||
|
vins->mConst.mMemory = IM_LOCAL;
|
||||||
|
vins->mConst.mVarIndex = vdec->mVarIndex;
|
||||||
|
vins->mConst.mOperandSize = vdec->mSize;
|
||||||
|
vins->mConst.mIntConst = vdec->mOffset;
|
||||||
|
}
|
||||||
|
|
||||||
block->Append(vins);
|
block->Append(vins);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "NativeCodeGenerator.h"
|
#include "NativeCodeGenerator.h"
|
||||||
|
#include "CompilerTypes.h"
|
||||||
|
|
||||||
static const int CPU_REG_A = 256;
|
static const int CPU_REG_A = 256;
|
||||||
static const int CPU_REG_X = 257;
|
static const int CPU_REG_X = 257;
|
||||||
|
@ -6791,7 +6792,9 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void)
|
||||||
{
|
{
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this)
|
if (!mLocked)
|
||||||
|
{
|
||||||
|
while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this && !mTrueJump->mLocked)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mTrueJump->mIns.Size(); i++)
|
for (int i = 0; i < mTrueJump->mIns.Size(); i++)
|
||||||
mIns.Push(mTrueJump->mIns[i]);
|
mIns.Push(mTrueJump->mIns[i]);
|
||||||
|
@ -6800,6 +6803,7 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void)
|
||||||
mTrueJump = mTrueJump->mTrueJump;
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mTrueJump)
|
if (mTrueJump)
|
||||||
mTrueJump->MergeBasicBlocks();
|
mTrueJump->MergeBasicBlocks();
|
||||||
|
@ -6909,6 +6913,80 @@ bool NativeCodeBasicBlock::ApplyEntryDataSet(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
switch (mIns[i].mMode)
|
||||||
|
{
|
||||||
|
case ASMIM_ZERO_PAGE:
|
||||||
|
used += mIns[i].mAddress;
|
||||||
|
break;
|
||||||
|
case ASMIM_INDIRECT_Y:
|
||||||
|
used += mIns[i].mAddress + 0;
|
||||||
|
used += mIns[i].mAddress + 1;
|
||||||
|
break;
|
||||||
|
case ASMIM_ABSOLUTE:
|
||||||
|
if (mIns[i].mType == ASMIT_JSR && mIns[i].mLinkerObject)
|
||||||
|
{
|
||||||
|
LinkerObject* lo = mIns[i].mLinkerObject;
|
||||||
|
|
||||||
|
for (int i = 0; i < lo->mNumTemporaries; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < lo->mTempSizes[i]; j++)
|
||||||
|
used += lo->mTemporaries[i] + j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->CollectZeroPageUsage(used);
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->CollectZeroPageUsage(used);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeCodeBasicBlock::RemapZeroPage(const uint8* remap)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
switch (mIns[i].mMode)
|
||||||
|
{
|
||||||
|
case ASMIM_ZERO_PAGE:
|
||||||
|
case ASMIM_INDIRECT_Y:
|
||||||
|
mIns[i].mAddress = remap[mIns[i].mAddress];
|
||||||
|
break;
|
||||||
|
case ASMIM_ABSOLUTE:
|
||||||
|
if (mIns[i].mType == ASMIT_JSR && mIns[i].mLinkerObject)
|
||||||
|
{
|
||||||
|
LinkerObject* lo = mIns[i].mLinkerObject;
|
||||||
|
|
||||||
|
for (int j = 0; j < lo->mNumTemporaries; j++)
|
||||||
|
{
|
||||||
|
lo->mTemporaries[j] = remap[lo->mTemporaries[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->RemapZeroPage(remap);
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->RemapZeroPage(remap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const
|
bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const
|
||||||
{
|
{
|
||||||
if (mIns.Size() > 0)
|
if (mIns.Size() > 0)
|
||||||
|
@ -8765,6 +8843,7 @@ NativeCodeBasicBlock::NativeCodeBasicBlock(void)
|
||||||
mKnownShortBranch = false;
|
mKnownShortBranch = false;
|
||||||
mBypassed = false;
|
mBypassed = false;
|
||||||
mAssembled = false;
|
mAssembled = false;
|
||||||
|
mLocked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeCodeBasicBlock::~NativeCodeBasicBlock(void)
|
NativeCodeBasicBlock::~NativeCodeBasicBlock(void)
|
||||||
|
@ -8783,8 +8862,62 @@ NativeCodeProcedure::~NativeCodeProcedure(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeCodeProcedure::CompressTemporaries(void)
|
||||||
|
{
|
||||||
|
if (mInterProc->mTempSize > 16)
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
|
||||||
|
NumberSet used(256);
|
||||||
|
|
||||||
|
mEntryBlock->CollectZeroPageUsage(used);
|
||||||
|
|
||||||
|
uint8 remap[256];
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
remap[i] = i;
|
||||||
|
|
||||||
|
int tpos = BC_REG_TMP_SAVED;
|
||||||
|
for (int i = 0; i < mInterProc->mTempOffset.Size(); i++)
|
||||||
|
{
|
||||||
|
bool tused = false;
|
||||||
|
|
||||||
|
int reg = BC_REG_TMP + mInterProc->mTempOffset[i];
|
||||||
|
if (reg >= BC_REG_TMP_SAVED)
|
||||||
|
{
|
||||||
|
int size = mInterProc->mTempSizes[i];
|
||||||
|
|
||||||
|
for (int j = 0; j < size; j++)
|
||||||
|
if (used[reg + j])
|
||||||
|
tused = true;
|
||||||
|
|
||||||
|
if (tused)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < size; j++)
|
||||||
|
remap[reg + j] = tpos + j;
|
||||||
|
|
||||||
|
mInterProc->mTempOffset[i] = tpos - BC_REG_TMP;
|
||||||
|
tpos += size;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInterProc->mTempOffset[i] = 0;
|
||||||
|
mInterProc->mTempSizes[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->RemapZeroPage(remap);
|
||||||
|
|
||||||
|
mInterProc->mTempSize = tpos - BC_REG_TMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
|
mInterProc = proc;
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
for (int i = 0; i < nblocks; i++)
|
for (int i = 0; i < nblocks; i++)
|
||||||
|
@ -8800,122 +8933,145 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
commonFrameSize += 2;
|
commonFrameSize += 2;
|
||||||
|
|
||||||
mFrameOffset = 0;
|
mFrameOffset = 0;
|
||||||
mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !proc->mHasDynamicStack && !(proc->mHasInlineAssembler && !proc->mLeafProcedure);
|
mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !proc->mHasDynamicStack;// && !(proc->mHasInlineAssembler && !proc->mLeafProcedure);
|
||||||
|
|
||||||
if (mNoFrame)
|
if (mNoFrame)
|
||||||
proc->mLinkerObject->mFlags |= LOBJF_NO_FRAME;
|
proc->mLinkerObject->mFlags |= LOBJF_NO_FRAME;
|
||||||
|
|
||||||
entryBlock = new NativeCodeBasicBlock();
|
if (mNoFrame)
|
||||||
mBlocks.Push(entryBlock);
|
{
|
||||||
entryBlock->mNoFrame = mNoFrame;
|
if (stackExpand > 0)
|
||||||
entryBlock->mIndex = 0;
|
mFrameOffset = tempSave;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stackExpand += 2;
|
||||||
|
}
|
||||||
|
|
||||||
// generator->mByteCodeUsed[BC_NATIVE] = true;
|
if (!proc->mLeafProcedure)
|
||||||
|
{
|
||||||
|
if (mNoFrame)
|
||||||
|
mFrameOffset = commonFrameSize + tempSave;
|
||||||
|
}
|
||||||
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
mEntryBlock = AllocateBlock();
|
||||||
|
mEntryBlock->mLocked = true;
|
||||||
|
mBlocks.Push(mEntryBlock);
|
||||||
|
|
||||||
|
mExitBlock = AllocateBlock();
|
||||||
|
mExitBlock->mLocked = true;
|
||||||
|
mBlocks.Push(mExitBlock);
|
||||||
|
|
||||||
|
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
|
||||||
|
mEntryBlock->mBranch = ASMIT_JMP;
|
||||||
|
|
||||||
|
// Place a temporary RTS
|
||||||
|
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
||||||
|
|
||||||
|
Optimize();
|
||||||
|
|
||||||
|
assert(mEntryBlock->mIns.Size() == 0);
|
||||||
|
|
||||||
|
// Remove temporary RTS
|
||||||
|
|
||||||
|
mExitBlock->mIns.Pop();
|
||||||
|
|
||||||
|
CompressTemporaries();
|
||||||
|
|
||||||
|
tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
|
||||||
|
|
||||||
|
if (!(mGenerator->mCompilerOptions & COPT_NATIVE))
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
||||||
|
|
||||||
if (mNoFrame)
|
if (mNoFrame)
|
||||||
{
|
{
|
||||||
if (stackExpand > 0)
|
if (stackExpand > 0)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
||||||
entryBlock->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 (tempSave)
|
if (tempSave)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
entryBlock->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 > 1)
|
if (tempSave > 1)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mFrameOffset = tempSave;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stackExpand += 2;
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
|
||||||
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
|
||||||
|
|
||||||
if (tempSave)
|
if (tempSave)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
entryBlock->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 > 1)
|
if (tempSave > 1)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proc->mLeafProcedure)
|
if (!proc->mLeafProcedure)
|
||||||
{
|
{
|
||||||
if (commonFrameSize > 0)
|
if (commonFrameSize > 0)
|
||||||
{
|
{
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||||
entryBlock->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 (mNoFrame)
|
|
||||||
mFrameOffset = commonFrameSize + tempSave;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entryBlock->mFrameOffset = mFrameOffset;
|
|
||||||
|
|
||||||
tblocks[0] = entryBlock;
|
|
||||||
|
|
||||||
exitBlock = AllocateBlock();
|
|
||||||
mBlocks.Push(exitBlock);
|
|
||||||
|
|
||||||
if (!proc->mLeafProcedure && commonFrameSize > 0)
|
if (!proc->mLeafProcedure && commonFrameSize > 0)
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNoFrame)
|
if (mNoFrame)
|
||||||
|
@ -8924,63 +9080,85 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
if (tempSave)
|
if (tempSave)
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
||||||
|
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
if (tempSave > 1)
|
if (tempSave > 1)
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
exitBlock->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 (tempSave)
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
if (tempSave > 1)
|
if (tempSave > 1)
|
||||||
{
|
{
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff));
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
||||||
|
|
||||||
CompileInterBlock(proc, proc->mBlocks[0], entryBlock);
|
mEntryBlock->Assemble();
|
||||||
|
|
||||||
|
int total, base;
|
||||||
|
|
||||||
|
NativeCodeBasicBlock* lentryBlock = mEntryBlock->BypassEmptyBlocks();
|
||||||
|
|
||||||
|
total = 0;
|
||||||
|
lentryBlock->CalculateOffset(total);
|
||||||
|
|
||||||
|
proc->mLinkerObject->mType = LOT_NATIVE_CODE;
|
||||||
|
lentryBlock->CopyCode(this, proc->mLinkerObject->AddSpace(total));
|
||||||
|
|
||||||
|
for (int i = 0; i < mRelocations.Size(); i++)
|
||||||
|
{
|
||||||
|
LinkerReference& rl(mRelocations[i]);
|
||||||
|
rl.mObject = proc->mLinkerObject;
|
||||||
|
if (!rl.mRefObject)
|
||||||
|
rl.mRefObject = proc->mLinkerObject;
|
||||||
|
proc->mLinkerObject->AddReference(rl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeCodeProcedure::Optimize(void)
|
||||||
|
{
|
||||||
#if 1
|
#if 1
|
||||||
int step = 0;
|
int step = 0;
|
||||||
|
|
||||||
|
@ -8997,52 +9175,52 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mBlocks[i]->mLoopHead = false;
|
mBlocks[i]->mLoopHead = false;
|
||||||
mBlocks[i]->mFromJump = nullptr;
|
mBlocks[i]->mFromJump = nullptr;
|
||||||
}
|
}
|
||||||
entryBlock->CountEntries(nullptr);
|
mEntryBlock->CountEntries(nullptr);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
changed = entryBlock->RemoveUnusedResultInstructions();
|
changed = mEntryBlock->RemoveUnusedResultInstructions();
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
NativeRegisterDataSet data;
|
NativeRegisterDataSet data;
|
||||||
if (entryBlock->ValueForwarding(data))
|
if (mEntryBlock->ValueForwarding(data))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
#endif
|
#endif
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (entryBlock->PeepHoleOptimizer())
|
if (mEntryBlock->PeepHoleOptimizer())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (entryBlock->OptimizeSimpleLoop(this))
|
if (mEntryBlock->OptimizeSimpleLoop(this))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (entryBlock->MergeBasicBlocks())
|
if (mEntryBlock->MergeBasicBlocks())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
for (int i = 0; i < mBlocks.Size(); i++)
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
mBlocks[i]->mEntryBlocks.SetSize(0);
|
mBlocks[i]->mEntryBlocks.SetSize(0);
|
||||||
entryBlock->CollectEntryBlocks(nullptr);
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
|
||||||
if (step > 2)
|
if (step > 2)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (entryBlock->JoinTailCodeSequences())
|
if (mEntryBlock->JoinTailCodeSequences())
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
NativeRegisterDataSet data;
|
NativeRegisterDataSet data;
|
||||||
entryBlock->BuildEntryDataSet(data);
|
mEntryBlock->BuildEntryDataSet(data);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (entryBlock->ApplyEntryDataSet())
|
if (mEntryBlock->ApplyEntryDataSet())
|
||||||
changed = true;
|
changed = true;
|
||||||
#endif
|
#endif
|
||||||
if (!changed && step < 4)
|
if (!changed && step < 4)
|
||||||
|
@ -9053,27 +9231,6 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
entryBlock->Assemble();
|
|
||||||
|
|
||||||
int total, base;
|
|
||||||
|
|
||||||
NativeCodeBasicBlock* lentryBlock = entryBlock->BypassEmptyBlocks();
|
|
||||||
|
|
||||||
total = 0;
|
|
||||||
lentryBlock->CalculateOffset(total);
|
|
||||||
|
|
||||||
proc->mLinkerObject->mType = LOT_NATIVE_CODE;
|
|
||||||
lentryBlock->CopyCode(this, proc->mLinkerObject->AddSpace(total));
|
|
||||||
|
|
||||||
for (int i = 0; i < mRelocations.Size(); i++)
|
|
||||||
{
|
|
||||||
LinkerReference& rl(mRelocations[i]);
|
|
||||||
rl.mObject = proc->mLinkerObject;
|
|
||||||
if (!rl.mRefObject)
|
|
||||||
rl.mRefObject = proc->mLinkerObject;
|
|
||||||
proc->mLinkerObject->AddReference(rl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeCodeProcedure::BuildDataFlowSets(void)
|
void NativeCodeProcedure::BuildDataFlowSets(void)
|
||||||
|
@ -9397,12 +9554,12 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block->Close(exitBlock, nullptr, ASMIT_JMP);
|
block->Close(mExitBlock, nullptr, ASMIT_JMP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IC_RETURN:
|
case IC_RETURN:
|
||||||
block->Close(exitBlock, nullptr, ASMIT_JMP);
|
block->Close(mExitBlock, nullptr, ASMIT_JMP);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case IC_TYPECAST:
|
case IC_TYPECAST:
|
||||||
|
@ -9443,7 +9600,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
|
|
||||||
|
|
||||||
NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker)
|
NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker)
|
||||||
: mErrors(errors), mLinker(linker), mRuntime({ 0 })
|
: mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT), mRuntime({ 0 })
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
GrowingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
||||||
|
|
||||||
int mOffset, mSize, mNumEntries, mNumEntered, mFrameOffset;
|
int mOffset, mSize, mNumEntries, mNumEntered, mFrameOffset;
|
||||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting;
|
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked;
|
||||||
|
|
||||||
NativeRegisterDataSet mDataSet, mNDataSet;
|
NativeRegisterDataSet mDataSet, mNDataSet;
|
||||||
|
|
||||||
|
@ -183,6 +183,9 @@ public:
|
||||||
|
|
||||||
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
||||||
bool ApplyEntryDataSet(void);
|
bool ApplyEntryDataSet(void);
|
||||||
|
|
||||||
|
void CollectZeroPageUsage(NumberSet& used);
|
||||||
|
void RemapZeroPage(const uint8* remap);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
@ -191,11 +194,13 @@ class NativeCodeProcedure
|
||||||
NativeCodeProcedure(NativeCodeGenerator* generator);
|
NativeCodeProcedure(NativeCodeGenerator* generator);
|
||||||
~NativeCodeProcedure(void);
|
~NativeCodeProcedure(void);
|
||||||
|
|
||||||
NativeCodeBasicBlock* entryBlock, * exitBlock;
|
NativeCodeBasicBlock* mEntryBlock, * mExitBlock;
|
||||||
NativeCodeBasicBlock** tblocks;
|
NativeCodeBasicBlock** tblocks;
|
||||||
|
|
||||||
NativeCodeGenerator* mGenerator;
|
NativeCodeGenerator* mGenerator;
|
||||||
|
|
||||||
|
InterCodeProcedure* mInterProc;
|
||||||
|
|
||||||
int mProgStart, mProgSize, mIndex, mFrameOffset;
|
int mProgStart, mProgSize, mIndex, mFrameOffset;
|
||||||
bool mNoFrame;
|
bool mNoFrame;
|
||||||
int mTempBlocks;
|
int mTempBlocks;
|
||||||
|
@ -204,12 +209,15 @@ class NativeCodeProcedure
|
||||||
GrowingArray < NativeCodeBasicBlock*> mBlocks;
|
GrowingArray < NativeCodeBasicBlock*> mBlocks;
|
||||||
|
|
||||||
void Compile(InterCodeProcedure* proc);
|
void Compile(InterCodeProcedure* proc);
|
||||||
|
void Optimize(void);
|
||||||
|
|
||||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||||
NativeCodeBasicBlock* AllocateBlock(void);
|
NativeCodeBasicBlock* AllocateBlock(void);
|
||||||
NativeCodeBasicBlock* TransientBlock(void);
|
|
||||||
|
|
||||||
void CompileInterBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* iblock, NativeCodeBasicBlock*block);
|
void CompileInterBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* iblock, NativeCodeBasicBlock*block);
|
||||||
|
|
||||||
|
void CompressTemporaries(void);
|
||||||
|
|
||||||
void BuildDataFlowSets(void);
|
void BuildDataFlowSets(void);
|
||||||
void ResetVisited(void);
|
void ResetVisited(void);
|
||||||
|
|
||||||
|
@ -223,6 +231,8 @@ public:
|
||||||
|
|
||||||
void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset);
|
void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset);
|
||||||
|
|
||||||
|
uint64 mCompilerOptions;
|
||||||
|
|
||||||
struct Runtime
|
struct Runtime
|
||||||
{
|
{
|
||||||
const Ident * mIdent;
|
const Ident * mIdent;
|
||||||
|
|
|
@ -75,7 +75,7 @@ int main(int argc, const char** argv)
|
||||||
DWORD length = ::GetModuleFileNameA(NULL, basePath, sizeof(basePath));
|
DWORD length = ::GetModuleFileNameA(NULL, basePath, sizeof(basePath));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
printf("Starting oscar64 1.1.42\n");
|
printf("Starting oscar64 1.1.43\n");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,1,42,0
|
FILEVERSION 1,1,43,0
|
||||||
PRODUCTVERSION 1,1,42,0
|
PRODUCTVERSION 1,1,43,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.1.42.0"
|
VALUE "FileVersion", "1.1.43.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.1.42.0"
|
VALUE "ProductVersion", "1.1.43.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_1F88FA4F35F043B3ABFCB552FCEA5CDD"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_216D2A5FECF74C96A4964A74DFEB8552"
|
"MsmKey" = "8:_216D2A5FECF74C96A4964A74DFEB8552"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -106,6 +112,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_B4265CBF352343D2867DBCCE67D9F493"
|
"MsmKey" = "8:_B4265CBF352343D2867DBCCE67D9F493"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -118,6 +130,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_C72E9CB8EC154F9BA499FAC968B83A93"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_D0E45B48D76B4407B0BDE4378C1DB2C7"
|
"MsmKey" = "8:_D0E45B48D76B4407B0BDE4378C1DB2C7"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -303,6 +321,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"IsolateTo" = "8:"
|
||||||
}
|
}
|
||||||
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1F88FA4F35F043B3ABFCB552FCEA5CDD"
|
||||||
|
{
|
||||||
|
"SourcePath" = "8:..\\include\\c64\\rasterirq.c"
|
||||||
|
"TargetName" = "8:rasterirq.c"
|
||||||
|
"Tag" = "8:"
|
||||||
|
"Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28"
|
||||||
|
"Condition" = "8:"
|
||||||
|
"Transitive" = "11:FALSE"
|
||||||
|
"Vital" = "11:TRUE"
|
||||||
|
"ReadOnly" = "11:FALSE"
|
||||||
|
"Hidden" = "11:FALSE"
|
||||||
|
"System" = "11:FALSE"
|
||||||
|
"Permanent" = "11:FALSE"
|
||||||
|
"SharedLegacy" = "11:FALSE"
|
||||||
|
"PackageAs" = "3:1"
|
||||||
|
"Register" = "3:1"
|
||||||
|
"Exclude" = "11:FALSE"
|
||||||
|
"IsDependency" = "11:FALSE"
|
||||||
|
"IsolateTo" = "8:"
|
||||||
|
}
|
||||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_216D2A5FECF74C96A4964A74DFEB8552"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_216D2A5FECF74C96A4964A74DFEB8552"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\include\\stdbool.h"
|
"SourcePath" = "8:..\\include\\stdbool.h"
|
||||||
|
@ -563,6 +601,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"IsolateTo" = "8:"
|
||||||
}
|
}
|
||||||
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F"
|
||||||
|
{
|
||||||
|
"SourcePath" = "8:..\\include\\stddef.h"
|
||||||
|
"TargetName" = "8:stddef.h"
|
||||||
|
"Tag" = "8:"
|
||||||
|
"Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F"
|
||||||
|
"Condition" = "8:"
|
||||||
|
"Transitive" = "11:FALSE"
|
||||||
|
"Vital" = "11:TRUE"
|
||||||
|
"ReadOnly" = "11:FALSE"
|
||||||
|
"Hidden" = "11:FALSE"
|
||||||
|
"System" = "11:FALSE"
|
||||||
|
"Permanent" = "11:FALSE"
|
||||||
|
"SharedLegacy" = "11:FALSE"
|
||||||
|
"PackageAs" = "3:1"
|
||||||
|
"Register" = "3:1"
|
||||||
|
"Exclude" = "11:FALSE"
|
||||||
|
"IsDependency" = "11:FALSE"
|
||||||
|
"IsolateTo" = "8:"
|
||||||
|
}
|
||||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B4265CBF352343D2867DBCCE67D9F493"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B4265CBF352343D2867DBCCE67D9F493"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\include\\c64\\joystick.c"
|
"SourcePath" = "8:..\\include\\c64\\joystick.c"
|
||||||
|
@ -603,6 +661,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"IsolateTo" = "8:"
|
||||||
}
|
}
|
||||||
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C72E9CB8EC154F9BA499FAC968B83A93"
|
||||||
|
{
|
||||||
|
"SourcePath" = "8:..\\include\\c64\\rasterirq.h"
|
||||||
|
"TargetName" = "8:rasterirq.h"
|
||||||
|
"Tag" = "8:"
|
||||||
|
"Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28"
|
||||||
|
"Condition" = "8:"
|
||||||
|
"Transitive" = "11:FALSE"
|
||||||
|
"Vital" = "11:TRUE"
|
||||||
|
"ReadOnly" = "11:FALSE"
|
||||||
|
"Hidden" = "11:FALSE"
|
||||||
|
"System" = "11:FALSE"
|
||||||
|
"Permanent" = "11:FALSE"
|
||||||
|
"SharedLegacy" = "11:FALSE"
|
||||||
|
"PackageAs" = "3:1"
|
||||||
|
"Register" = "3:1"
|
||||||
|
"Exclude" = "11:FALSE"
|
||||||
|
"IsDependency" = "11:FALSE"
|
||||||
|
"IsolateTo" = "8:"
|
||||||
|
}
|
||||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D0E45B48D76B4407B0BDE4378C1DB2C7"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D0E45B48D76B4407B0BDE4378C1DB2C7"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\include\\stdlib.h"
|
"SourcePath" = "8:..\\include\\stdlib.h"
|
||||||
|
@ -872,15 +950,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{BE34D2A8-161C-4DA2-972D-BBF520134E2C}"
|
"ProductCode" = "8:{9CDBFF70-1B69-46D4-AF9A-421A9A0A39A3}"
|
||||||
"PackageCode" = "8:{B497440C-3E40-4996-868C-98739B7F7C7B}"
|
"PackageCode" = "8:{5E5D8444-E4D7-49D3-B597-D5F498EC44BE}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.1.42"
|
"ProductVersion" = "8:1.1.43"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue