Byte operand sizes fixes and optimizations

This commit is contained in:
drmortalwombat 2021-09-22 22:49:52 +02:00
parent 2cd9a55880
commit 4ca77ba41a
8 changed files with 449 additions and 257 deletions

48
autotest/switchlooptest.c Normal file
View File

@ -0,0 +1,48 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char text[14];
for(char i=0; i<12; i++)
{
switch (i)
{
case 0:
text[i] = 'H';
break;
case 1:
text[i] = 'E';
break;
case 2:
case 3:
case 9:
text[i] = 'L';
break;
case 4:
case 7:
text[i] = 'O';
break;
case 5:
text[i] = ' ';
break;
case 6:
text[i] = 'W';
break;
case 8:
text[i] = 'R';
break;
case 10:
text[i] = 'D';
break;
default:
text[i] = 0;
}
}
printf("<%s>\n", text);
return 0;
}

View File

@ -287,7 +287,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
{ {
const char * p = fmt; const char * p = fmt;
char c; char c;
int bi = 0; char bi = 0;
sinfo si; sinfo si;
while (c = *p++) while (c = *p++)

View File

@ -47,6 +47,7 @@ ByteCodeInstruction::ByteCodeInstruction(ByteCode code)
{ {
} }
bool ByteCodeInstruction::IsStore(void) const bool ByteCodeInstruction::IsStore(void) const
{ {
return return
@ -2506,241 +2507,259 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), nullptr, BC_JUMPS); this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), nullptr, BC_JUMPS);
} }
void ByteCodeBasicBlock::PeepHoleOptimizer(void)
bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
{ {
int accuReg = -1; bool changed = false;
bool progress = false; if (!mVisited)
do { {
progress = false; mVisited = true;
int i = 0; int accuReg = -1;
int j = 0;
while (i < mIns.Size()) bool progress = false;
{ do {
if (mIns[i].mCode == BC_NOP) progress = false;
;
else int i = 0;
int j = 0;
while (i < mIns.Size())
{ {
if (i != j) if (mIns[i].mCode == BC_NOP)
mIns[j] = mIns[i]; ;
j++; else
{
if (i != j)
mIns[j] = mIns[i];
j++;
}
i++;
} }
i++; mIns.SetSize(j);
}
mIns.SetSize(j);
int accuTemp = -1, addrTemp = -1; int accuTemp = -1, addrTemp = -1;
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{
if (i + 2 < mIns.Size())
{ {
if (mIns[i].mCode == BC_LOAD_LOCAL_16 && if (i + 2 < mIns.Size())
mIns[i + 1].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mRegister != BC_REG_ACCU && mIns[i + 1].mRegister != mIns[i].mRegister &&
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 2].mRegister == mIns[i].mRegister && mIns[i + 2].mRegisterFinal)
{ {
mIns[i].mRegister = BC_REG_ACCU; if (mIns[i].mCode == BC_LOAD_LOCAL_16 &&
mIns[i + 2].mCode = BC_NOP; mIns[i + 1].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mRegister != BC_REG_ACCU && mIns[i + 1].mRegister != mIns[i].mRegister &&
progress = true; mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 2].mRegister == mIns[i].mRegister && mIns[i + 2].mRegisterFinal)
} {
else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i].mRegister = BC_REG_ACCU;
!mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && mIns[i + 2].mCode = BC_NOP;
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 2].mRegister) progress = true;
{ }
mIns[i + 2].mCode = BC_NOP; else if (mIns[i].mCode == BC_STORE_REG_16 &&
if (mIns[i + 2].mRegisterFinal) !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister &&
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 2].mRegister)
{
mIns[i + 2].mCode = BC_NOP;
if (mIns[i + 2].mRegisterFinal)
mIns[i].mCode = BC_NOP;
}
else if (mIns[i].mCode == BC_STORE_REG_32 &&
!mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister &&
mIns[i + 2].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 2].mRegister)
{
mIns[i + 2].mCode = BC_NOP;
if (mIns[i + 2].mRegisterFinal)
mIns[i].mCode = BC_NOP;
}
else if (mIns[i].mCode == BC_STORE_REG_16 &&
!mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister &&
mIns[i + 2].IsStore() && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal)
{
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
} mIns[i + 2].mRegister = BC_REG_ACCU;
else if (mIns[i].mCode == BC_STORE_REG_32 && }
!mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && else if (mIns[i].mCode == BC_STORE_REG_16 &&
mIns[i + 2].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 2].mRegister) !mIns[i + 1].ChangesAddr() && mIns[i + 1].mRegister != mIns[i].mRegister &&
{ mIns[i + 2].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal)
mIns[i + 2].mCode = BC_NOP; {
if (mIns[i + 2].mRegisterFinal) mIns[i].mCode = BC_ADDR_REG;
mIns[i].mCode = BC_NOP; mIns[i].mRegister = BC_REG_ACCU;
} mIns[i + 2].mCode = BC_NOP;
else if (mIns[i].mCode == BC_STORE_REG_16 && }
!mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && else if (
mIns[i + 2].IsStore() && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) mIns[i + 2].mCode == BC_BINOP_ADDR_16 &&
{ mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister &&
mIns[i].mCode = BC_NOP; mIns[i + 0].LoadsRegister(mIns[i + 2].mRegister) && mIns[i + 2].mRegisterFinal)
mIns[i + 2].mRegister = BC_REG_ACCU; {
} mIns[i + 0].mRegister = BC_REG_ACCU;
else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode = mIns[i + 2].mCode;
!mIns[i + 1].ChangesAddr() && mIns[i + 1].mRegister != mIns[i].mRegister && mIns[i + 2].mCode = BC_NOP;
mIns[i + 2].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) }
{ else if (
mIns[i].mCode = BC_ADDR_REG; mIns[i + 2].mCode == BC_BINOP_ADDR_16 &&
mIns[i].mRegister = BC_REG_ACCU; mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister &&
mIns[i + 2].mCode = BC_NOP; mIns[i + 0].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal)
} {
else if ( mIns[i + 0].mCode = BC_NOP;;
mIns[i + 2].mCode == BC_BINOP_ADDR_16 && mIns[i + 1].mCode = mIns[i + 2].mCode;
mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && mIns[i + 2].mCode = BC_NOP;
mIns[i + 0].LoadsRegister(mIns[i + 2].mRegister) && mIns[i + 2].mRegisterFinal) }
{ else if (mIns[i].mCode == BC_STORE_REG_32 &&
mIns[i + 0].mRegister = BC_REG_ACCU; mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i + 1].mRegister != mIns[i + 2].mRegister &&
mIns[i + 1].mCode = mIns[i + 2].mCode; mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister)
mIns[i + 2].mCode = BC_NOP; {
} if (mIns[i + 2].mRegisterFinal)
else if ( mIns[i + 0].mCode = BC_NOP;
mIns[i + 2].mCode == BC_BINOP_ADDR_16 && mIns[i + 1].mCode = BC_NOP;
mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && mIns[i + 2].mRegister = mIns[i + 1].mRegister;
mIns[i + 0].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal;
{ }
mIns[i + 0].mCode = BC_NOP;; else if (mIns[i].mCode == BC_STORE_REG_16 &&
mIns[i + 1].mCode = mIns[i + 2].mCode; mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister &&
mIns[i + 2].mCode = BC_NOP; mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister)
} {
else if (mIns[i].mCode == BC_STORE_REG_32 && if (mIns[i + 2].mRegisterFinal)
mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && mIns[i + 0].mCode = BC_NOP;
mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister) mIns[i + 1].mCode = BC_NOP;
{ mIns[i + 2].mRegister = mIns[i + 1].mRegister;
if (mIns[i + 2].mRegisterFinal) mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal;
}
else if (mIns[i + 0].mCode == BC_STORE_REG_32 &&
mIns[i + 2].mCode == BC_BINOP_CMP_F32 && mIns[i + 2].mRegister == mIns[i + 0].mRegister && mIns[i + 2].mRegisterFinal &&
mIns[i + 1].LoadsRegister(BC_REG_ACCU) && i + 3 == mIns.Size())
{
mIns[i + 1].mRegister = mIns[i + 0].mRegister;
mIns[i + 0].mCode = BC_NOP; mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_NOP; mBranch = TransposeBranchCondition(mBranch);
mIns[i + 2].mRegister = mIns[i + 1].mRegister; }
mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; else if (mIns[i + 0].mCode == BC_LOAD_REG_16 &&
mIns[i + 1].mCode == BC_STORE_REG_16 &&
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister)
{
mIns[i + 2].mCode = BC_NOP;
}
else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister))
{
mIns[i + 2].mCode = BC_NOP;
}
} }
else if (mIns[i].mCode == BC_STORE_REG_16 && if (i + 1 < mIns.Size())
mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister &&
mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister)
{ {
if (mIns[i + 2].mRegisterFinal) if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister)
mIns[i + 0].mCode = BC_NOP; {
mIns[i + 1].mCode = BC_NOP; mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mRegister = mIns[i + 1].mRegister; if (mIns[i + 1].mRegisterFinal)
mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; mIns[i].mCode = BC_NOP;
} progress = true;
else if (mIns[i + 0].mCode == BC_STORE_REG_32 && }
mIns[i + 2].mCode == BC_BINOP_CMP_F32 && mIns[i + 2].mRegister == mIns[i + 0].mRegister && mIns[i + 2].mRegisterFinal && else if (mIns[i].mCode == BC_LOAD_REG_16 && mIns[i + 1].mCode == BC_STORE_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister)
mIns[i + 1].LoadsRegister(BC_REG_ACCU) && i + 3 == mIns.Size()) {
{ mIns[i + 1].mCode = BC_NOP;
mIns[i + 1].mRegister = mIns[i + 0].mRegister; progress = true;
mIns[i + 0].mCode = BC_NOP; }
mBranch = TransposeBranchCondition(mBranch); else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister)
} {
else if (mIns[i + 0].mCode == BC_LOAD_REG_16 && mIns[i + 1].mCode = BC_NOP;
mIns[i + 1].mCode == BC_STORE_REG_16 && if (mIns[i + 1].mRegisterFinal)
mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister) mIns[i].mCode = BC_NOP;
{ progress = true;
mIns[i + 2].mCode = BC_NOP; }
} else if (mIns[i].mCode == BC_LOAD_REG_32 && mIns[i + 1].mCode == BC_STORE_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister)
else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) {
{ mIns[i + 1].mCode = BC_NOP;
mIns[i + 2].mCode = BC_NOP; progress = true;
} }
} else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
if (i + 1 < mIns.Size()) {
{ mIns[i].mCode = BC_ADDR_REG;
if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) mIns[i].mRegister = BC_REG_ACCU;
{ mIns[i + 1].mCode = BC_NOP;
mIns[i + 1].mCode = BC_NOP; progress = true;
if (mIns[i + 1].mRegisterFinal) }
else if (mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i + 1].mRegister = BC_REG_ACCU;
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
progress = true; progress = true;
} }
else if (mIns[i].mCode == BC_LOAD_REG_16 && mIns[i + 1].mCode == BC_STORE_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal)
{ {
mIns[i + 1].mCode = BC_NOP; mIns[i + 1].mRegister = BC_REG_ACCU;
progress = true;
}
else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister)
{
mIns[i + 1].mCode = BC_NOP;
if (mIns[i + 1].mRegisterFinal)
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
progress = true; progress = true;
}
else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ADDR;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_ABS_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_ABS_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_LOCAL_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_LOCAL_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_ADDR_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_ADDR_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
} }
else if (mIns[i].mCode == BC_LOAD_REG_32 && mIns[i + 1].mCode == BC_STORE_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister)
{ if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister)
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_ADDR_REG;
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i + 1].mRegister = BC_REG_ACCU;
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
progress = true; if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister == addrTemp)
}
else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal)
{
mIns[i + 1].mRegister = BC_REG_ACCU;
mIns[i].mCode = BC_NOP; mIns[i].mCode = BC_NOP;
progress = true;
} if (mIns[i].ChangesAccu())
else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) accuTemp = -1;
{ if (mIns[i].ChangesAddr())
mIns[i].mRegister = BC_REG_ACCU; addrTemp = -1;
mIns[i + 1].mCode = BC_NOP; if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp))
progress = true; accuTemp = -1;
} if (addrTemp != -1 && mIns[i].ChangesRegister(addrTemp))
else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) addrTemp = -1;
{
mIns[i].mRegister = BC_REG_ADDR; if (mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32)
mIns[i + 1].mCode = BC_NOP; accuTemp = mIns[i].mRegister;
progress = true; if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU)
} addrTemp = mIns[i].mRegister;
else if (mIns[i].mCode == BC_LOAD_ABS_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_ABS_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_LOCAL_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_LOCAL_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
else if (mIns[i].mCode == BC_LOAD_ADDR_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i].mCode = BC_LOAD_ADDR_I8;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
} }
if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister) if (progress)
mIns[i].mCode = BC_NOP; changed = true;
if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister == addrTemp) } while (progress);
mIns[i].mCode = BC_NOP;
if (mIns[i].ChangesAccu()) if (mTrueJump && mTrueJump->PeepHoleOptimizer())
accuTemp = -1; changed = true;
if (mIns[i].ChangesAddr()) if (mFalseJump && mFalseJump->PeepHoleOptimizer())
addrTemp = -1; changed = true;
if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp)) }
accuTemp = -1;
if (addrTemp != -1 && mIns[i].ChangesRegister(addrTemp))
addrTemp = -1;
if (mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) return changed;
accuTemp = mIns[i].mRegister;
if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU)
addrTemp = mIns[i].mRegister;
}
} while (progress);
} }
void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator) void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator)
@ -2749,8 +2768,6 @@ void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator)
{ {
mAssembled = true; mAssembled = true;
PeepHoleOptimizer();
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
mIns[i].Assemble(generator, this); mIns[i].Assemble(generator, this);
@ -2987,6 +3004,7 @@ void ByteCodeBasicBlock::CalculateOffset(int& total)
} }
ByteCodeProcedure::ByteCodeProcedure(void) ByteCodeProcedure::ByteCodeProcedure(void)
: mBlocks(nullptr)
{ {
} }
@ -3000,13 +3018,16 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
{ {
mID = proc->mID; mID = proc->mID;
tblocks = new ByteCodeBasicBlock * [proc->mBlocks.Size()]; mNumBlocks = proc->mBlocks.Size();
for (int i = 0; i < proc->mBlocks.Size(); i++)
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
for (int i = 0; i < mNumBlocks; i++)
tblocks[i] = nullptr; tblocks[i] = nullptr;
int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
entryBlock = new ByteCodeBasicBlock(); entryBlock = new ByteCodeBasicBlock();
mBlocks.Push(entryBlock);
entryBlock->PutCode(generator, BC_ENTER); entryBlock->PutWord(proc->mLocalSize + 2 + tempSave); entryBlock->PutByte(tempSave); entryBlock->PutCode(generator, BC_ENTER); entryBlock->PutWord(proc->mLocalSize + 2 + tempSave); entryBlock->PutByte(tempSave);
if (!proc->mLeafProcedure) if (!proc->mLeafProcedure)
@ -3018,6 +3039,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
tblocks[0] = entryBlock; tblocks[0] = entryBlock;
exitBlock = new ByteCodeBasicBlock(); exitBlock = new ByteCodeBasicBlock();
mBlocks.Push(exitBlock);
if (!proc->mLeafProcedure) if (!proc->mLeafProcedure)
{ {
@ -3027,6 +3049,11 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
exitBlock->PutCode(generator, BC_RETURN); exitBlock->PutByte(tempSave); exitBlock->PutWord(proc->mLocalSize + 2 + tempSave); exitBlock->PutCode(generator, BC_RETURN); exitBlock->PutByte(tempSave); exitBlock->PutWord(proc->mLocalSize + 2 + tempSave);
entryBlock->Compile(proc, this, proc->mBlocks[0]); entryBlock->Compile(proc, this, proc->mBlocks[0]);
bool progress = false;
ResetVisited();
progress = entryBlock->PeepHoleOptimizer();
entryBlock->Assemble(generator); entryBlock->Assemble(generator);
int total; int total;
@ -3049,12 +3076,20 @@ ByteCodeBasicBlock* ByteCodeProcedure::CompileBlock(InterCodeProcedure* iproc, I
return tblocks[sblock->mIndex]; return tblocks[sblock->mIndex];
ByteCodeBasicBlock * block = new ByteCodeBasicBlock(); ByteCodeBasicBlock * block = new ByteCodeBasicBlock();
mBlocks.Push(block);
tblocks[sblock->mIndex] = block; tblocks[sblock->mIndex] = block;
block->Compile(iproc, this, sblock); block->Compile(iproc, this, sblock);
return block; return block;
} }
void ByteCodeProcedure::ResetVisited(void)
{
for (int i = 0; i < mBlocks.Size(); i++)
{
mBlocks[i]->mVisited = false;
}
}
ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker) ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker) : mErrors(errors), mLinker(linker)

View File

@ -176,6 +176,8 @@ public:
bool StoresRegister(uint32 reg) const; bool StoresRegister(uint32 reg) const;
bool IsCommutative(void) const; bool IsCommutative(void) const;
bool ValueForwarding(ByteCodeInstruction*& accuIns, ByteCodeInstruction*& addrIns);
}; };
class ByteCodeBasicBlock class ByteCodeBasicBlock
@ -192,7 +194,7 @@ public:
GrowingArray<LinkerReference> mRelocations; GrowingArray<LinkerReference> mRelocations;
int mOffset, mSize; int mOffset, mSize;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled; bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mVisited;
ByteCodeBasicBlock(void); ByteCodeBasicBlock(void);
@ -230,7 +232,7 @@ public:
void BinaryIntOperator(InterCodeProcedure* proc, const InterInstruction * ins, ByteCode code); void BinaryIntOperator(InterCodeProcedure* proc, const InterInstruction * ins, ByteCode code);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins); void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins);
void PeepHoleOptimizer(void); bool PeepHoleOptimizer(void);
}; };
class ByteCodeGenerator; class ByteCodeGenerator;
@ -243,12 +245,15 @@ public:
ByteCodeBasicBlock * entryBlock, * exitBlock; ByteCodeBasicBlock * entryBlock, * exitBlock;
ByteCodeBasicBlock ** tblocks; ByteCodeBasicBlock ** tblocks;
GrowingArray < ByteCodeBasicBlock*> mBlocks;
int mProgSize, mID; int mProgSize, mID, mNumBlocks;
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc); void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block); ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
void ResetVisited(void);
protected: protected:
ByteCodeDisassembler mDisassembler; ByteCodeDisassembler mDisassembler;
}; };

