Fixed copy with offset

This commit is contained in:
drmortalwombat 2023-11-20 08:29:23 +01:00
parent 38e1cd0bab
commit 0309fcb286
5 changed files with 223 additions and 36 deletions

View File

@ -41,7 +41,6 @@ void dispmode80col(void);
#define PETSCII_F7 0x88
#define PETSCII_F8 0x8c
int kbhit(void);
int getche(void);

View File

@ -604,8 +604,16 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
return exp->mDecValue;
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
if (exp->mToken == TK_ASSIGN)
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
if (exp->mLeft->mDecType->IsReference())
rdec = Analyze(exp->mRight, procDec, ANAFL_LHS | ANAFL_RHS);
else
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
RegisterProc(rdec);
return ldec;

View File

@ -9446,6 +9446,76 @@ static bool IsValidSignedIntRange(InterType t, int64 value)
}
}
bool InterCodeBasicBlock::ForwardShortLoadStoreOffsets(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* lins = mInstructions[i];
if (lins->mCode == IC_LEA && lins->mSrc[1].mTemp >= 0 && lins->mSrc[0].mTemp < 0 && lins->mSrc[0].IsUByte())
{
for (int j = i + 1; j < mInstructions.Size(); j++)
{
InterInstruction* lins2 = mInstructions[j];
if (lins2->mCode == IC_LEA && lins2->mSrc[1].mTemp == lins->mDst.mTemp && lins2->mSrc[0].mTemp >= 0)
{
int k = j + 1;
while (k < mInstructions.Size() && !mInstructions[k]->ReferencesTemp(lins2->mDst.mTemp) && !mInstructions[k]->ReferencesTemp(lins->mSrc[1].mTemp))
k++;
if (k < mInstructions.Size())
{
InterInstruction* mins = mInstructions[k];
if (mins->mCode == IC_LOAD && mins->mSrc[0].mTemp == lins2->mDst.mTemp && mins->mSrc[0].mFinal)
{
lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp;
lins->mSrc[1].mFinal = false;
mins->mSrc[0].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
else if (mins->mCode == IC_STORE && mins->mSrc[1].mTemp == lins2->mDst.mTemp && mins->mSrc[1].mFinal)
{
lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp;
lins->mSrc[1].mFinal = false;
mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
else if (mins->mCode == IC_COPY && mins->mSrc[0].mTemp == lins2->mDst.mTemp && mins->mSrc[0].mFinal)
{
lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp;
lins->mSrc[1].mFinal = false;
mins->mSrc[0].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
else if (mins->mCode == IC_COPY && mins->mSrc[1].mTemp == lins2->mDst.mTemp && mins->mSrc[1].mFinal)
{
lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp;
lins->mSrc[1].mFinal = false;
mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
}
}
if (lins2->mDst.mTemp == lins->mDst.mTemp)
break;
}
}
}
if (mTrueJump && mTrueJump->ForwardShortLoadStoreOffsets())
changed = true;
if (mFalseJump && mFalseJump->ForwardShortLoadStoreOffsets())
changed = true;
}
return changed;
}
bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps)
{
bool changed = false;
@ -16375,7 +16445,6 @@ bool InterCodeBasicBlock::PeepholeReplaceOptimization(const GrowingVariableArray
mInstructions[i + 0]->mCode = IC_NONE; mInstructions[i + 0]->mNumOperands = 0;
changed = true;
}
}
@ -18525,7 +18594,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "interpret_builtin");
CheckFunc = !strcmp(mIdent->mString, "test");
CheckCase = false;
mEntryBlock = mBlocks[0];
@ -19273,6 +19342,12 @@ void InterCodeProcedure::Close(void)
CombineIndirectAddressing();
BuildDataFlowSets();
ResetVisited();
mEntryBlock->ForwardShortLoadStoreOffsets();
DisassembleDebug("ForwardShortLoadStoreOffsets");
#if 1
for (int i = 0; i < 8; i++)
{
@ -19613,21 +19688,47 @@ void InterCodeProcedure::MapVariables(void)
}
}
static bool IsReadModifyWrite(const InterCodeBasicBlock* block, int at)
{
if (block->mInstructions[at]->mCode == IC_LOAD &&
block->mInstructions[at + 2]->mCode == IC_STORE &&
block->mInstructions[at + 1]->mDst.mTemp == block->mInstructions[at + 2]->mSrc[0].mTemp &&
block->mInstructions[at]->mSrc[0].IsEqual(block->mInstructions[at + 2]->mSrc[1]))
{
if (block->mInstructions[at + 1]->mCode == IC_BINARY_OPERATOR)
{
return
block->mInstructions[at + 1]->mSrc[0].mTemp == block->mInstructions[at]->mDst.mTemp ||
block->mInstructions[at + 1]->mSrc[1].mTemp == block->mInstructions[at]->mDst.mTemp;
}
else if (block->mInstructions[at + 1]->mCode == IC_UNARY_OPERATOR)
{
return
block->mInstructions[at + 1]->mSrc[0].mTemp == block->mInstructions[at]->mDst.mTemp;
}
}
return false;
}
bool InterCodeBasicBlock::SameExitCode(const InterCodeBasicBlock* block) const
{
if (mInstructions.Size() > 1 && block->mInstructions.Size() > 1)
int sz0 = mInstructions.Size();
int sz1 = block->mInstructions.Size();
if (sz0 > 1 && sz1 > 1)
{
InterInstruction* ins0 = mInstructions[mInstructions.Size() - 2];
InterInstruction* ins1 = block->mInstructions[block->mInstructions.Size() - 2];
InterInstruction* ins0 = mInstructions[sz0 - 2];
InterInstruction* ins1 = block->mInstructions[sz1 - 2];
if (ins0->IsEqual(ins1))
{
if (ins0->mCode == IC_STORE && ins0->mSrc[1].mTemp >= 0)
{
int j0 = mInstructions.Size() - 3;
int j0 = sz0 - 3;
while (j0 >= 0 && mInstructions[j0]->mDst.mTemp != ins0->mSrc[1].mTemp)
j0--;
int j1 = block->mInstructions.Size() - 3;
int j1 = sz1 - 3;
while (j1 >= 0 && block->mInstructions[j1]->mDst.mTemp != ins0->mSrc[1].mTemp)
j1--;
@ -19641,6 +19742,20 @@ bool InterCodeBasicBlock::SameExitCode(const InterCodeBasicBlock* block) const
return false;
}
}
if (InterTypeSize[ins0->mSrc[0].mType] == 4)
{
bool rm0 = sz0 >= 4 && IsReadModifyWrite(this, sz0 - 4);
bool rm1 = sz1 >= 4 && IsReadModifyWrite(block, sz1 - 4);
if (rm0 && rm1)
{
if (!(mInstructions[sz0 - 3]->IsEqual(block->mInstructions[sz1 - 3])))
return false;
}
else if (rm0 || rm1)
return false;
}
}
else if (ins0->mCode == IC_LOAD && ins0->mSrc[0].mTemp >= 0)
{

View File

@ -484,6 +484,8 @@ public:
bool SimplifyPointerOffsets(void);
bool EliminateAliasValues(const GrowingInstructionPtrArray& tvalue, const GrowingInstructionPtrArray& avalue);
bool ForwardShortLoadStoreOffsets(void);
void CalculateSingleUsedTemps(FastNumberSet& fused, FastNumberSet& fsingle);
bool CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory);

View File

@ -5934,7 +5934,7 @@ void NativeCodeBasicBlock::StoreByteIndexedValue(InterCodeProcedure* proc, const
void NativeCodeBasicBlock::LoadAbsoluteByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins)
{
mIns.Push(NativeCodeInstruction(iins, ASMIT_LDX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[iins->mSrc[0].mTemp]));
int address = iins->mSrc[1].mIntConst + rins->mSrc[0].mIntConst;
int address = int(iins->mSrc[1].mIntConst + rins->mSrc[0].mIntConst);
uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile)
@ -5950,7 +5950,7 @@ void NativeCodeBasicBlock::LoadAbsoluteByteIndexedValue(InterCodeProcedure* proc
void NativeCodeBasicBlock::StoreAbsoluteByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* wins)
{
mIns.Push(NativeCodeInstruction(iins, ASMIT_LDX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[iins->mSrc[0].mTemp]));
int address = iins->mSrc[1].mIntConst + wins->mSrc[1].mIntConst;
int address = int(iins->mSrc[1].mIntConst + wins->mSrc[1].mIntConst);
uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile)
@ -7037,7 +7037,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
for (int i = 0; i < size; i++)
{
CheckFrameIndex(ins, areg, index, i * stride);
CheckFrameIndex(ins, areg, index, 1);
if (reg == areg)
accu = true;
@ -7287,7 +7287,7 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
#endif
int sreg, dreg;
int si = 0, di = 0;
if (ins->mSrc[0].mTemp < 0)
{
@ -7330,14 +7330,22 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
else if (ins->mSrc[0].mIntConst != 0)
{
int index = int(ins->mSrc[0].mIntConst);
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
if (size <= msize && (size - 1) * sstride + 1 + index <= 256)
{
si = index;
sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
}
else
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
sreg = BC_REG_ACCU;
}
}
else if (size * sstride > 256 && !ins->mSrc[0].mFinal)
{
@ -7406,14 +7414,22 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
else if (ins->mSrc[1].mIntConst != 0)
{
int index = int(ins->mSrc[1].mIntConst);
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
if (size <= msize && (size - 1) * dstride + 1 + index <= 256)
{
di = index;
dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
}
else
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
}
else if (size * dstride > 256 && !ins->mSrc[1].mFinal)
{
@ -7430,8 +7446,6 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
if (size <= msize)
{
int si = 0;
int di = 0;
for (int i = 0; i < size; i++)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, si));
@ -16670,6 +16684,30 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
break;
}
else if (i + 4 == mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA &&
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 + 0].SameEffectiveAddress(mIns[i + 3]) &&
!(mIns[i + 3].mLive & LIVE_CPU_REG_A) &&
mExitRequiredRegs.Size() && !mExitRequiredRegs[CPU_REG_C] &&
(mBranch == ASMIT_BCC || mBranch == ASMIT_BCS))
{
mIns[i + 3].mType = ASMIT_INC;
mIns[i + 3].mLive |= LIVE_CPU_REG_Z;
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
if (mBranch == ASMIT_BCC)
mBranch = ASMIT_BNE;
else
mBranch = ASMIT_BEQ;
changed = true;
break;
}
#endif
#if 1
if (i + 6 < mIns.Size())
@ -17873,6 +17911,31 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
}
if (mIns.Size() >= 3 && mFalseJump && mBranch == ASMIT_BCC && mExitRequiredRegs.Size())
{
int sz = mIns.Size();
if (mIns[sz - 3].mType == ASMIT_LDA &&
mIns[sz - 2].mType == ASMIT_ADC && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 &&
mIns[sz - 1].mType == ASMIT_STA && mIns[sz - 1].SameEffectiveAddress(mIns[sz - 3]) &&
HasAsmInstructionMode(ASMIT_INC, mIns[sz - 1].mMode) &&
!(mIns[sz - 1].mLive & LIVE_CPU_REG_A) && !mExitRequiredRegs[CPU_REG_C])
{
NativeCodeBasicBlock* tblock = this->SplitAt(sz - 3);
tblock->mBranch = ASMIT_BNE;
tblock->mIns[0].mType = ASMIT_INC;
tblock->mIns.SetSize(1);
mBranch = ASMIT_BCC;
mFalseJump = tblock;
mTrueJump = tblock->mTrueJump;
mTrueJump->mNumEntries++;
mTrueJump->mEntryBlocks.Push(this);
changed = true;
}
}
if (mIns.Size() >= 8 && mFalseJump && (mBranch == ASMIT_BNE || mBranch == ASMIT_BEQ))
{
int sz = mIns.Size();
@ -27210,7 +27273,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 2].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true, false))
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true, true))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true))
@ -27236,7 +27299,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 1].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, false))
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, true))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
@ -42726,7 +42789,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_builtin");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -43519,13 +43582,13 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->CheckBlocks();
#endif
#if 1
ResetVisited();
if (mEntryBlock->PeepHoleOptimizer(this, step))
changed = true;
#endif
if (step == 2)
{
ResetVisited();