Fix TAXA range bypass with trailing multi store

This commit is contained in:
drmortalwombat 2025-04-08 18:22:45 +02:00
parent 6de1b1fd96
commit 94f2489083
2 changed files with 91 additions and 22 deletions

View File

@ -667,21 +667,19 @@ L1: rol accu
sbc tmp + 1 sbc tmp + 1
lda tmp + 6 lda tmp + 6
sbc tmp + 2 sbc tmp + 2
tax
lda tmp + 7 lda tmp + 7
sbc tmp + 3 sbc tmp + 3
bcc W1 bcc W1
stx tmp + 6
sta tmp + 7
lda tmp + 4 lda tmp + 4
sbc tmp + 0 sbc tmp + 0
sta tmp + 4 sta tmp + 4
lda tmp + 5 lda tmp + 5
sbc tmp + 1 sbc tmp + 1
sta tmp + 5 sta tmp + 5
lda tmp + 6 sec
sbc tmp + 2
sta tmp + 6
lda tmp + 7
sbc tmp + 3
sta tmp + 7
W1: dey W1: dey
bne L1 bne L1
rol accu rol accu

View File

@ -9697,6 +9697,16 @@ static int Binlog(unsigned n)
return k; return k;
} }
static unsigned BinMask(unsigned n)
{
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n;
}
void NativeCodeBasicBlock::AddAsrSignedByte(InterCodeProcedure* proc, const InterInstruction* ains, const InterInstruction* sins) void NativeCodeBasicBlock::AddAsrSignedByte(InterCodeProcedure* proc, const InterInstruction* ains, const InterInstruction* sins)
{ {
mIns.Push(NativeCodeInstruction(ains, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ains->mSrc[1].mTemp])); mIns.Push(NativeCodeInstruction(ains, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ains->mSrc[1].mTemp]));
@ -31191,11 +31201,26 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
{ {
if (mIns[to + 1].mType == ASMIT_ORA && mIns[to + 1].mMode == ASMIM_IMMEDIATE) if (mIns[to + 1].mType == ASMIT_ORA && mIns[to + 1].mMode == ASMIM_IMMEDIATE)
{ {
mIns[to + 0].mType = ASMIT_NOP; mIns[to + 0].mMode = ASMIM_IMPLIED; if (mIns[to + 2].mLive & LIVE_CPU_REG_A)
mIns[to + 1].mType = ASMIT_NOP; mIns[to + 1].mMode = ASMIM_IMPLIED; {
mIns[to + 2].mType = ASMIT_STX; if (to + 3 < mIns.Size() && mIns[to + 3].mType == ASMIT_STA && HasAsmInstructionMode(ASMIT_STX, mIns[to + 3].mMode) && !(mIns[to + 3].mLive & LIVE_CPU_REG_A))
mIns.Insert(from, NativeCodeInstruction(mIns[to + 0].mIns, ASMIT_ORA, ASMIM_IMMEDIATE, mIns[to + 1].mAddress)); {
return true; mIns[to + 0].mType = ASMIT_NOP; mIns[to + 0].mMode = ASMIM_IMPLIED;
mIns[to + 1].mType = ASMIT_NOP; mIns[to + 1].mMode = ASMIM_IMPLIED;
mIns[to + 2].mType = ASMIT_STX; mIns[to + 2].mLive |= LIVE_CPU_REG_X;
mIns[to + 3].mType = ASMIT_STX;
mIns.Insert(from, NativeCodeInstruction(mIns[to + 0].mIns, ASMIT_ORA, ASMIM_IMMEDIATE, mIns[to + 1].mAddress));
return true;
}
}
else
{
mIns[to + 0].mType = ASMIT_NOP; mIns[to + 0].mMode = ASMIM_IMPLIED;
mIns[to + 1].mType = ASMIT_NOP; mIns[to + 1].mMode = ASMIM_IMPLIED;
mIns[to + 2].mType = ASMIT_STX;
mIns.Insert(from, NativeCodeInstruction(mIns[to + 0].mIns, ASMIT_ORA, ASMIM_IMMEDIATE, mIns[to + 1].mAddress));
return true;
}
} }
} }
@ -36551,8 +36576,33 @@ bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
break; break;
} }
} }
else if (lins.mType == ASMIT_CMP && lins.mMode == ASMIM_IMMEDIATE)
{
switch (mBranch)
{
case ASMIT_BCS:
{
unsigned m = ~BinMask(lins.mAddress - 1) & 0xff;
mFDataSet.mRegs[CPU_REG_A].mMask |= m;
mFDataSet.mRegs[CPU_REG_A].mValue &= ~m;
m = ~BinMask(~lins.mAddress & 0xff) & 0xff;
mNDataSet.mRegs[CPU_REG_A].mMask |= m;
mNDataSet.mRegs[CPU_REG_A].mValue |= m;
}
break;
case ASMIT_BCC:
{
unsigned m = ~BinMask(lins.mAddress - 1) & 0xff;
mNDataSet.mRegs[CPU_REG_A].mMask |= m;
mNDataSet.mRegs[CPU_REG_A].mValue &= ~m;
m = ~BinMask(~lins.mAddress & 0xff) & 0xff;
mFDataSet.mRegs[CPU_REG_A].mMask |= m;
mFDataSet.mRegs[CPU_REG_A].mValue |= m;
}
break;
}
}
} }
} }
assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size()); assert(mIndex == 1000 || mNumEntries == mEntryBlocks.Size());
@ -40268,15 +40318,25 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
mIns[i + 1].mMode = ASMIM_ABSOLUTE_X; mIns[i + 1].mMode = ASMIM_ABSOLUTE_X;
changed = true; changed = true;
} }
else if (mIns[i].mType == ASMIT_LDY && HasAsmInstructionMode(ASMIT_LDX, mIns[i].mMode) && !(mIns[i].mLive & LIVE_CPU_REG_X) && mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y && HasAsmInstructionMode(mIns[i + 1].mType, ASMIM_ABSOLUTE_X) && !(mIns[i + 1].mLive & LIVE_CPU_REG_Y)) else if (mIns[i].mType == ASMIT_LDY && HasAsmInstructionMode(ASMIT_LDX, mIns[i].mMode) && !(mIns[i].mLive & LIVE_CPU_REG_X))
{ {
mIns[i].mType = ASMIT_LDX; mIns[i].mLive |= LIVE_CPU_REG_X; mIns[i].mLive &= ~LIVE_CPU_REG_Y; int j = i + 1;
mIns[i + 1].mMode = ASMIM_ABSOLUTE_X; while (j < mIns.Size() && !mIns[j].ReferencesXReg() && !mIns[j].ReferencesYReg() && !mIns[j].ChangesGlobalMemory())
changed = true; j++;
if (j < mIns.Size() && mIns[j].mMode == ASMIM_ABSOLUTE_Y && HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_X) && !(mIns[j].mLive & LIVE_CPU_REG_Y))
{
mIns[i].mType = ASMIT_LDX;
mIns[j].mMode = ASMIM_ABSOLUTE_X;
while (j > i)
{
j--;
mIns[j].mLive |= LIVE_CPU_REG_X; mIns[j].mLive &= ~LIVE_CPU_REG_Y;
}
changed = true;
}
} }
} }
} }
else if (xindex && xother) else if (xindex && xother)
{ {
for (int i = 0; i < sz-3; i++) for (int i = 0; i < sz-3; i++)
@ -40289,11 +40349,22 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
changed = true; changed = true;
} }
else if (mIns[i].mType == ASMIT_LDX && HasAsmInstructionMode(ASMIT_LDY, mIns[i].mMode) && !(mIns[i].mLive & LIVE_CPU_REG_Y) && mIns[i + 1].mMode == ASMIM_ABSOLUTE_X && HasAsmInstructionMode(mIns[i + 1].mType, ASMIM_ABSOLUTE_Y) && !(mIns[i + 1].mLive & LIVE_CPU_REG_X)) else if (mIns[i].mType == ASMIT_LDX && HasAsmInstructionMode(ASMIT_LDY, mIns[i].mMode) && !(mIns[i].mLive & LIVE_CPU_REG_Y))
{ {
mIns[i].mType = ASMIT_LDY; mIns[i].mLive |= LIVE_CPU_REG_Y; mIns[i].mLive &= ~LIVE_CPU_REG_X; int j = i + 1;
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; while (j < mIns.Size() && !mIns[j].ReferencesXReg() && !mIns[j].ReferencesYReg() && !mIns[j].ChangesGlobalMemory())
changed = true; j++;
if (j < mIns.Size() && mIns[j].mMode == ASMIM_ABSOLUTE_X && HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_Y) && !(mIns[j].mLive & LIVE_CPU_REG_X))
{
mIns[i].mType = ASMIT_LDY;
mIns[j].mMode = ASMIM_ABSOLUTE_Y;
while (j > i)
{
j--;
mIns[j].mLive |= LIVE_CPU_REG_Y; mIns[j].mLive &= ~LIVE_CPU_REG_X;
}
changed = true;
}
} }
} }
} }
@ -53502,7 +53573,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc->mLinkerObject->mNativeProc = this; mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mIdent->mString, "enemies_iterate"); CheckFunc = !strcmp(mIdent->mString, "main");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];