Improve zero page variable usage
This commit is contained in:
parent
7b20e6cca0
commit
fefa462730
|
@ -239,7 +239,7 @@ int iec_write_bytes(const char * data, int num)
|
||||||
|
|
||||||
int iec_read_bytes(char * data, int num)
|
int iec_read_bytes(char * data, int num)
|
||||||
{
|
{
|
||||||
char i = 0;
|
int i = 0;
|
||||||
while (i < num)
|
while (i < num)
|
||||||
{
|
{
|
||||||
char ch = iec_read();
|
char ch = iec_read();
|
||||||
|
|
|
@ -21199,6 +21199,7 @@ void InterCodeProcedure::Close(void)
|
||||||
if (var && !var->mTemp && !var->mLinkerObject)
|
if (var && !var->mTemp && !var->mLinkerObject)
|
||||||
{
|
{
|
||||||
var->mLinkerObject = mModule->mLinker->AddObject(mLocation, var->mIdent, mLinkerObject->mStackSection, LOT_BSS);
|
var->mLinkerObject = mModule->mLinker->AddObject(mLocation, var->mIdent, mLinkerObject->mStackSection, LOT_BSS);
|
||||||
|
var->mLinkerObject->mVariable = var;
|
||||||
var->mLinkerObject->mFlags |= LOBJF_LOCAL_VAR;
|
var->mLinkerObject->mFlags |= LOBJF_LOCAL_VAR;
|
||||||
var->mLinkerObject->AddSpace(var->mSize);
|
var->mLinkerObject->AddSpace(var->mSize);
|
||||||
var->mIndex = mModule->mGlobalVars.Size();
|
var->mIndex = mModule->mGlobalVars.Size();
|
||||||
|
|
|
@ -665,6 +665,7 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
||||||
var->mOffset = 0;
|
var->mOffset = 0;
|
||||||
var->mSize = dec->mSize;
|
var->mSize = dec->mSize;
|
||||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||||
|
var->mLinkerObject->mVariable = var;
|
||||||
var->mIdent = dec->mQualIdent;
|
var->mIdent = dec->mQualIdent;
|
||||||
|
|
||||||
Declaration* decb = dec->mBase;
|
Declaration* decb = dec->mBase;
|
||||||
|
@ -2082,6 +2083,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
var->mOffset = 0;
|
var->mOffset = 0;
|
||||||
var->mSize = dec->mSize;
|
var->mSize = dec->mSize;
|
||||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||||
|
var->mLinkerObject->mVariable = var;
|
||||||
|
|
||||||
if (dec->mBase->mFlags & DTF_CONST)
|
if (dec->mBase->mFlags & DTF_CONST)
|
||||||
var->mLinkerObject->mFlags |= LOBJF_CONST;
|
var->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||||
|
@ -2120,6 +2122,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (dec->mFlags & DTF_VAR_ALIASING)
|
if (dec->mFlags & DTF_VAR_ALIASING)
|
||||||
var->mAliased = true;
|
var->mAliased = true;
|
||||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||||
|
var->mLinkerObject->mVariable = var;
|
||||||
dec->mLinkerObject = var->mLinkerObject;
|
dec->mLinkerObject = var->mLinkerObject;
|
||||||
var->mIdent = dec->mQualIdent;
|
var->mIdent = dec->mQualIdent;
|
||||||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||||
|
@ -5297,6 +5300,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
||||||
if (dec->mFlags & DTF_VAR_ALIASING)
|
if (dec->mFlags & DTF_VAR_ALIASING)
|
||||||
var->mAliased = true;
|
var->mAliased = true;
|
||||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||||
|
var->mLinkerObject->mVariable = var;
|
||||||
dec->mLinkerObject = var->mLinkerObject;
|
dec->mLinkerObject = var->mLinkerObject;
|
||||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||||
mod->mGlobalVars.Push(var);
|
mod->mGlobalVars.Push(var);
|
||||||
|
|
|
@ -359,6 +359,7 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L
|
||||||
obj->mSection = section;
|
obj->mSection = section;
|
||||||
obj->mRegion = nullptr;
|
obj->mRegion = nullptr;
|
||||||
obj->mProc = nullptr;
|
obj->mProc = nullptr;
|
||||||
|
obj->mVariable = nullptr;
|
||||||
obj->mFlags = 0;
|
obj->mFlags = 0;
|
||||||
obj->mAlignment = alignment;
|
obj->mAlignment = alignment;
|
||||||
section->mObjects.Push(obj);
|
section->mObjects.Push(obj);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "CompilerTypes.h"
|
#include "CompilerTypes.h"
|
||||||
|
|
||||||
class InterCodeProcedure;
|
class InterCodeProcedure;
|
||||||
|
class InterVariable;
|
||||||
|
|
||||||
enum LinkerObjectType
|
enum LinkerObjectType
|
||||||
{
|
{
|
||||||
|
@ -191,6 +192,7 @@ public:
|
||||||
LinkerRegion * mRegion;
|
LinkerRegion * mRegion;
|
||||||
uint8 * mData, * mMemory;
|
uint8 * mData, * mMemory;
|
||||||
InterCodeProcedure * mProc;
|
InterCodeProcedure * mProc;
|
||||||
|
InterVariable * mVariable;
|
||||||
uint32 mFlags;
|
uint32 mFlags;
|
||||||
uint8 mTemporaries[16], mTempSizes[16];
|
uint8 mTemporaries[16], mTempSizes[16];
|
||||||
int mNumTemporaries;
|
int mNumTemporaries;
|
||||||
|
|
|
@ -92,6 +92,79 @@ void NativeRegisterDataSet::ResetMask(void)
|
||||||
mRegs[i].ResetMask();
|
mRegs[i].ResetMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeRegisterDataSet::ResetCall(const NativeCodeInstruction& ins, int fastCallBase)
|
||||||
|
{
|
||||||
|
mRegs[CPU_REG_C].Reset();
|
||||||
|
mRegs[CPU_REG_Z].Reset();
|
||||||
|
mRegs[CPU_REG_A].Reset();
|
||||||
|
mRegs[CPU_REG_X].Reset();
|
||||||
|
mRegs[CPU_REG_Y].Reset();
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
{
|
||||||
|
if (mRegs[i].mMode == NRDM_ABSOLUTE ||
|
||||||
|
mRegs[i].mMode == NRDM_ABSOLUTE_X ||
|
||||||
|
mRegs[i].mMode == NRDM_ABSOLUTE_Y)
|
||||||
|
{
|
||||||
|
if (mRegs[i].mLinkerObject && mRegs[i].mLinkerObject->mVariable)
|
||||||
|
{
|
||||||
|
InterVariable* var = mRegs[i].mLinkerObject->mVariable;
|
||||||
|
|
||||||
|
if (ins.mLinkerObject && ins.mLinkerObject->mProc)
|
||||||
|
{
|
||||||
|
if (!(var->mLinkerObject->mFlags & LOBJF_LOCAL_VAR))
|
||||||
|
{
|
||||||
|
if (var->mIndex && var->mIndex < ins.mLinkerObject->mProc->mModule->mGlobalVars.Size() && var == ins.mLinkerObject->mProc->mModule->mGlobalVars[var->mIndex])
|
||||||
|
{
|
||||||
|
if (ins.mLinkerObject->mProc->ModifiesGlobal(var->mIndex))
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (var->mAliased)
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
else if (mRegs[i].mMode == NRDM_INDIRECT_Y)
|
||||||
|
{
|
||||||
|
mRegs[i].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetWorkRegs();
|
||||||
|
|
||||||
|
if (!(ins.mFlags & NCIF_RUNTIME) || (ins.mFlags & NCIF_FEXEC))
|
||||||
|
{
|
||||||
|
if (ins.mLinkerObject && ins.mLinkerObject->mProc)
|
||||||
|
{
|
||||||
|
for (int i = BC_REG_TMP; i < BC_REG_TMP + ins.mLinkerObject->mProc->mCallerSavedTemps; i++)
|
||||||
|
ResetZeroPage(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++)
|
||||||
|
ResetZeroPage(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ins.mLinkerObject && (ins.mLinkerObject->mFlags & LOBJF_ZEROPAGESET))
|
||||||
|
{
|
||||||
|
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
|
||||||
|
if (ins.mLinkerObject->mZeroPageSet[i])
|
||||||
|
ResetZeroPage(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
|
||||||
|
ResetZeroPage(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NativeRegisterDataSet::ResetWorkRegs(void)
|
void NativeRegisterDataSet::ResetWorkRegs(void)
|
||||||
|
@ -3042,41 +3115,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
|
|
||||||
if (mType == ASMIT_JSR)
|
if (mType == ASMIT_JSR)
|
||||||
{
|
{
|
||||||
data.mRegs[CPU_REG_C].Reset();
|
data.ResetCall(*this, fastCallBase);
|
||||||
data.mRegs[CPU_REG_Z].Reset();
|
|
||||||
data.mRegs[CPU_REG_A].Reset();
|
|
||||||
data.mRegs[CPU_REG_X].Reset();
|
|
||||||
data.mRegs[CPU_REG_Y].Reset();
|
|
||||||
|
|
||||||
data.ResetIndirect(0);
|
|
||||||
|
|
||||||
data.ResetWorkRegs();
|
|
||||||
|
|
||||||
if (!(mFlags & NCIF_RUNTIME) || (mFlags & NCIF_FEXEC))
|
|
||||||
{
|
|
||||||
if (mLinkerObject && mLinkerObject->mProc)
|
|
||||||
{
|
|
||||||
for (int i = BC_REG_TMP; i < BC_REG_TMP + mLinkerObject->mProc->mCallerSavedTemps; i++)
|
|
||||||
data.ResetZeroPage(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++)
|
|
||||||
data.ResetZeroPage(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLinkerObject && (mLinkerObject->mFlags & LOBJF_ZEROPAGESET))
|
|
||||||
{
|
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
|
|
||||||
if (mLinkerObject->mZeroPageSet[i])
|
|
||||||
data.ResetZeroPage(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS + fastCallBase; i++)
|
|
||||||
data.ResetZeroPage(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19636,7 +19675,7 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mIns.Size() >= 3 && mFalseJump && (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS))
|
if (mExitRequiredRegs.Size() > 0 && mIns.Size() >= 3 && mFalseJump && (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS))
|
||||||
{
|
{
|
||||||
int sz = mIns.Size();
|
int sz = mIns.Size();
|
||||||
|
|
||||||
|
@ -21328,9 +21367,15 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
|
||||||
{
|
{
|
||||||
mExitRequiredRegs += CPU_REG_A;
|
mExitRequiredRegs += CPU_REG_A;
|
||||||
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y])
|
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y])
|
||||||
|
{
|
||||||
|
mTrueJump->mEntryRequiredRegs += CPU_REG_A;
|
||||||
mTrueJump->PrependInstruction(mIns[i - 1]);
|
mTrueJump->PrependInstruction(mIns[i - 1]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
mFalseJump->mEntryRequiredRegs += CPU_REG_A;
|
||||||
mFalseJump->PrependInstruction(mIns[i - 1]);
|
mFalseJump->PrependInstruction(mIns[i - 1]);
|
||||||
|
}
|
||||||
mIns.Remove(i - 1);
|
mIns.Remove(i - 1);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -26710,7 +26755,12 @@ void NativeCodeBasicBlock::PropagateZPAbsolute(const NativeRegisterDataSet& data
|
||||||
|
|
||||||
if (mLoopHead)
|
if (mLoopHead)
|
||||||
{
|
{
|
||||||
mDataSet.Reset();
|
if (mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
|
||||||
|
{
|
||||||
|
ResetModifiedDataSet(mDataSet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mDataSet.Reset();
|
||||||
}
|
}
|
||||||
else if (mNumEntries > 0)
|
else if (mNumEntries > 0)
|
||||||
{
|
{
|
||||||
|
@ -26782,7 +26832,10 @@ void NativeCodeBasicBlock::PropagateZPAbsolute(const NativeRegisterDataSet& data
|
||||||
else if (mIns[i].mType == ASMIT_STY && mIns[i].mMode == ASMIM_ZERO_PAGE)
|
else if (mIns[i].mType == ASMIT_STY && mIns[i].mMode == ASMIM_ZERO_PAGE)
|
||||||
mDataSet.mRegs[mIns[i].mAddress] = mDataSet.mRegs[CPU_REG_Y];
|
mDataSet.mRegs[mIns[i].mAddress] = mDataSet.mRegs[CPU_REG_Y];
|
||||||
else if (mIns[i].mType == ASMIT_JSR)
|
else if (mIns[i].mType == ASMIT_JSR)
|
||||||
mDataSet.Reset();
|
{
|
||||||
|
mDataSet.ResetCall(mIns[i], mProc->mFastCallBase);
|
||||||
|
// mDataSet.Reset();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE)
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
@ -33200,25 +33253,50 @@ bool NativeCodeBasicBlock::OptimizeSingleEntryLoop(NativeCodeProcedure* proc)
|
||||||
if (mLoopHead && mEntryBlocks.Size() > 1)
|
if (mLoopHead && mEntryBlocks.Size() > 1)
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* pblock = nullptr;
|
NativeCodeBasicBlock* pblock = nullptr;
|
||||||
ExpandingArray<NativeCodeBasicBlock*> lblocks;
|
ExpandingArray<NativeCodeBasicBlock*> lblocks, pblocks;
|
||||||
|
|
||||||
int i = 0;
|
bool addprefix = false;
|
||||||
while (i < mEntryBlocks.Size())
|
for(int i=0; i<mEntryBlocks.Size(); i++)
|
||||||
{
|
{
|
||||||
NativeCodeBasicBlock* b = mEntryBlocks[i];
|
NativeCodeBasicBlock* b = mEntryBlocks[i];
|
||||||
|
|
||||||
if (b == this || b->IsDominatedBy(this))
|
if (b == this || b->IsDominatedBy(this))
|
||||||
lblocks.Push(b);
|
lblocks.Push(b);
|
||||||
else if (pblock || b->mFalseJump)
|
|
||||||
{
|
|
||||||
pblock = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
pblock = b;
|
{
|
||||||
i++;
|
if (b->mFalseJump)
|
||||||
|
addprefix = true;
|
||||||
|
pblocks.Push(b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pblocks.Size() > 1 || addprefix)
|
||||||
|
{
|
||||||
|
pblock = mProc->AllocateBlock();
|
||||||
|
pblock->mEntryRequiredRegs = mEntryRequiredRegs;
|
||||||
|
pblock->mExitRequiredRegs = mExitRequiredRegs;
|
||||||
|
pblock->Close(pblocks[0]->mBranchIns, this, nullptr, ASMIT_JMP);
|
||||||
|
AddEntryBlock(pblock);
|
||||||
|
for (int i = 0; i < pblocks.Size(); i++)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* b = pblocks[i];
|
||||||
|
if (this == b->mTrueJump)
|
||||||
|
{
|
||||||
|
b->mTrueJump = pblock;
|
||||||
|
RemEntryBlock(b);
|
||||||
|
pblock->AddEntryBlock(b);
|
||||||
|
}
|
||||||
|
if (this == b->mFalseJump)
|
||||||
|
{
|
||||||
|
b->mFalseJump = pblock;
|
||||||
|
RemEntryBlock(b);
|
||||||
|
pblock->AddEntryBlock(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pblocks.Size() == 1)
|
||||||
|
pblock = pblocks[0];
|
||||||
|
|
||||||
if (pblock && lblocks.Size() + 1 == mEntryBlocks.Size())
|
if (pblock && lblocks.Size() + 1 == mEntryBlocks.Size())
|
||||||
{
|
{
|
||||||
proc->ResetPatched();
|
proc->ResetPatched();
|
||||||
|
@ -36260,6 +36338,80 @@ bool NativeCodeBasicBlock::OptimizeSingleEntryLoopInvariant(NativeCodeProcedure*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tz = tail->mIns.Size();
|
||||||
|
if (mIns.Size() > 0 && mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
tz > 0 && (tail->mIns[tz - 1].mType == ASMIT_INC || tail->mIns[tz - 1].mType == ASMIT_DEC) && tail->mIns[tz - 1].SameEffectiveAddress(mIns[0]))
|
||||||
|
{
|
||||||
|
if (!ChangesYReg(1) && !ReferencesZeroPage(mIns[0].mAddress, 1) &&
|
||||||
|
!tail->ChangesYReg() && !tail->ReferencesZeroPage(mIns[0].mAddress, 0, tz - 1))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (i < lblocks.Size() && (lblocks[i] == tail || (!lblocks[i]->ChangesYReg() && !lblocks[i]->ReferencesZeroPage(mIns[0].mAddress))))
|
||||||
|
i++;
|
||||||
|
if (i == lblocks.Size())
|
||||||
|
{
|
||||||
|
if (this == tail->mTrueJump)
|
||||||
|
{
|
||||||
|
tail->mFalseJump->mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
tail->mFalseJump->mIns.Insert(0, NativeCodeInstruction(mIns[0].mIns, ASMIT_STY, mIns[0]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->mTrueJump->mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
tail->mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[0].mIns, ASMIT_STY, mIns[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tail->mIns[tz - 1].mType == ASMIT_INC)
|
||||||
|
tail->mIns[tz - 1].mType = ASMIT_INY;
|
||||||
|
else
|
||||||
|
tail->mIns[tz - 1].mType = ASMIT_DEY;
|
||||||
|
tail->mIns[tz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
prev->mIns.Push(mIns[0]);
|
||||||
|
mIns.Remove(0);
|
||||||
|
mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
mExitRequiredRegs += CPU_REG_Y;
|
||||||
|
prev->mExitRequiredRegs += CPU_REG_Y;
|
||||||
|
for (int i = 0; i < lblocks.Size(); i++)
|
||||||
|
{
|
||||||
|
lblocks[i]->mEntryRequiredRegs += CPU_REG_Y;
|
||||||
|
lblocks[i]->mExitRequiredRegs += CPU_REG_Y;
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mEntryBlocks.Size() == 2)
|
||||||
|
{
|
||||||
|
if (!tail->mExitRequiredRegs[CPU_REG_X] && !mEntryRequiredRegs[CPU_REG_X])
|
||||||
|
{
|
||||||
|
int ei = tail->mIns.Size() - 1;
|
||||||
|
while (ei >= 0 && !tail->mIns[ei].ReferencesXReg())
|
||||||
|
ei--;
|
||||||
|
if (ei >= 0 && tail->mIns[ei].mType == ASMIT_STX && tail->mIns[ei].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
int si = 0;
|
||||||
|
while (si < mIns.Size() && !mIns[si].ChangesXReg())
|
||||||
|
si++;
|
||||||
|
if (si >= 0 && mIns[si].mType == ASMIT_LDX && mIns[si].SameEffectiveAddress(tail->mIns[ei]))
|
||||||
|
{
|
||||||
|
prev->mIns.Push(mIns[si]);
|
||||||
|
mIns.Remove(si);
|
||||||
|
tail->mIns.Remove(ei);
|
||||||
|
|
||||||
|
for (int i = 0; i < si; i++)
|
||||||
|
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
|
for (int i = ei; i < tail->mIns.Size(); i++)
|
||||||
|
tail->mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mEntryRequiredRegs += CPU_REG_X;
|
||||||
|
tail->mExitRequiredRegs += CPU_REG_X;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -46234,7 +46386,7 @@ void NativeCodeBasicBlock::CheckLive(void)
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
uint32 live = 0;
|
uint32 live = 0;
|
||||||
|
|
||||||
if (mFalseJump && mFalseJump->mEntryRequiredRegs.Size() > 0 && mFalseJump->mEntryRequiredRegs[CPU_REG_X])
|
if (mFalseJump && mFalseJump->mEntryRequiredRegs.Size() > 0 && mFalseJump->mEntryRequiredRegs[CPU_REG_X] && mExitRequiredRegs.Size() > 0)
|
||||||
{
|
{
|
||||||
if (mFalseJump->mIns.Size() > 0 && mFalseJump->mIns[0].RequiresXReg())
|
if (mFalseJump->mIns.Size() > 0 && mFalseJump->mIns[0].RequiresXReg())
|
||||||
assert(mExitRequiredRegs[CPU_REG_X]);
|
assert(mExitRequiredRegs[CPU_REG_X]);
|
||||||
|
@ -46977,7 +47129,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "memmove");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct NativeRegisterDataSet
|
||||||
|
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
void ResetMask(void);
|
void ResetMask(void);
|
||||||
|
void ResetCall(const NativeCodeInstruction & ins, int fastCallBase);
|
||||||
|
|
||||||
void ResetZeroPage(int addr);
|
void ResetZeroPage(int addr);
|
||||||
void ResetZeroPageRange(int addr, int num);
|
void ResetZeroPageRange(int addr, int num);
|
||||||
|
|
Loading…
Reference in New Issue