More promotion of abs and abs indexed when only single use

This commit is contained in:
drmortalwombat 2022-03-03 19:23:47 +01:00
parent 51d447618b
commit 7e458d1eda
3 changed files with 153 additions and 26 deletions

View File

@ -4248,14 +4248,24 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
return false; return false;
} }
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{
if (rins1->mSrc[0].mIntConst == wins->mSrc[1].mIntConst && rins0->mSrc[0].mIntConst != wins->mSrc[1].mIntConst)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins0->mSrc[0].mIntConst + i));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins0->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins1->mSrc[0].mIntConst + i));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins1->mSrc[0].mTemp]));
}
else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins1->mSrc[0].mIntConst + i)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins1->mSrc[0].mIntConst + i));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins1->mSrc[0].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins1->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins0->mSrc[0].mIntConst + i)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins0->mSrc[0].mIntConst + i));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins0->mSrc[0].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins0->mSrc[0].mTemp]));
}
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst + i)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst + i));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
@ -9968,7 +9978,7 @@ bool NativeCodeBasicBlock::FindImmediateStore(int at, int reg, const NativeCodeI
return false; return false;
} }
bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains) bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains, int cycles)
{ {
if (!mPatched) if (!mPatched)
{ {
@ -9993,14 +10003,25 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const Nativ
{ {
if (ins.ChangesAddress()) if (ins.ChangesAddress())
return false; return false;
return !(ins.mLive & LIVE_MEM); if (!HasAsmInstructionMode(ins.mType, ains.mMode))
return false;
if (ins.mLive & LIVE_MEM)
{
cycles--;
if (cycles == 0)
return false;
}
else
return true;
} }
else else
return true; return true;
} }
else if (ins.mType == ASMIT_JSR) else if (ins.mType == ASMIT_JSR)
{ {
if (ins.mFlags & NCIF_RUNTIME) if (ains.mMode == ASMIM_ABSOLUTE_X || ains.mMode == ASMIM_ABSOLUTE_Y)
return false;
else if (ins.mFlags & NCIF_RUNTIME)
{ {
if (ins.UsesZeroPage(reg)) if (ins.UsesZeroPage(reg))
return false; return false;
@ -10008,6 +10029,10 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const Nativ
else else
return false; return false;
} }
else if (ains.mMode == ASMIM_ABSOLUTE_X && ins.ChangesXReg())
return false;
else if (ains.mMode == ASMIM_ABSOLUTE_Y && ins.ChangesYReg())
return false;
else if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress + 1 == reg)) else if (ins.mMode == ASMIM_INDIRECT_Y && (ins.mAddress == reg || ins.mAddress + 1 == reg))
return false; return false;
else if (ins.ChangesZeroPage(reg)) else if (ins.ChangesZeroPage(reg))
@ -10018,9 +10043,9 @@ bool NativeCodeBasicBlock::CheckSingleUseGlobalLoad(int reg, int at, const Nativ
at++; at++;
} }
if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoad(reg, 0, ains)) if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoad(reg, 0, ains, cycles))
return false; return false;
if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoad(reg, 0, ains)) if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoad(reg, 0, ains, cycles))
return false; return false;
} }
@ -10046,8 +10071,8 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(int reg, int at, const Nativ
{ {
if (ins.UsesAddress()) if (ins.UsesAddress())
{ {
assert(!(ins.mLive & LIVE_MEM));
ins.CopyMode(ains); ins.CopyMode(ains);
if (!(ins.mLive & LIVE_MEM))
return true; return true;
} }
@ -15940,6 +15965,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_CMP && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 2].mAddress &&
!(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_MEM)))
{
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_CMP; mIns[i + 1].mLive |= LIVE_CPU_REG_Z;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
#if 1 #if 1
if ( if (
@ -16747,11 +16784,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (i + 1 < mIns.Size()) if (i + 1 < mIns.Size())
{ {
if ( if (
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE && mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y) &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (CheckSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i])) if (CheckSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i], 3))
{ {
proc->ResetPatched(); proc->ResetPatched();
if (PatchSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i])) if (PatchSingleUseGlobalLoad(mIns[i + 1].mAddress, i + 2, mIns[i]))
@ -16898,6 +16935,26 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true; progress = true;
} }
} }
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y &&
mIns[i + 2].mType == ASMIT_CLC &&
mIns[i + 3].mType == ASMIT_LDY && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 4].mLive & LIVE_CPU_REG_Y))
{
int j = i + 5;
while (j < mIns.Size() && !mIns[j].ChangesYReg())
j++;
if (j < mIns.Size() && mIns[j].mType == ASMIT_LDY && mIns[j].mMode == ASMIM_IMMEDIATE && mIns[j].mAddress == mIns[i + 0].mAddress)
{
int reg = mIns[1].mAddress; mIns[1].mAddress = mIns[4].mAddress; mIns[4].mAddress = reg;
int yr = mIns[0].mAddress; mIns[0].mAddress = mIns[3].mAddress; mIns[3].mAddress = yr;
mIns[1].mLive |= LIVE_MEM;
mIns[4].mLive |= LIVE_MEM;
progress = true;
}
}
#endif #endif
} }

View File

