Improve register allocator
This commit is contained in:
parent
931f9e71b9
commit
5d51ea13c5
12
README.md
12
README.md
|
@ -231,6 +231,18 @@ The compiler uses basic zero page space for temporaries, local variables and fun
|
||||||
|
|
||||||
__zeropage int a;
|
__zeropage int a;
|
||||||
|
|
||||||
|
### Prevent inlining
|
||||||
|
|
||||||
|
With compiler option O2 and greater the compiler will try to inline small functions. This may not always be desirable, so the __noinline qualifier can be added to a function to prevent this.
|
||||||
|
|
||||||
|
__noinline byte EzRead(char bank, const char * p)
|
||||||
|
{
|
||||||
|
eflash.bank = bank;
|
||||||
|
byte b = *p;
|
||||||
|
eflash.bank = CodeBank;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
### Pre-Processor control
|
### Pre-Processor control
|
||||||
|
|
||||||
The pre processor has additional commands to control the scanner and allow for dynamic code generation including loops.
|
The pre processor has additional commands to control the scanner and allow for dynamic code generation including loops.
|
||||||
|
|
|
@ -72,6 +72,7 @@ static const uint64 DTF_EXPORT = (1ULL << 19);
|
||||||
static const uint64 DTF_HWINTERRUPT = (1ULL << 20);
|
static const uint64 DTF_HWINTERRUPT = (1ULL << 20);
|
||||||
static const uint64 DTF_STACKCALL = (1ULL << 21);
|
static const uint64 DTF_STACKCALL = (1ULL << 21);
|
||||||
static const uint64 DTF_ZEROPAGE = (1ULL << 22);
|
static const uint64 DTF_ZEROPAGE = (1ULL << 22);
|
||||||
|
static const uint64 DTF_PREVENT_INLINE = (1ULL << 23);
|
||||||
|
|
||||||
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
|
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
|
||||||
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);
|
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);
|
||||||
|
|
|
@ -62,7 +62,14 @@ void GlobalAnalyzer::AutoInline(void)
|
||||||
for (int i = 0; i < mFunctions.Size(); i++)
|
for (int i = 0; i < mFunctions.Size(); i++)
|
||||||
{
|
{
|
||||||
Declaration* f = mFunctions[i];
|
Declaration* f = mFunctions[i];
|
||||||
if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100)
|
if (!(f->mFlags & DTF_INLINE) &&
|
||||||
|
!(f->mFlags & DTF_EXPORT) &&
|
||||||
|
!(f->mFlags & DTF_PREVENT_INLINE) &&
|
||||||
|
!(f->mBase->mFlags & DTF_VARIADIC) &&
|
||||||
|
!(f->mFlags & DTF_FUNC_VARIABLE) &&
|
||||||
|
!((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) &&
|
||||||
|
!(f->mFlags & DTF_INTRINSIC) &&
|
||||||
|
!(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100)
|
||||||
{
|
{
|
||||||
int nparams = 0;
|
int nparams = 0;
|
||||||
Declaration* dec = f->mBase->mParams;
|
Declaration* dec = f->mBase->mParams;
|
||||||
|
|
|
@ -2419,9 +2419,15 @@ bool InterOperand::IsEqual(const InterOperand& op) const
|
||||||
if (mMemory != op.mMemory)
|
if (mMemory != op.mMemory)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mIntConst != op.mIntConst || mFloatConst != op.mFloatConst || mVarIndex != op.mVarIndex || mLinkerObject != op.mLinkerObject)
|
if (mIntConst != op.mIntConst || mFloatConst != op.mFloatConst)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (mMemory != IM_NONE && mMemory != IM_INDIRECT)
|
||||||
|
{
|
||||||
|
if (mVarIndex != op.mVarIndex || mLinkerObject != op.mLinkerObject)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5740,10 +5746,13 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
switch (ins->mOperator)
|
switch (ins->mOperator)
|
||||||
{
|
{
|
||||||
case IA_EXT8TO16U:
|
case IA_EXT8TO16U:
|
||||||
case IA_EXT8TO16S:
|
|
||||||
if (ins->mSrc[0].mTemp >= 0 && (vr.mMaxValue != 255 || vr.mMinValue != 0))
|
if (ins->mSrc[0].mTemp >= 0 && (vr.mMaxValue != 255 || vr.mMinValue != 0))
|
||||||
mReverseValueRange[ins->mSrc[0].mTemp].Limit(vr);
|
mReverseValueRange[ins->mSrc[0].mTemp].Limit(vr);
|
||||||
break;
|
break;
|
||||||
|
case IA_EXT8TO16S:
|
||||||
|
if (ins->mSrc[0].mTemp >= 0 && (vr.mMaxValue != 127 || vr.mMinValue != -128))
|
||||||
|
mReverseValueRange[ins->mSrc[0].mTemp].Limit(vr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IC_BINARY_OPERATOR:
|
case IC_BINARY_OPERATOR:
|
||||||
|
@ -13005,35 +13014,60 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
|
||||||
|
|
||||||
assert(freeCallerSavedTemps <= mCallerSavedTemps);
|
assert(freeCallerSavedTemps <= mCallerSavedTemps);
|
||||||
|
|
||||||
mTempOffset.SetSize(0);
|
mTempOffset.SetSize(mTemporaries.Size(), true);
|
||||||
mTempSizes.SetSize(0);
|
mTempSizes.SetSize(mTemporaries.Size(), true);
|
||||||
|
|
||||||
for (int i = 0; i < mTemporaries.Size(); i++)
|
for (int i = 0; i < mTemporaries.Size(); i++)
|
||||||
{
|
{
|
||||||
int size = InterTypeSize[mTemporaries[i]];
|
if (!callerSaved[i])
|
||||||
|
{
|
||||||
|
int size = InterTypeSize[mTemporaries[i]];
|
||||||
|
|
||||||
if (freeTemps + size <= freeCallerSavedTemps && !callerSaved[i])
|
if (freeTemps + size <= freeCallerSavedTemps)
|
||||||
{
|
{
|
||||||
mTempOffset.Push(freeTemps);
|
mTempOffset[i] = freeTemps;
|
||||||
mTempSizes.Push(size);
|
mTempSizes[i] = size;
|
||||||
freeTemps += size;
|
freeTemps += size;
|
||||||
}
|
}
|
||||||
else if (callerSavedTemps + size <= maxCallerSavedTemps)
|
|
||||||
{
|
|
||||||
mTempOffset.Push(callerSavedTemps);
|
|
||||||
mTempSizes.Push(size);
|
|
||||||
callerSavedTemps += size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mTempOffset.Push(calleeSavedTemps);
|
|
||||||
mTempSizes.Push(size);
|
|
||||||
calleeSavedTemps += size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (freeTemps > callerSavedTemps)
|
||||||
|
// callerSavedTemps = freeTemps;
|
||||||
|
|
||||||
|
for (int i = 0; i < mTemporaries.Size(); i++)
|
||||||
|
{
|
||||||
|
if (!mTempSizes[i])
|
||||||
|
{
|
||||||
|
int size = InterTypeSize[mTemporaries[i]];
|
||||||
|
|
||||||
|
if (callerSavedTemps + size <= maxCallerSavedTemps)
|
||||||
|
{
|
||||||
|
mTempOffset[i] = callerSavedTemps;
|
||||||
|
mTempSizes[i] = size;
|
||||||
|
callerSavedTemps += size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTempOffset[i] = calleeSavedTemps;
|
||||||
|
mTempSizes[i] = size;
|
||||||
|
calleeSavedTemps += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mTempSize = calleeSavedTemps;
|
mTempSize = calleeSavedTemps;
|
||||||
mCallerSavedTemps = callerSavedTemps;
|
mCallerSavedTemps = callerSavedTemps;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("Map %s, %d, %d, %d, %d\n", mIdent->mString, freeTemps, callerSavedTemps, calleeSavedTemps, freeCallerSavedTemps);
|
||||||
|
for (int i = 0; i < mTempOffset.Size(); i++)
|
||||||
|
printf("T%02d : %d, %d\n", i, mTempOffset[i], mTempSizes[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mSaveTempsLinkerObject && mTempSize > 16)
|
||||||
|
mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
|
||||||
|
|
||||||
// printf("Map %s, %d, %d, %d, %d\n", mIdent->mString, freeTemps, callerSavedTemps, calleeSavedTemps, freeCallerSavedTemps);
|
// printf("Map %s, %d, %d, %d, %d\n", mIdent->mString, freeTemps, callerSavedTemps, calleeSavedTemps, freeCallerSavedTemps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,12 @@ void LinkerObject::AddData(const uint8* data, int size)
|
||||||
|
|
||||||
uint8* LinkerObject::AddSpace(int size)
|
uint8* LinkerObject::AddSpace(int size)
|
||||||
{
|
{
|
||||||
mSize = size;
|
if (mSize != size)
|
||||||
mData = new uint8[size];
|
{
|
||||||
memset(mData, 0, size);
|
mSize = size;
|
||||||
|
mData = new uint8[size];
|
||||||
|
memset(mData, 0, size);
|
||||||
|
}
|
||||||
return mData;
|
return mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16294,6 +16294,228 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair)
|
||||||
|
{
|
||||||
|
if (at == 0 && mVisited)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (at == 0)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
if (mNumEntries > 1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||||
|
if (!mEntryBlocks[i]->IsDominatedBy(block))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (at < mIns.Size())
|
||||||
|
{
|
||||||
|
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
if (mIns[at].mAddress == to)
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == to + 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (mIns[at].mMode == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
if (mIns[at].mAddress == to)
|
||||||
|
return false;
|
||||||
|
if (mIns[at].mAddress + 1 == to)
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == to + 1)
|
||||||
|
return false;
|
||||||
|
if (!pair && mIns[at].mAddress == from)
|
||||||
|
return false;
|
||||||
|
if (mIns[at].mAddress + 1 == from)
|
||||||
|
return false;
|
||||||
|
if (pair && mIns[at].mAddress == from + 1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (mIns[at].mType == ASMIT_JSR)
|
||||||
|
{
|
||||||
|
LinkerObject* lo = mIns[at].mLinkerObject;
|
||||||
|
if (lo)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lo->mNumTemporaries; i++)
|
||||||
|
{
|
||||||
|
if (from >= lo->mTemporaries[i] && from < lo->mTemporaries[i] + lo->mTempSizes[i] ||
|
||||||
|
to >= lo->mTemporaries[i] && to < lo->mTemporaries[i] + lo->mTempSizes[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIns[at].mFlags & NCIF_USE_ZP_32_X)
|
||||||
|
{
|
||||||
|
if (to >= mIns[at].mParam && to < mIns[at].mParam + 4 ||
|
||||||
|
from >= mIns[at].mParam && from < mIns[at].mParam + 4)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
at++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && !mTrueJump->IsFinalZeroPageUse(block, 0, from, to, pair))
|
||||||
|
return false;
|
||||||
|
if (mFalseJump && !mFalseJump->IsFinalZeroPageUse(block, 0, from, to, pair))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
|
||||||
|
{
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (i + 1 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 0].mAddress >= BC_REG_FPARAMS && mIns[i + 0].mAddress < BC_REG_FPARAMS_END &&
|
||||||
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (IsFinalZeroPageUse(this, i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress, false))
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress + 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
|
||||||
|
mIns[i + 0].mAddress >= BC_REG_FPARAMS && mIns[i + 0].mAddress < BC_REG_FPARAMS_END &&
|
||||||
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (IsFinalZeroPageUse(this, i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
changed = true;
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 4, mIns[i + 3].mAddress, mIns[i + 2].mAddress))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i + 5 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 0].mAddress + 1 &&
|
||||||
|
mIns[i + 4].mType == ASMIT_ADC && !mIns[i + 4].MayBeSameAddress(mIns[i + 2]) &&
|
||||||
|
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 &&
|
||||||
|
mIns[i + 0].mAddress >= BC_REG_FPARAMS && mIns[i + 0].mAddress < BC_REG_FPARAMS_END &&
|
||||||
|
mIns[i + 2].mAddress >= BC_REG_TMP)
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true))
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress))
|
||||||
|
changed = true;
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 6, mIns[i + 5].mAddress, mIns[i + 3].mAddress))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
mIns[i + 2].mAddress = mIns[i + 0].mAddress;
|
||||||
|
mIns[i + 5].mAddress = mIns[i + 3].mAddress;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i + 4 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_ADC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress + 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && !mIns[i + 3].MayBeSameAddress(mIns[i + 1]) &&
|
||||||
|
mIns[i + 4].mType == ASMIT_STA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress + 1 &&
|
||||||
|
mIns[i + 0].mAddress >= BC_REG_FPARAMS && mIns[i + 0].mAddress < BC_REG_FPARAMS_END &&
|
||||||
|
mIns[i + 1].mAddress >= BC_REG_TMP)
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
|
||||||
|
{
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
|
||||||
|
changed = true;
|
||||||
|
nproc->ResetPatched();
|
||||||
|
if (ForwardReplaceZeroPage(i + 5, mIns[i + 4].mAddress, mIns[i + 2].mAddress))
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
mIns[i + 1].mAddress = mIns[i + 0].mAddress;
|
||||||
|
mIns[i + 4].mAddress = mIns[i + 2].mAddress;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->ReplaceFinalZeroPageUse(nproc))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->ReplaceFinalZeroPageUse(nproc))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::ForwardReplaceZeroPage(int at, int from, int to)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mPatched)
|
||||||
|
{
|
||||||
|
mPatched = true;
|
||||||
|
|
||||||
|
for (int i = at; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE || mIns[i].mMode == ASMIM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
if (mIns[i].mAddress == from)
|
||||||
|
{
|
||||||
|
mIns[i].mAddress = to;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->ForwardReplaceZeroPage(0, from, to))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->ForwardReplaceZeroPage(0, from, to))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::Propagate16BitSum(void)
|
bool NativeCodeBasicBlock::Propagate16BitSum(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -19631,7 +19853,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
|
||||||
#endif
|
#endif
|
||||||
else if (i + 3 < mIns.Size() &&
|
else if (i + 3 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
@ -19644,7 +19866,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
else if (i + 3 < mIns.Size() &&
|
else if (i + 3 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_SEC &&
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
@ -19655,6 +19877,67 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
|
||||||
j += 3;
|
j += 3;
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0] = mIns[i + 0];
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX;
|
||||||
|
mIns[j + 1].mType = ASMIT_INX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_STX; mIns[j + 2].mMode = ASMIM_ZERO_PAGE; mIns[j + 2].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 3;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0] = mIns[i + 0];
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX;
|
||||||
|
mIns[j + 1].mType = ASMIT_DEX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_STX; mIns[j + 2].mMode = ASMIM_ZERO_PAGE; mIns[j + 2].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 3;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0] = mIns[i + 0];
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX;
|
||||||
|
mIns[j + 1].mType = ASMIT_INX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_INX; mIns[j + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 3].mType = ASMIT_STX; mIns[j + 3].mMode = ASMIM_ZERO_PAGE; mIns[j + 3].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 4;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
else if (i + 3 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 0].mMode) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 2 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
!(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z | LIVE_CPU_REG_X)))
|
||||||
|
{
|
||||||
|
mIns[j + 0] = mIns[i + 0];
|
||||||
|
mIns[j + 0].mType = ASMIT_LDX;
|
||||||
|
mIns[j + 1].mType = ASMIT_DEX; mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 2].mType = ASMIT_DEX; mIns[j + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[j + 3].mType = ASMIT_STX; mIns[j + 3].mMode = ASMIM_ZERO_PAGE; mIns[j + 3].mAddress = mIns[i + 3].mAddress;
|
||||||
|
j += 4;
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
|
|
||||||
else if (i + 3 < mIns.Size() &&
|
else if (i + 3 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -19679,6 +19962,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc)
|
||||||
j += 2;
|
j += 2;
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (i + 1 < mIns.Size() &&
|
else if (i + 1 < mIns.Size() &&
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_X &&
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_X &&
|
||||||
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||||
|
@ -23321,7 +23605,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
|
@ -23337,7 +23621,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_SEC &&
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
|
@ -23353,7 +23637,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
|
@ -23369,7 +23653,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_SEC &&
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
|
||||||
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress <= 2 &&
|
||||||
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_C)))
|
||||||
{
|
{
|
||||||
|
@ -23659,6 +23943,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SBC &&
|
||||||
|
mIns[i + 2].mType == ASMIT_SEC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_SBC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 1 && !(mIns[i + 3].mLive & LIVE_CPU_REG_C))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_CLC;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -24824,6 +25119,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
CheckLive();
|
CheckLive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (sz >= 2 &&
|
||||||
|
mIns[sz - 2].ChangesAccuAndFlag() &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !mExitRequiredRegs[CPU_REG_Z] && !mExitRequiredRegs[CPU_REG_C])
|
||||||
|
{
|
||||||
|
if (mBranch == ASMIT_BCC)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_BPL;
|
||||||
|
mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
}
|
||||||
|
else if (mBranch == ASMIT_BCS)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_BMI;
|
||||||
|
mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (sz >= 4 &&
|
else if (sz >= 4 &&
|
||||||
mIns[sz - 4].mType == ASMIT_EOR && mIns[sz - 4].mMode == ASMIM_IMMEDIATE && mIns[sz - 4].mAddress == 0x80 &&
|
mIns[sz - 4].mType == ASMIT_EOR && mIns[sz - 4].mMode == ASMIM_IMMEDIATE && mIns[sz - 4].mAddress == 0x80 &&
|
||||||
|
@ -25392,56 +25706,65 @@ void NativeCodeProcedure::CompressTemporaries(void)
|
||||||
remap[i] = i;
|
remap[i] = i;
|
||||||
|
|
||||||
int tpos = BC_REG_TMP + mInterProc->mFreeCallerSavedTemps;
|
int tpos = BC_REG_TMP + mInterProc->mFreeCallerSavedTemps;
|
||||||
// BC_REG_TMP_SAVED;
|
int spos = BC_REG_TMP_SAVED;
|
||||||
// if (mInterProc->mLeafProcedure)
|
|
||||||
// tpos = BC_REG_TMP;
|
|
||||||
|
|
||||||
for (int i = 0; i < mInterProc->mTempOffset.Size(); i++)
|
// for (int tsize = 4; tsize > 0; tsize >>= 1)
|
||||||
{
|
{
|
||||||
bool tused = false;
|
for (int i = 0; i < mInterProc->mTempOffset.Size(); i++)
|
||||||
|
|
||||||
int reg = BC_REG_TMP + mInterProc->mTempOffset[i];
|
|
||||||
// if (mInterProc->mLeafProcedure || reg >= BC_REG_TMP_SAVED)
|
|
||||||
if (reg >= BC_REG_TMP + mInterProc->mFreeCallerSavedTemps)
|
|
||||||
{
|
{
|
||||||
int size = mInterProc->mTempSizes[i];
|
bool tused = false;
|
||||||
int usize = 0;
|
|
||||||
|
|
||||||
for (int j = 0; j < size; j++)
|
int reg = BC_REG_TMP + mInterProc->mTempOffset[i];
|
||||||
if (used[reg + j])
|
// if (mInterProc->mLeafProcedure || reg >= BC_REG_TMP_SAVED)
|
||||||
usize = j + 1;
|
if (reg >= BC_REG_TMP + mInterProc->mFreeCallerSavedTemps)
|
||||||
|
|
||||||
if (usize)
|
|
||||||
{
|
{
|
||||||
if (tpos < BC_REG_TMP_SAVED && tpos + usize > BC_REG_TMP + mInterProc->mCallerSavedTemps)
|
int size = mInterProc->mTempSizes[i];
|
||||||
tpos = BC_REG_TMP_SAVED;
|
// if (size == tsize)
|
||||||
|
{
|
||||||
|
int usize = 0;
|
||||||
|
|
||||||
for (int j = 0; j < usize; j++)
|
for (int j = 0; j < size; j++)
|
||||||
remap[reg + j] = tpos + j;
|
if (used[reg + j])
|
||||||
|
usize = j + 1;
|
||||||
|
|
||||||
mInterProc->mTempOffset[i] = tpos - BC_REG_TMP;
|
if (usize)
|
||||||
mInterProc->mTempSizes[i] = usize;
|
{
|
||||||
tpos += usize;
|
int pos = spos;
|
||||||
|
if (tpos + usize <= BC_REG_TMP + mInterProc->mCallerSavedTemps)
|
||||||
|
{
|
||||||
|
pos = tpos;
|
||||||
|
tpos += usize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
spos += usize;
|
||||||
|
|
||||||
}
|
for (int j = 0; j < usize; j++)
|
||||||
else
|
remap[reg + j] = pos + j;
|
||||||
{
|
|
||||||
mInterProc->mTempOffset[i] = 0;
|
mInterProc->mTempOffset[i] = pos - BC_REG_TMP;
|
||||||
mInterProc->mTempSizes[i] = 0;
|
mInterProc->mTempSizes[i] = usize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInterProc->mTempOffset[i] = 0;
|
||||||
|
mInterProc->mTempSizes[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tpos < BC_REG_TMP_SAVED)
|
mInterProc->mCallerSavedTemps = tpos - BC_REG_TMP;
|
||||||
{
|
|
||||||
// printf("%s, %d -> %d\n", mInterProc->mIdent->mString, mInterProc->mCallerSavedTemps, tpos - BC_REG_TMP);
|
|
||||||
mInterProc->mCallerSavedTemps = tpos - BC_REG_TMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->RemapZeroPage(remap);
|
mEntryBlock->RemapZeroPage(remap);
|
||||||
|
|
||||||
mInterProc->mTempSize = tpos - BC_REG_TMP;
|
assert(mInterProc->mTempSize >= tpos - BC_REG_TMP);
|
||||||
|
|
||||||
|
if (spos > BC_REG_TMP_SAVED)
|
||||||
|
mInterProc->mTempSize = spos - BC_REG_TMP;
|
||||||
|
else
|
||||||
|
mInterProc->mTempSize = tpos - BC_REG_TMP;
|
||||||
|
|
||||||
if (mNoFrame && !used[BC_REG_STACK] && mInterProc->mTempSize <= 16)
|
if (mNoFrame && !used[BC_REG_STACK] && mInterProc->mTempSize <= 16)
|
||||||
mStackExpand = 0;
|
mStackExpand = 0;
|
||||||
|
@ -26021,6 +26344,13 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (step == 2)
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
@ -345,6 +345,10 @@ public:
|
||||||
bool Check16BitSum(int at, NativeRegisterSum16Info& info);
|
bool Check16BitSum(int at, NativeRegisterSum16Info& info);
|
||||||
bool Propagate16BitSum(void);
|
bool Propagate16BitSum(void);
|
||||||
|
|
||||||
|
bool IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair);
|
||||||
|
bool ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc);
|
||||||
|
bool ForwardReplaceZeroPage(int at, int from, int to);
|
||||||
|
|
||||||
NativeRegisterDataSet mEntryRegisterDataSet;
|
NativeRegisterDataSet mEntryRegisterDataSet;
|
||||||
|
|
||||||
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
||||||
|
|
|
@ -986,6 +986,11 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
storageFlags |= DTF_ZEROPAGE;
|
storageFlags |= DTF_ZEROPAGE;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
|
else if (mScanner->mToken == TK_NOINLINE)
|
||||||
|
{
|
||||||
|
storageFlags |= DTF_PREVENT_INLINE;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
else if (mScanner->mToken == TK_INLINE)
|
else if (mScanner->mToken == TK_INLINE)
|
||||||
{
|
{
|
||||||
storageFlags |= DTF_REQUEST_INLINE;
|
storageFlags |= DTF_REQUEST_INLINE;
|
||||||
|
|
|
@ -56,6 +56,7 @@ const char* TokenNames[] =
|
||||||
"__fastcall",
|
"__fastcall",
|
||||||
"__export",
|
"__export",
|
||||||
"__zeropage",
|
"__zeropage",
|
||||||
|
"__noinline",
|
||||||
|
|
||||||
"number",
|
"number",
|
||||||
"char",
|
"char",
|
||||||
|
@ -1341,6 +1342,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_EXPORT;
|
mToken = TK_EXPORT;
|
||||||
else if (!strcmp(tkident, "__zeropage"))
|
else if (!strcmp(tkident, "__zeropage"))
|
||||||
mToken = TK_ZEROPAGE;
|
mToken = TK_ZEROPAGE;
|
||||||
|
else if (!strcmp(tkident, "__noinline"))
|
||||||
|
mToken = TK_NOINLINE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mToken = TK_IDENT;
|
mToken = TK_IDENT;
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum Token
|
||||||
TK_FASTCALL,
|
TK_FASTCALL,
|
||||||
TK_EXPORT,
|
TK_EXPORT,
|
||||||
TK_ZEROPAGE,
|
TK_ZEROPAGE,
|
||||||
|
TK_NOINLINE,
|
||||||
|
|
||||||
TK_NUMBER,
|
TK_NUMBER,
|
||||||
TK_CHARACTER,
|
TK_CHARACTER,
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.7.141");
|
strcpy(strProductVersion, "1.7.142");
|
||||||
|
|
||||||
#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,7,141,0
|
FILEVERSION 1,7,142,0
|
||||||
PRODUCTVERSION 1,7,141,0
|
PRODUCTVERSION 1,7,142,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.7.141.0"
|
VALUE "FileVersion", "1.7.142.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.7.141.0"
|
VALUE "ProductVersion", "1.7.142.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -4153,15 +4153,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{AAAF5F55-0261-47DA-B051-EF84642395A5}"
|
"ProductCode" = "8:{54C9EB87-4154-49FD-B146-2408492EDE3B}"
|
||||||
"PackageCode" = "8:{A7501921-EE58-422B-AEE2-4491A2249AC0}"
|
"PackageCode" = "8:{A90AA9BF-452A-4C37-B592-CAF52893124A}"
|
||||||
"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.7.141"
|
"ProductVersion" = "8:1.7.142"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue