More promotion of abs and abs indexed when only single use
This commit is contained in:
parent
51d447618b
commit
7e458d1eda
|
@ -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++)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins1->mSrc[0].mIntConst + i));
|
if (rins1->mSrc[0].mIntConst == wins->mSrc[1].mIntConst && rins0->mSrc[0].mIntConst != wins->mSrc[1].mIntConst)
|
||||||
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_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins0->mSrc[0].mTemp]));
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins0->mSrc[0].mIntConst + i));
|
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[rins0->mSrc[0].mTemp]));
|
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_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_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,9 +10071,9 @@ 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);
|
||||||
return true;
|
if (!(ins.mLive & LIVE_MEM))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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--;
|
ecount--;
|
||||||
|
spr_show(2 + i, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spr_move(2 + i, rx + 24, enemies[i].py + 50);
|
||||||
|
|
||||||
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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue