Optimizing byte code generator
This commit is contained in:
parent
417f65e2c2
commit
f50eb7cd19
|
@ -45,12 +45,37 @@ void reverseb(int * d, const int * s, char n)
|
||||||
d[i] = s[n - i - 1];
|
d[i] = s[n - i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long suml(long * a, char s)
|
||||||
|
{
|
||||||
|
long sum = 0;
|
||||||
|
for(char i=0; i<s; i++)
|
||||||
|
{
|
||||||
|
sum += a[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyl(long * d, const long * s, char n)
|
||||||
|
{
|
||||||
|
for(char i=0; i<n ; i++)
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void reversel(long * d, const long * s, char n)
|
||||||
|
{
|
||||||
|
for(char i=0; i<n ; i++)
|
||||||
|
d[i] = s[n - i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int a[100], b[100], c[100];
|
int a[100], b[100], c[100];
|
||||||
|
long al[100], bl[100], cl[100];
|
||||||
|
|
||||||
for(int i=0; i<100; i++)
|
for(int i=0; i<100; i++)
|
||||||
{
|
{
|
||||||
a[i] = i % 10;
|
a[i] = i % 10;
|
||||||
|
al[i] = i % 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sum(a, 100) == 450);
|
assert(sum(a, 100) == 450);
|
||||||
|
@ -65,5 +90,13 @@ int main(void)
|
||||||
reverseb(c, a, 100);
|
reverseb(c, a, 100);
|
||||||
assert(sumb(c, 100) == 450);
|
assert(sumb(c, 100) == 450);
|
||||||
|
|
||||||
|
assert(suml(al, 100) == 450);
|
||||||
|
|
||||||
|
copyl(bl, al, 100);
|
||||||
|
assert(suml(bl, 100) == 450);
|
||||||
|
|
||||||
|
reversel(cl, al, 100);
|
||||||
|
assert(suml(cl, 100) == 450);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,7 +571,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
case BC_STORE_ADDR_32:
|
case BC_STORE_ADDR_32:
|
||||||
fprintf(file, "MOV\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
|
fprintf(file, "MOVD\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc));
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -542,6 +542,17 @@ bool NativeCodeInstruction::RequiresYReg(void) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::RequiresXReg(void) const
|
||||||
|
{
|
||||||
|
if (mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_INDIRECT_X || mMode == ASMIM_ZERO_PAGE_X)
|
||||||
|
return true;
|
||||||
|
if (mType == ASMIT_TXA || mType == ASMIT_STX || mType == ASMIT_CPX || mType == ASMIT_INX || mType == ASMIT_DEX)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeInstruction::ChangesYReg(void) const
|
bool NativeCodeInstruction::ChangesYReg(void) const
|
||||||
{
|
{
|
||||||
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR;
|
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR;
|
||||||
|
@ -9133,13 +9144,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
//
|
//
|
||||||
// move ldy down
|
// move ldx/y down
|
||||||
|
|
||||||
for (int i = 0; i + 1 < mIns.Size(); i++)
|
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
|
if (mIns[i].mType == ASMIT_LDY)
|
||||||
{
|
{
|
||||||
if (!mIns[i + 1].RequiresYReg() && !mIns[i + 1].ChangesYReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
if (!mIns[i + 1].RequiresYReg() && !mIns[i + 1].ChangesYReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_IMMEDIATE || !mIns[i + 1].ChangesAddress())
|
||||||
{
|
{
|
||||||
NativeCodeInstruction ins = mIns[i];
|
NativeCodeInstruction ins = mIns[i];
|
||||||
mIns[i] = mIns[i + 1];
|
mIns[i] = mIns[i + 1];
|
||||||
|
@ -9148,6 +9161,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (!mIns[i + 1].RequiresXReg() && !mIns[i + 1].ChangesXReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_IMMEDIATE || !mIns[i + 1].ChangesAddress())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction ins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = ins;
|
||||||
|
mIns[i + 1].mLive |= mIns[i].mLive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -9440,6 +9467,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 1].mLive & (LIVE_MEM | LIVE_CPU_REG_A)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDA;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mType = ASMIT_ASL;
|
||||||
|
mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_TAY, ASMIM_IMPLIED));
|
||||||
|
mIns[i + 2].mLive = mIns[i + 1].mLive;
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TXA &&
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
|
@ -9512,7 +9554,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDY && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TYA && !(mIns[i + 1].mLive & LIVE_CPU_REG_Y))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDX && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TXA && !(mIns[i + 1].mLive & LIVE_CPU_REG_X))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mLive |= mIns[i + 1].mLive;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
(mIns[i + 0].mType == ASMIT_ASL || mIns[i + 0].mType == ASMIT_LSR || mIns[i + 0].mType == ASMIT_ROL || mIns[i + 0].mType == ASMIT_ROR) && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
(mIns[i + 0].mType == ASMIT_ASL || mIns[i + 0].mType == ASMIT_LSR || mIns[i + 0].mType == ASMIT_ROL || mIns[i + 0].mType == ASMIT_ROR) && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 0].mAddress && !(mIns[i + 1].mLive & LIVE_MEM))
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 0].mAddress && !(mIns[i + 1].mLive & LIVE_MEM))
|
||||||
|
@ -9524,6 +9583,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 0].mType = ASMIT_LDA;
|
mIns[i + 0].mType = ASMIT_LDA;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
else if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_INDIRECT_Y)
|
else if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_INDIRECT_Y)
|
||||||
{
|
{
|
||||||
|
@ -9575,7 +9636,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
{
|
{
|
||||||
mIns[i + 0].mType = ASMIT_NOP;
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
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;
|
mIns[apos].mLive = LIVE_CPU_REG_Y | LIVE_MEM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -9825,6 +9886,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
|
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
|
||||||
|
mIns[i + 2].mLive = mIns[i + 3].mLive | LIVE_CPU_REG_Y | LIVE_MEM;
|
||||||
mIns[i + 3].mAddress = breg;
|
mIns[i + 3].mAddress = breg;
|
||||||
}
|
}
|
||||||
progress = true;
|
progress = true;
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
bool ChangesCarry(void) const;
|
bool ChangesCarry(void) const;
|
||||||
bool RequiresAccu(void) const;
|
bool RequiresAccu(void) const;
|
||||||
bool RequiresYReg(void) const;
|
bool RequiresYReg(void) const;
|
||||||
|
bool RequiresXReg(void) const;
|
||||||
bool ChangesYReg(void) const;
|
bool ChangesYReg(void) const;
|
||||||
bool ChangesXReg(void) const;
|
bool ChangesXReg(void) const;
|
||||||
bool ChangesZeroPage(int address) const;
|
bool ChangesZeroPage(int address) const;
|
||||||
|
|
Loading…
Reference in New Issue