Optimize native comparison against zero
This commit is contained in:
parent
eebc39e53a
commit
603b62b9d3
|
@ -52,22 +52,97 @@ bool nle(int a, int b)
|
|||
return a <= b;
|
||||
}
|
||||
|
||||
#pragma native(nlt)
|
||||
#pragma native(nle)
|
||||
|
||||
bool nge(int a, int b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
#pragma native(ngt)
|
||||
#pragma native(nge)
|
||||
|
||||
bool beqz(int a)
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
bool bltz(int a)
|
||||
{
|
||||
return a < 0;
|
||||
}
|
||||
|
||||
bool bgtz(int a)
|
||||
{
|
||||
return a > 0;
|
||||
}
|
||||
|
||||
bool blez(int a)
|
||||
{
|
||||
return a <= 0;
|
||||
}
|
||||
|
||||
bool bgez(int a)
|
||||
{
|
||||
return a >= 0;
|
||||
}
|
||||
|
||||
bool neqz(int a)
|
||||
{
|
||||
return a == 0;
|
||||
}
|
||||
|
||||
#pragma native(neqz)
|
||||
|
||||
bool nltz(int a)
|
||||
{
|
||||
return a < 0;
|
||||
}
|
||||
|
||||
#pragma native(nltz)
|
||||
|
||||
bool ngtz(int a)
|
||||
{
|
||||
return a > 0;
|
||||
}
|
||||
|
||||
#pragma native(ngtz)
|
||||
|
||||
bool nlez(int a)
|
||||
{
|
||||
return a <= 0;
|
||||
}
|
||||
|
||||
#pragma native(nlez)
|
||||
|
||||
bool ngez(int a)
|
||||
{
|
||||
return a >= 0;
|
||||
}
|
||||
|
||||
#pragma native(ngez)
|
||||
|
||||
void cmp(int a, int b)
|
||||
{
|
||||
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = blt(a, b), bgef = bgt(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nlt(a, b), ngef = ngt(a, b);
|
||||
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
||||
// printf("BYTE %d, %d : EQ %d LT %d GT %d\r", a, b, beqf, bltf, bgtf);
|
||||
// printf("NATIVE %d, %d : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
printf("BYTE %d, %d : EQ %d LT %d GT %d\r", a, b, beqf, bltf, bgtf);
|
||||
printf("NATIVE %d, %d : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
assert(bgtf == ngtf);
|
||||
assert(blef == nlef);
|
||||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpz(int a)
|
||||
{
|
||||
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
|
||||
bool neqf = neqz(a), nltf = nltz(a), ngtf = ngtz(a), nlef = nlez(a), ngef = ngez(a);
|
||||
|
||||
printf("BYTE %d, 0 : EQ %d LT %d GT %d\r", a, beqf, bltf, bgtf);
|
||||
printf("NATIVE %d, 0 : EQ %d LT %d GT %d\r", a, neqf, nltf, ngtf);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
|
@ -142,6 +217,18 @@ int main(void)
|
|||
cmp(-1024, 1025);
|
||||
cmp(-1025, 1024);
|
||||
|
||||
cmpz(0);
|
||||
cmpz(1);
|
||||
cmpz(255);
|
||||
cmpz(256);
|
||||
cmpz(10000);
|
||||
cmpz(20000);
|
||||
cmpz(-1);
|
||||
cmpz(-255);
|
||||
cmpz(-256);
|
||||
cmpz(-10000);
|
||||
cmpz(-20000);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ int nformi(const sinfo * si, char * str, int v, bool s)
|
|||
u /= si->base;
|
||||
}
|
||||
|
||||
int digits = si->precision != 255 ? 10 - si->precision : 9;
|
||||
char digits = si->precision != 255 ? 10 - si->precision : 9;
|
||||
|
||||
while (i > digits)
|
||||
sp[--i] = '0';
|
||||
|
|
|
@ -3496,6 +3496,90 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 0 || ins->mSTemp[0] < 0 && ins->mSIntConst[0] == 0)
|
||||
{
|
||||
int rt = ins->mSTemp[1];
|
||||
if (rt < 0)
|
||||
{
|
||||
rt = ins->mSTemp[0];
|
||||
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:
|
||||
case IA_CMPLEU:
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(trueJump, falseJump, ASMIT_BEQ);
|
||||
break;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(trueJump, falseJump, ASMIT_BNE);
|
||||
break;
|
||||
case IA_CMPGEU:
|
||||
this->Close(trueJump, nullptr, ASMIT_JMP);
|
||||
break;
|
||||
case IA_CMPLU:
|
||||
this->Close(falseJump, nullptr, ASMIT_JMP);
|
||||
break;
|
||||
case IA_CMPGES:
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(trueJump, falseJump, ASMIT_BPL);
|
||||
break;
|
||||
case IA_CMPLS:
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(trueJump, falseJump, ASMIT_BMI);
|
||||
break;
|
||||
case IA_CMPGS:
|
||||
{
|
||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(eblock, falseJump, ASMIT_BPL);
|
||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
|
||||
eblock->Close(trueJump, falseJump, ASMIT_BNE);
|
||||
break;
|
||||
}
|
||||
case IA_CMPLES:
|
||||
{
|
||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 1));
|
||||
this->Close(eblock, trueJump, ASMIT_BPL);
|
||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[rt] + 0));
|
||||
eblock->Close(trueJump, falseJump, ASMIT_BEQ);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||
|
@ -4398,6 +4482,16 @@ void NativeCodeBasicBlock::CalculateOffset(int& total)
|
|||
else
|
||||
{
|
||||
// neither falseJump nor trueJump have been placed
|
||||
//
|
||||
|
||||
if (mTrueJump->mFalseJump == mFalseJump || mTrueJump->mTrueJump == mFalseJump)
|
||||
{
|
||||
NativeCodeBasicBlock* block = mFalseJump;
|
||||
mFalseJump = mTrueJump;
|
||||
mTrueJump = block;
|
||||
mBranch = InvertBranchCondition(mBranch);
|
||||
}
|
||||
|
||||
// this may lead to some undo operation...
|
||||
// first assume a full size branch:
|
||||
|
||||
|
|
Loading…
Reference in New Issue