Optimize global arrays and const comparisons

This commit is contained in:
drmortalwombat 2021-09-30 20:00:47 +02:00
parent e846caaf1f
commit 02305e8bc5
5 changed files with 441 additions and 27 deletions

View File

@ -61,6 +61,8 @@ bool nge(int a, int b)
#pragma native(nge) #pragma native(nge)
bool beqz(int a) bool beqz(int a)
{ {
return a == 0; return a == 0;
@ -121,6 +123,71 @@ bool ngez(int a)
#pragma native(ngez) #pragma native(ngez)
bool beq1(int a)
{
return a == 1;
}
bool blt1(int a)
{
return a < 1;
}
bool bgt1(int a)
{
return a > 1;
}
bool ble1(int a)
{
return a <= 1;
}
bool bge1(int a)
{
return a >= 1;
}
bool neq1(int a)
{
return a == 1;
}
#pragma native(neq1)
bool nlt1(int a)
{
return a < 1;
}
#pragma native(nlt1)
bool ngt1(int a)
{
return a > 1;
}
#pragma native(ngt1)
bool nle1(int a)
{
return a <= 1;
}
#pragma native(nle1)
bool nge1(int a)
{
return a >= 1;
}
#pragma native(nge1)
void cmp(int a, int b) void cmp(int a, int b)
{ {
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b); bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
@ -151,6 +218,21 @@ void cmpz(int a)
assert(bgef == ngef); assert(bgef == ngef);
} }
void cmp1(int a)
{
bool beqf = beq1(a), bltf = blt1(a), bgtf = bgt1(a), blef = ble1(a), bgef = bge1(a);
bool neqf = neq1(a), nltf = nlt1(a), ngtf = ngt1(a), nlef = nle1(a), ngef = nge1(a);
printf("BYTE %d, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
printf("NATIVE %d, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
assert(beqf == neqf);
assert(bltf == nltf);
assert(bgtf == ngtf);
assert(blef == nlef);
assert(bgef == ngef);
}
int main(void) int main(void)
{ {
cmp( 0, 1); cmp( 0, 1);
@ -229,6 +311,22 @@ int main(void)
cmpz(-10000); cmpz(-10000);
cmpz(-20000); cmpz(-20000);
cmp1(0);
cmp1(1);
cmp1(2);
cmp1(3);
cmp1(255);
cmp1(256);
cmp1(10000);
cmp1(20000);
cmp1(-1);
cmp1(-2);
cmp1(-3);
cmp1(-255);
cmp1(-256);
cmp1(-10000);
cmp1(-20000);
return 0; return 0;
} }

View File

@ -1571,6 +1571,42 @@ void ByteCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const In
mIns.Push(sins); mIns.Push(sins);
} }
} }
else if (ins->mSTemp[1] < 0)
{
if (ins->mMemory == IM_GLOBAL)
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = BC_REG_ACCU;
bins.mLinkerObject = ins->mLinkerObject;
bins.mValue = ins->mIntValue;
bins.mRelocate = true;
mIns.Push(bins);
}
else if (ins->mMemory == IM_ABSOLUTE)
{
ByteCodeInstruction bins(BC_LEA_ABS);
bins.mRegister = BC_REG_ACCU;
bins.mValue = ins->mIntValue;
mIns.Push(bins);
}
else if (ins->mMemory == IM_PROCEDURE)
{
ByteCodeInstruction bins(BC_CONST_16);
bins.mRegister = BC_REG_ACCU;
bins.mLinkerObject = ins->mLinkerObject;
bins.mValue = 0;
bins.mRelocate = true;
mIns.Push(bins);
}
ByteCodeInstruction ains(BC_BINOP_ADDR_16);
ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
ains.mRegisterFinal = ins->mSFinal[0];
mIns.Push(ains);
ByteCodeInstruction sins(BC_STORE_REG_16);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
mIns.Push(sins);
}
else else
{ {
ByteCodeInstruction lins(BC_LOAD_REG_16); ByteCodeInstruction lins(BC_LOAD_REG_16);

View File

@ -1915,6 +1915,15 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSTemp[0] = -1; ins->mSTemp[0] = -1;
} }
} }
else if (ins->mSTemp[1] >= 0 && tvalue[ins->mSTemp[1]] && tvalue[ins->mSTemp[1]]->mCode == IC_CONSTANT && tvalue[ins->mSTemp[1]]->mMemory == IM_GLOBAL)
{
ins->mMemory = tvalue[ins->mSTemp[1]]->mMemory;
ins->mLinkerObject = tvalue[ins->mSTemp[1]]->mLinkerObject;
ins->mVarIndex = tvalue[ins->mSTemp[1]]->mVarIndex;
ins->mIntValue = tvalue[ins->mSTemp[1]]->mIntValue + tvalue[ins->mSTemp[0]]->mIntValue;
ins->mOperandSize = tvalue[ins->mSTemp[1]]->mOperandSize;
ins->mSTemp[1] = -1;
}
break; break;
case IC_TYPECAST: case IC_TYPECAST:
if (ins->mSType[0] == ins->mTType) if (ins->mSType[0] == ins->mTType)