View File

@ -1387,7 +1387,8 @@ void InterInstruction::GlobalRenameRegister(const GrowingIntArray& renameTable,
if (mTTemp >= 0) if (mTTemp >= 0)
{ {
mTTemp = renameTable[mTTemp]; mTTemp = renameTable[mTTemp];
temporaries[mTTemp] = mTType; if (InterTypeSize[mTType] > InterTypeSize[temporaries[mTTemp]])
temporaries[mTTemp] = mTType;
} }
} }
@ -3529,7 +3530,7 @@ void InterCodeProcedure::RenameTemporaries(void)
mGlobalRenameTable[i] = mGlobalRenameTable[j]; mGlobalRenameTable[i] = mGlobalRenameTable[j];
} }
mTemporaries.SetSize(numRenamedTemps); mTemporaries.SetSize(numRenamedTemps, true);
// //
// Set global temporary IDs // Set global temporary IDs
@ -3794,7 +3795,7 @@ void InterCodeProcedure::Close(void)
mBlocks[0]->CollectActiveTemporaries(activeSet); mBlocks[0]->CollectActiveTemporaries(activeSet);
mTemporaries.SetSize(activeSet.Num()); mTemporaries.SetSize(activeSet.Num(), true);
@ -3892,7 +3893,7 @@ void InterCodeProcedure::ReduceTemporaries(void)
if (j >= numRenamedTemps) numRenamedTemps = j + 1; if (j >= numRenamedTemps) numRenamedTemps = j + 1;
} }
mTemporaries.SetSize(numRenamedTemps); mTemporaries.SetSize(numRenamedTemps, true);
ResetVisited(); ResetVisited();
mBlocks[0]->GlobalRenameRegister(mRenameTable, mTemporaries); mBlocks[0]->GlobalRenameRegister(mRenameTable, mTemporaries);
@ -3960,6 +3961,16 @@ void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
fprintf(file, "--------------------------------------------------------------------\n"); fprintf(file, "--------------------------------------------------------------------\n");
fprintf(file, "%s : %s:%d\n", name, mLocation.mFileName, mLocation.mLine); fprintf(file, "%s : %s:%d\n", name, mLocation.mFileName, mLocation.mLine);
if (mTempOffset.Size())
{
static char typechars[] = "NBCILFP";
for (int i = 0; i < mTemporaries.Size(); i++)
{
fprintf(file, "$%02x T%d(%c), ", mTempOffset[i], i, typechars[mTemporaries[i]]);
}
}
fprintf(file, "\n");
ResetVisited(); ResetVisited();
mBlocks[0]->Disassemble(file, dumpSets); mBlocks[0]->Disassemble(file, dumpSets);

