Optimize byte size right shift

This commit is contained in:
drmortalwombat 2022-01-12 15:54:50 +01:00
parent 180e2598b8
commit d9946e12b9
3 changed files with 267 additions and 75 deletions

View File

@ -3897,6 +3897,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
} }
} }
} }
else if (ins->mSrc[1].mTemp >= 0)
vr = mLocalValueRange[ins->mSrc[1].mTemp];
else else
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND; vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
break; break;

View File

@ -6768,6 +6768,34 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f)); mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f));
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
if (ins->mSrc[1].IsUByte())
{
if (ins->mSrc[1].mTemp < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff));
}
else if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg));
}
mIns.Push(NativeCodeInstruction(ASMIT_CPX, ASMIM_IMMEDIATE, 0x00));
this->Close(lblock, eblock, ASMIT_BNE);
lblock->mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
lblock->Close(lblock, eblock, ASMIT_BNE);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
else
{
if (ins->mSrc[1].mTemp < 0) if (ins->mSrc[1].mTemp < 0)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff));
@ -6795,6 +6823,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
lblock->Close(lblock, eblock, ASMIT_BNE); lblock->Close(lblock, eblock, ASMIT_BNE);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
return eblock; return eblock;
} }
} break; } break;
@ -9058,21 +9087,38 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
apos = j + 0; apos = j + 0;
int ireg = iins->mAddress; int ireg = iins->mAddress;
if (reg == ireg && !direct) if (reg == ireg)
{
if (!direct)
return false; return false;
flags = (LIVE_CPU_REG_X | LIVE_CPU_REG_Y) & ~mIns[j + 1].mLive;
int k = j + 7;
while (k < at)
{
if (mIns[k].ChangesYReg())
flags &= ~LIVE_CPU_REG_Y;
if (mIns[k].ChangesXReg())
flags &= ~LIVE_CPU_REG_X;
k++;
}
return flags != 0;
}
else
{
int k = j + 7; int k = j + 7;
while (k < at) while (k < at)
{ {
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false; return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++; k++;
} }
return true; return true;
} }
}
else if ( else if (
mIns[j + 0].mType == ASMIT_STA && mIns[j + 0].mMode == ASMIM_ZERO_PAGE && mIns[j + 0].mType == ASMIT_STA && mIns[j + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 1].mType == ASMIT_CLC && mIns[j + 1].mType == ASMIT_CLC &&
@ -9087,21 +9133,38 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
apos = j + 1; apos = j + 1;
int ireg = iins->mAddress; int ireg = iins->mAddress;
if (reg == ireg && !direct) if (reg == ireg)
{
if (!direct)
return false; return false;
flags = (LIVE_CPU_REG_X | LIVE_CPU_REG_Y) & ~mIns[j + 1].mLive;
int k = j + 7;
while (k < at)
{
if (mIns[k].ChangesYReg())
flags &= ~LIVE_CPU_REG_Y;
if (mIns[k].ChangesXReg())
flags &= ~LIVE_CPU_REG_X;
k++;
}
return flags != 0;
}
else
{
int k = j + 7; int k = j + 7;
while (k < at) while (k < at)
{ {
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false; return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++; k++;
} }
return true; return true;
} }
}
else if (mIns[j + 0].mType == ASMIT_CLC && else if (mIns[j + 0].mType == ASMIT_CLC &&
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[j + 1].mFlags & NCIF_LOWER) && mIns[j + 1].mLinkerObject && mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[j + 1].mFlags & NCIF_LOWER) && mIns[j + 1].mLinkerObject &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ABSOLUTE && mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ABSOLUTE &&
@ -9175,21 +9238,38 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
addr = mIns[j + 2].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress); addr = mIns[j + 2].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress);
int ireg = iins->mAddress; int ireg = iins->mAddress;
if (reg == ireg && !direct) if (reg == ireg)
{
if (!direct)
return false; return false;
flags = (LIVE_CPU_REG_X | LIVE_CPU_REG_Y) & ~mIns[j + 1].mLive;
int k = j + 7;
while (k < at)
{
if (mIns[k].ChangesYReg())
flags &= ~LIVE_CPU_REG_Y;
if (mIns[k].ChangesXReg())
flags &= ~LIVE_CPU_REG_X;
k++;
}
return flags != 0;
}
else
{
int k = j + 7; int k = j + 7;
while (k < at) while (k < at)
{ {
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false; return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++; k++;
} }
return true; return true;
} }
}
else if (mIns[j + 0].mType == ASMIT_CLC && else if (mIns[j + 0].mType == ASMIT_CLC &&
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_IMMEDIATE && mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_IMMEDIATE &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE && mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
@ -9205,21 +9285,38 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
addr = mIns[j + 1].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress); addr = mIns[j + 1].mAddress + 256 * (mIns[j + 4].mAddress + mIns[j + 5].mAddress);
int ireg = iins->mAddress; int ireg = iins->mAddress;
if (reg == ireg && !direct) if (reg == ireg)
{
if (!direct)
return false; return false;
flags = (LIVE_CPU_REG_X | LIVE_CPU_REG_Y) & ~mIns[j + 1].mLive;
int k = j + 7;
while (k < at)
{
if (mIns[k].ChangesYReg())
flags &= ~LIVE_CPU_REG_Y;
if (mIns[k].ChangesXReg())
flags &= ~LIVE_CPU_REG_X;
k++;
}
return flags != 0;
}
else
{
int k = j + 7; int k = j + 7;
while (k < at) while (k < at)
{ {
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false; return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++; k++;
} }
return true; return true;
} }
}
else if ( else if (
mIns[j + 1].mType == ASMIT_CLC && mIns[j + 1].mType == ASMIT_CLC &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_IMMEDIATE && mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_IMMEDIATE &&
@ -9335,6 +9432,59 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, i
return false; return false;
} }
bool NativeCodeBasicBlock::PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr)
{
int yindex = 0;
int last = at;
while (last < mIns.Size())
{
if (mIns[last].mType == ASMIT_LDY && mIns[last].mMode == ASMIM_IMMEDIATE)
yindex = mIns[last].mAddress;
else if (mIns[last].ChangesYReg())
return false;
else if (mIns[last].mMode == ASMIM_ZERO_PAGE && (mIns[last].mAddress == reg || mIns[last].mAddress == reg + 1) && mIns[last].ChangesAddress())
return false;
else if (mIns[last].mMode == ASMIM_INDIRECT_Y && mIns[last].mAddress == reg)
{
if (!(mIns[last].mLive & LIVE_MEM))
break;
}
else if (mIns[last].RequiresXReg())
return false;
last++;
}
if (last == mIns.Size())
return false;
yindex = 0;
for (int i = at; i <= last; i++)
{
mIns[i].mLive | LIVE_CPU_REG_X;
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
yindex = mIns[i].mAddress;
else if (mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i].mAddress == reg)
{
mIns[i].mMode = ASMIM_ABSOLUTE_X;
if (ains.mMode == ASMIM_IMMEDIATE)
{
mIns[i].mLinkerObject = nullptr;
mIns[i].mAddress = addr + yindex;
}
else
{
mIns[i].mLinkerObject = ains.mLinkerObject;
mIns[i].mAddress = ains.mAddress + yindex;
}
}
}
return true;
}
bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int breg) bool NativeCodeBasicBlock::PatchDirectAddressSumY(int at, int reg, int apos, int breg)
{ {
int yindex = 0; int yindex = 0;
@ -12059,14 +12209,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
} }
if (iins || (flags & LIVE_CPU_REG_Y)) if (flags & LIVE_CPU_REG_Y)
{ {
mIns[i + 0].mMode = ASMIM_ABSOLUTE_Y; mIns[i + 0].mMode = ASMIM_ABSOLUTE_Y;
} }
else else if (flags & LIVE_CPU_REG_X)
{ {
mIns[i + 0].mMode = ASMIM_ABSOLUTE_X; mIns[i + 0].mMode = ASMIM_ABSOLUTE_X;
} }
else
{
mIns[i + 0].mMode = ASMIM_ABSOLUTE_Y;
}
if (ains->mMode == ASMIM_IMMEDIATE) if (ains->mMode == ASMIM_IMMEDIATE)
{ {
@ -12092,9 +12247,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
else else
{ {
PatchGlobalAdressSumYByX(i + 1, sreg, *ains, addr);
mIns.Insert(apos, NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); mIns.Insert(apos, NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A; mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A;
for (int j = apos; j < i + 1; j++) for (int j = apos; j < i + 2; j++)
mIns[j].mLive |= LIVE_CPU_REG_X; mIns[j].mLive |= LIVE_CPU_REG_X;
} }
} }
@ -12103,9 +12259,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
if (iins->mMode != ASMIM_ZERO_PAGE) if (iins->mMode != ASMIM_ZERO_PAGE)
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, iins->mMode, iins->mAddress, iins->mLinkerObject, iins->mFlags)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, iins->mMode, iins->mAddress, iins->mLinkerObject, iins->mFlags));
else if (iins->mAddress == sreg) else if (iins->mAddress == sreg)
{
if (flags & LIVE_CPU_REG_Y)
{ {
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress)); mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress));
mIns[apos].mLive = LIVE_CPU_REG_Y | LIVE_MEM; mIns[apos].mLive = LIVE_CPU_REG_Y | LIVE_CPU_REG_A | LIVE_MEM;
for (int j = apos; j < i + 2; j++)
mIns[j].mLive |= LIVE_CPU_REG_Y;
}
else
{
PatchGlobalAdressSumYByX(i + 1, sreg, *ains, addr);
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, iins->mAddress));
mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A | LIVE_MEM;
for (int j = apos; j < i + 2; j++)
mIns[j].mLive |= LIVE_CPU_REG_X;
}
i++;
} }
else else
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress));
@ -12440,14 +12610,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
} }
if (iins || (flags & LIVE_CPU_REG_Y)) if (flags & LIVE_CPU_REG_Y)
{ {
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
} }
else else if (flags & LIVE_CPU_REG_X)
{ {
mIns[i + 1].mMode = ASMIM_ABSOLUTE_X; mIns[i + 1].mMode = ASMIM_ABSOLUTE_X;
} }
else
{
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
}
if (ains->mMode == ASMIM_IMMEDIATE) if (ains->mMode == ASMIM_IMMEDIATE)
{ {
@ -12472,6 +12646,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
else else
{ {
PatchGlobalAdressSumYByX(i + 1, sreg, *ains, addr);
mIns.Insert(apos, NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); mIns.Insert(apos, NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A; mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A;
for (int j = apos; j < i + 2; j++) for (int j = apos; j < i + 2; j++)
@ -12488,8 +12663,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
else if (iins->mAddress == sreg) else if (iins->mAddress == sreg)
{ {
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
if (flags & LIVE_CPU_REG_Y)
{
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress)); mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, iins->mAddress));
mIns[apos].mLive = LIVE_CPU_REG_Y | LIVE_MEM; mIns[apos].mLive = LIVE_CPU_REG_Y | LIVE_CPU_REG_A | LIVE_MEM;
for (int j = apos; j < i + 2; j++)
mIns[j].mLive |= LIVE_CPU_REG_Y;
}
else
{
PatchGlobalAdressSumYByX(i + 1, sreg, *ains, addr);
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, iins->mAddress));
mIns[apos].mLive = LIVE_CPU_REG_X | LIVE_CPU_REG_A | LIVE_MEM;
for (int j = apos; j < i + 2; j++)
mIns[j].mLive |= LIVE_CPU_REG_X;
}
} }
else else
{ {

View File

@ -222,6 +222,8 @@ public:
bool MoveAddHighByteDown(int at); bool MoveAddHighByteDown(int at);
bool ReverseLoadCommutativeOpUp(int aload, int aop); bool ReverseLoadCommutativeOpUp(int aload, int aop);
bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr);
bool ValueForwarding(const NativeRegisterDataSet& data, bool global); bool ValueForwarding(const NativeRegisterDataSet& data, bool global);
void CollectEntryBlocks(NativeCodeBasicBlock* block); void CollectEntryBlocks(NativeCodeBasicBlock* block);