View File

@ -3772,6 +3772,13 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr
} break; } break;
case IA_SHL: case IA_SHL:
{ {
if (ins->mSTemp[0] < 0 && (ins->mSIntConst[0] & 15) == 1 && sins1)
{
NativeCodeInstruction insl(ASMIT_ASL, ASMIM_IMPLIED);
NativeCodeInstruction insh(ASMIT_ROL, ASMIM_IMPLIED);
LoadValueToReg(proc, sins1, treg, &insl, &insh);
return;
}
if (sins1) LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]], nullptr, nullptr); if (sins1) LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]], nullptr, nullptr);
if (sins0) LoadValueToReg(proc, sins0, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]], nullptr, nullptr); if (sins0) LoadValueToReg(proc, sins0, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]], nullptr, nullptr);
@ -4461,6 +4468,168 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
} }
} }
#if 1
else if (ins->mSTemp[1] < 0 && ins->mSIntConst[1] < 256 && ins->mSIntConst[1] > 0 || ins->mSTemp[0] < 0 && ins->mSIntConst[0] < 256 && ins->mSIntConst[0] > 0)
{
int rt = ins->mSTemp[1];
int ival = ins->mSIntConst[0];
if (rt < 0)
{
rt = ins->mSTemp[0];
ival = ins->mSIntConst[1];
switch (op)
{
case IA_CMPLEU:
op = IA_CMPGEU;
break;
case IA_CMPGEU:
op = IA_CMPLEU;
break;
case IA_CMPLU:
op = IA_CMPGU;
break;
case IA_CMPGU:
op = IA_CMPLU;
break;
case IA_CMPLES:
op = IA_CMPGES;
break;
case IA_CMPGES:
op = IA_CMPLES;
break;
case IA_CMPLS:
op = IA_CMPGS;
break;
case IA_CMPGS:
op = IA_CMPLS;
break;
}
}
switch (op)
{
case IA_CMPEQ:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, falseJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(trueJump, falseJump, ASMIT_BEQ);
break;
}
case IA_CMPNE:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, trueJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(falseJump, trueJump, ASMIT_BEQ);
break;
}
case IA_CMPLEU:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, falseJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ival));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(falseJump, trueJump, ASMIT_BCC);
break;
}
case IA_CMPGEU:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, trueJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(falseJump, trueJump, ASMIT_BCC);
break;
}
case IA_CMPLU:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, falseJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(trueJump, falseJump, ASMIT_BCC);
break;
}
case IA_CMPGU:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(eblock, trueJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ival));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(trueJump, falseJump, ASMIT_BCC);
break;
}
case IA_CMPLES:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* sblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(sblock, trueJump, ASMIT_BPL);
sblock->Close(eblock, falseJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ival));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(falseJump, trueJump, ASMIT_BCC);
break;
}
case IA_CMPGES:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* sblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(sblock, falseJump, ASMIT_BPL);
sblock->Close(eblock, trueJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(falseJump, trueJump, ASMIT_BCC);
break;
}
case IA_CMPLS:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* sblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(sblock, trueJump, ASMIT_BPL);
sblock->Close(eblock, falseJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ival));
eblock->Close(trueJump, falseJump, ASMIT_BCC);
break;
}
case IA_CMPGS:
{
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
NativeCodeBasicBlock* sblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
this->Close(sblock, falseJump, ASMIT_BPL);
sblock->Close(eblock, trueJump, ASMIT_BEQ);
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ival));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
eblock->Close(trueJump, falseJump, ASMIT_BCC);
break;
}
}
}
#endif
else else
{ {
NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
@ -4472,9 +4641,34 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
li = 0; ri = 1; li = 0; ri = 1;
} }
int iconst = 0;
bool rconst = false;
if (ins->mSTemp[li] < 0 && (op == IA_CMPGES || op == IA_CMPLS) && int16(ins->mSIntConst[li]) > - 32768)
{
iconst = ins->mSIntConst[li] - 1;
rconst = true;
li = ri; ri = 1 - li;
NativeCodeBasicBlock* t = trueJump; trueJump = falseJump; falseJump = t;
}
else if (ins->mSTemp[li] < 0 && (op == IA_CMPLES || op == IA_CMPGS) && int16(ins->mSIntConst[li]) < 32767)
{
iconst = ins->mSIntConst[li] + 1;
rconst = true;
li = ri; ri = 1 - li;
NativeCodeBasicBlock* t = trueJump; trueJump = falseJump; falseJump = t;
}
else if (ins->mSTemp[ri] < 0)
{
iconst = ins->mSIntConst[ri];
rconst = true;
}
if (op >= IA_CMPGES && ins->mOperator <= IA_CMPLS) if (op >= IA_CMPGES && ins->mOperator <= IA_CMPLS)
{ {
if (ins->mSTemp[ri] >= 0) if (!rconst)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80)); mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80));
@ -4489,8 +4683,8 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80)); mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80));
} }
if (ins->mSTemp[ri] < 0) if (rconst)
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ((ins->mSIntConst[ri] >> 8) & 0xff) ^ 0x80)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ((iconst >> 8) & 0xff) ^ 0x80));
else else
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_WORK)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_WORK));
} }
@ -4500,8 +4694,8 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[li] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[li] >> 8) & 0xff));
else else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[li]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[li]] + 1));
if (ins->mSTemp[ri] < 0) if (rconst)
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, (ins->mSIntConst[ri] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, (iconst >> 8) & 0xff));
else else
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]] + 1));
} }
@ -4512,8 +4706,8 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[li] & 0xff)); eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[li] & 0xff));
else else
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[li]])); eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[li]]));
if (ins->mSTemp[ri] < 0) if (rconst)
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, ins->mSIntConst[ri] & 0xff)); eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, iconst & 0xff));
else else
eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]])); eblock->mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[ri]]));
@ -4570,15 +4764,43 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
} }
} }
} }
else if (ins->mSTemp[1] < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
if (ins->mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mLinkerObject, NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
}
else if (ins->mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mIntValue & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mIntValue >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
}
else if (ins->mMemory == IM_PROCEDURE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
}
}
else else
{ {
if (ins->mSTemp[0] >= 0 || ins->mSIntConst[0] != 0) if (ins->mSTemp[0] >= 0 || ins->mSIntConst[0] != 0)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
if (ins->mSTemp[1] < 0) mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]));
if (ins->mSTemp[0] < 0) if (ins->mSTemp[0] < 0)
{ {
@ -4590,10 +4812,7 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp]));
if (ins->mSTemp[1] < 0) mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff));
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1));
if (ins->mSTemp[0] < 0) if (ins->mSTemp[0] < 0)
{ {
@ -5039,6 +5258,32 @@ bool NativeCodeBasicBlock::FindGlobalAddress(int at, int reg, int& apos)
return false; return false;
} }
bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, int& apos, 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_IMMEDIATE_ADDRESS && (mIns[j + 1].mFlags & NCIF_LOWER) && mIns[j + 1].mLinkerObject &&
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_IMMEDIATE_ADDRESS && (mIns[j + 4].mFlags & NCIF_UPPER) && mIns[j + 4].mLinkerObject == mIns[j + 1].mLinkerObject &&
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)
{
apos = j + 0;
ireg = mIns[j + 2].mAddress;
return true;
}
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
return false;
j--;
}
return false;
}
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg) bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
{ {
int j = at - 7; int j = at - 7;
@ -5573,6 +5818,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
{ {
#if 1
#if 1 #if 1
if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0) if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0)
{ {
@ -5603,7 +5849,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i].mLinkerObject = mIns[apos].mLinkerObject; mIns[i].mLinkerObject = mIns[apos].mLinkerObject;
progress = true; progress = true;
} }
#endif
#if 1
if (i + 1 < mIns.Size()) if (i + 1 < mIns.Size())
{ {
if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_LDA) if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_LDA)
@ -5679,15 +5926,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mType = ASMIT_STA; mIns[i + 1].mType = ASMIT_STA;
progress = true; progress = true;
} }
else if (
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & LIVE_CPU_REG_A) &&
mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress &&
(mIns[i + 0].mType == ASMIT_DEC || mIns[i + 0].mType == ASMIT_INC))
{
mIns[i + 1].mType = ASMIT_NOP;
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
progress = true;
}
else if ( else if (
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 0].mLive & LIVE_CPU_REG_A)) mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 0].mLive & LIVE_CPU_REG_A))
@ -5699,6 +5937,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
progress = true; progress = true;
} }
#if 1
if ( if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & LIVE_MEM )) mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & LIVE_MEM ))
@ -5723,9 +5962,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mAddress = breg; mIns[i + 1].mAddress = breg;
progress = true; progress = true;
} }
else if (FindGlobalAddressSumY(i, mIns[i + 1].mAddress, apos, ireg))
{
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
}
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
mIns[i + 0].mAddress = ireg;
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
mIns[i + 1].mLinkerObject = mIns[apos + 1].mLinkerObject;
mIns[i + 1].mAddress = mIns[apos + 1].mAddress;
progress = true;
}
} }
#endif
} }
#endif
#if 1
if (i + 2 < mIns.Size()) if (i + 2 < mIns.Size())
{ {
if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC)) if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC))
@ -5802,6 +6060,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 2].mType = ASMIT_CLC; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_CLC; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
#if 1
else if (
mIns[i + 0].mMode != ASMIM_RELATIVE &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & LIVE_CPU_REG_A) &&
mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 1].mAddress &&
(mIns[i + 1].mType == ASMIT_DEC || mIns[i + 1].mType == ASMIT_INC))
{
mIns[i + 2].mType = ASMIT_NOP;
mIns[i + 1].mLive |= LIVE_CPU_REG_Z;
progress = true;
}
#endif
#if 1 #if 1
if ( if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
@ -5895,6 +6165,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
progress = true; progress = true;
} }
} }
#endif
#endif #endif
} }
@ -6347,7 +6618,6 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
} while (changed); } while (changed);
ResetVisited(); ResetVisited();
if (entryBlock->PeepHoleOptimizer()) if (entryBlock->PeepHoleOptimizer())
changed = true; changed = true;
@ -6355,7 +6625,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ResetVisited(); ResetVisited();
if (entryBlock->OptimizeSimpleLoop(this)) if (entryBlock->OptimizeSimpleLoop(this))
changed = true; changed = true;
ResetVisited(); ResetVisited();
if (entryBlock->MergeBasicBlocks()) if (entryBlock->MergeBasicBlocks())
changed = true; changed = true;

View File

@ -138,6 +138,7 @@ public:
bool MoveLoadStoreUp(int at); bool MoveLoadStoreUp(int at);
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddress(int at, int reg, int& apos);
bool FindGlobalAddressSumY(int at, int reg, int& apos, int& ireg);
bool ValueForwarding(const NativeRegisterDataSet& data); bool ValueForwarding(const NativeRegisterDataSet& data);