View File

@ -719,6 +719,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mTTemp = proc->AddTemporary(cins->mTType); cins->mTTemp = proc->AddTemporary(cins->mTType);
block->Append(cins); block->Append(cins);
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
InterInstruction * mins = new InterInstruction(); InterInstruction * mins = new InterInstruction();
mins->mCode = IC_BINARY_OPERATOR; mins->mCode = IC_BINARY_OPERATOR;
mins->mOperator = IA_MUL; mins->mOperator = IA_MUL;

View File

@ -183,6 +183,10 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
case ASMIT_DEX: case ASMIT_DEX:
case ASMIT_INY: case ASMIT_INY:
case ASMIT_DEY: case ASMIT_DEY:
case ASMIT_TYA:
case ASMIT_TXA:
case ASMIT_TAY:
case ASMIT_TAX:
used = true; used = true;
break; break;
} }
@ -248,11 +252,6 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
case ASMIT_LSR: case ASMIT_LSR:
case ASMIT_INC: case ASMIT_INC:
case ASMIT_DEC: case ASMIT_DEC:
case ASMIT_ADC:
case ASMIT_SBC:
case ASMIT_ORA:
case ASMIT_EOR:
case ASMIT_AND:
case ASMIT_STA: case ASMIT_STA:
case ASMIT_STX: case ASMIT_STX:
case ASMIT_STY: case ASMIT_STY:
@ -2657,8 +2656,17 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 1 && !sins0 && ins->mSTemp[0] == ins->mTTemp)) ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 1 && !sins0 && ins->mSTemp[0] == ins->mTTemp))
{ {
mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, 2)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1)); {
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, 2));
mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1));
}
}
else if (ins->mOperator == IA_ADD && InterTypeSize[ins->mTType] == 1 && (
ins->mSTemp[0] < 0 && ins->mSIntConst[0] == -1 && !sins1 && ins->mSTemp[1] == ins->mTTemp ||
ins->mSTemp[1] < 0 && ins->mSIntConst[1] == -1 && !sins0 && ins->mSTemp[0] == ins->mTTemp))
{
mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, treg));
} }
else else
{ {
@ -2694,9 +2702,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(insh); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(insh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
else if (ins->mSTemp[0] < 0) else if (ins->mSTemp[0] < 0)
@ -2712,9 +2723,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(insh); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
mIns.Push(insh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
else else
@ -2748,9 +2762,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
} }
@ -2759,7 +2776,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
{ {
NativeCodeInstruction insl, insh; NativeCodeInstruction insl, insh;
if (ins->mSTemp[0] < 0) if (InterTypeSize[ins->mTType] == 1 &&
ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 1 && !sins0 && ins->mSTemp[0] == ins->mTTemp)
{
mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, treg));
}
else if (ins->mSTemp[0] < 0)
{ {
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff); insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff);
insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (ins->mSIntConst[0] >> 8) & 0xff); insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (ins->mSIntConst[0] >> 8) & 0xff);
@ -2771,9 +2793,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(insh); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
mIns.Push(insh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
else if (ins->mSTemp[1] < 0) else if (ins->mSTemp[1] < 0)
@ -2786,9 +2811,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1)); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
else else
{ {
@ -2796,9 +2824,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
else else
@ -2826,9 +2857,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); if (InterTypeSize[ins->mTType] > 1)
mIns.Push(insh); {
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
mIns.Push(insh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
} }
} }
} break; } break;
@ -3993,6 +4027,42 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void)
return changed; return changed;
} }
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int& breg, int& ireg)
{
int j = at - 7;
while (j >= 0)
{
if (
mIns[j + 0].mType == ASMIT_CLC &&
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE && mIns[j + 1].mAddress != reg &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 1].mAddress + 1 &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
breg = mIns[j + 1].mAddress;
ireg = mIns[j + 2].mAddress;
j = j + 7;
while (j < at)
{
if (mIns[j].mMode == ASMIM_ZERO_PAGE && (mIns[j].mAddress == breg || mIns[j].mAddress == breg + 1 || mIns[j].mAddress == ireg) && mIns[j].ChangesAddress())
return false;
j++;
}
return true;
}
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j].mAddress == reg || mIns[j].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
return false;
j--;
}
return false;
}
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at) bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
{ {
int j = at; int j = at;
@ -4259,6 +4329,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mType = ASMIT_NOP;
progress = true; progress = true;
} }
#if 1
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Y)))
{
int breg, ireg;
if (FindAddressSumY(i, mIns[i + 2].mAddress, breg, ireg))
{
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
mIns[i + 0].mAddress = ireg;
mIns[i + 2].mAddress = breg;
progress = true;
}
}
#endif
} }
if (i + 3 < mIns.Size()) if (i + 3 < mIns.Size())
@ -4911,8 +4998,11 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
{ {
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]])); block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]]));
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp])); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp]));
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 1)); if (InterTypeSize[ins->mTType] > 1)
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp] + 1)); {
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 1));
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp] + 1));
}
if (ins->mSType[0] == IT_FLOAT) if (ins->mSType[0] == IT_FLOAT)
{ {
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 2)); block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 2));

View File

@ -124,6 +124,7 @@ public:
bool MergeBasicBlocks(void); bool MergeBasicBlocks(void);
bool MoveLoadStoreUp(int at); bool MoveLoadStoreUp(int at);
bool FindAddressSumY(int at, int reg, int& breg, int& ireg);
bool ValueForwarding(const NativeRegisterDataSet& data); bool ValueForwarding(const NativeRegisterDataSet& data);