@ -279,7 +279,7 @@ public:
bool CheckGlobalAddressSumYPointer(int reg, int at, int yval); bool CheckGlobalAddressSumYPointer(int reg, int at, int yval);
bool PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject * lobj, int address); bool PatchGlobalAddressSumYPointer(int reg, int at, int yval, LinkerObject * lobj, int address);
bool CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains); bool CheckSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains, int cycles);
bool PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains); bool PatchSingleUseGlobalLoad(int reg, int at, const NativeCodeInstruction& ains);
bool CheckForwardSumYPointer(int reg, int base, int index, int at, int yval); bool CheckForwardSumYPointer(int reg, int base, int index, int at, int yval);

View File

@ -31,8 +31,10 @@ char spriteset[4096] = {
char xtileset[16][64]; char xtileset[16][64];
char xtilemap[144 * 5]; char xtilemap[144 * 5];
char stars[24]; char stars[24];
char xcollision[256];
#pragma align(xtileset, 64); #pragma align(xtileset, 64);
#pragma align(xcollision, 256)
void tiles_unpack(void) void tiles_unpack(void)
{ {
@ -49,6 +51,12 @@ void tiles_unpack(void)
xtilemap[y * 144 + x] = tilemap[y * 128 + (x & 127)]; xtilemap[y * 144 + x] = tilemap[y * 128 + (x & 127)];
} }
} }
for(char i=0; i<160; i+=40)
{
for(char j=0; j<3; j++)
xcollision[i + j] = 1;
}
} }
void tiles_draw0(char * dp, char * tm) void tiles_draw0(char * dp, char * tm)
@ -343,6 +351,7 @@ struct Enemy
int px; int px;
byte py; byte py;
sbyte dx; sbyte dx;
byte state, pad0, pad1, pad2;
} enemies[5]; } enemies[5];
int spx = 40; int spx = 40;
@ -357,18 +366,36 @@ void enemies_move(void)
{ {
for(char i=0; i<5; i++) for(char i=0; i<5; i++)
{ {
if (enemies[i].dx) if (enemies[i].state)
{ {
enemies[i].px += enemies[i].dx; enemies[i].px += enemies[i].dx;
int rx = enemies[i].px - spx; int rx = enemies[i].px - spx;
if (rx < -192 || rx >= 480) if (rx < -192 || rx >= 480)
{ {
enemies[i].dx = 0; enemies[i].state = 0;
ecount--;
spr_show(2 + i, false);
}
else
{
spr_move(2 + i, rx + 24, enemies[i].py + 50);
if (enemies[i].state & 0x80)
{
}
else
{
spr_image(2 + i, 127 - (enemies[i].state >> 2));
enemies[i].state--;
if (enemies[i].state == 0)
{
spr_show(2 + i, false);
ecount--; ecount--;
} }
}
spr_move(2 + i, rx + 24, enemies[i].py + 50); }
} }
} }
} }
@ -382,9 +409,10 @@ void enemies_spawn(void)
__assume(e < 5); __assume(e < 5);
sbyte v = 1 + (u & 3); sbyte v = 1 + (u & 3);
enemies[ecount].py = 20 + 30 * e; enemies[ecount].py = 21 + 32 * e;
enemies[ecount].dx = vpx < 0 ? v : -v; enemies[ecount].dx = vpx < 0 ? v : -v;
enemies[ecount].px = (vpx < 0 ? spx - 56 : spx + 320) + ((u >> 1) & 31); enemies[ecount].px = (vpx < 0 ? spx - 56 : spx + 320) + ((u >> 1) & 31);
enemies[ecount].state = 0x80;
int rx = enemies[ecount].px - spx; int rx = enemies[ecount].px - spx;
@ -392,6 +420,43 @@ void enemies_spawn(void)
ecount++; ecount++;
} }
void shots_check(void)
{
Shot * ps = shots;
for(char i=0; i<5; i++)
{
if (enemies[i].state & 0x80)
{
sbyte rx = (enemies[i].px - spx) >> 3;
if (rx >= 0 && rx < 40)
{
Shot * ss = ps->next;
while (ss->ty < i)
{
ps = ss;
ss = ps->next;
}
while (ss->ty == i)
{
if (xcollision[(char)(ss->x - rx)])
{
ps->next = ss->next;
ss->next = freeShot;
freeShot = ss;
enemies[i].state = 64;
break;
}
ps = ss;
ss = ps->next;
}
}
}
}
}
int main(void) int main(void)
{ {
cia_init(); cia_init();
@ -498,15 +563,19 @@ int main(void)
spr_move(0, 172 - 4 * vpx, 50 + spy); spr_move(0, 172 - 4 * vpx, 50 + spy);
spr_move(7, 180 - 4 * vpx, 58 + spy); spr_move(7, 180 - 4 * vpx, 58 + spy);
vic.color_border++; vic.color_border = VCOL_BLACK;
vic_waitLine(82); vic_waitTop();
vic.color_border++; while (vic.raster < 82)
;
vic.color_border = VCOL_BLUE;
tiles_draw(spx & 4095); tiles_draw(spx & 4095);
vic.color_border--; vic.color_border = VCOL_WHITE;
if (edelay) if (edelay)
{ {
edelay--; edelay--;
if (edelay < 5) if (edelay < 10 && !(edelay & 1))
enemies_spawn(); enemies_spawn();
} }
else else
@ -515,7 +584,8 @@ int main(void)
if (!ecount) if (!ecount)
edelay = 64 + (rand() & 63); edelay = 64 + (rand() & 63);
} }
vic.color_border--;
shots_check();
spx += vpx >> 2; spx += vpx >> 2;
} }