Optimize signed long compare

This commit is contained in:
drmortalwombat 2025-05-20 16:05:09 +02:00
parent e660757824
commit 65540da3f7
2 changed files with 332 additions and 107 deletions

View File

@ -63,6 +63,33 @@ bool nge(long a, long b)
inline bool ieq(long a, long b)
{
return a == b;
}
inline bool ilt(long a, long b)
{
return a < b;
}
inline bool igt(long a, long b)
{
return a > b;
}
inline bool ile(long a, long b)
{
return a <= b;
}
inline bool ige(long a, long b)
{
return a >= b;
}
bool beqz(long a) bool beqz(long a)
{ {
return a == 0; return a == 0;
@ -188,7 +215,71 @@ bool nge1(long a)
void cmp(long a, long b) bool beqm(long a)
{
return a == -1;
}
bool bltm(long a)
{
return a < -1;
}
bool bgtm(long a)
{
return a > -1;
}
bool blem(long a)
{
return a <= -1;
}
bool bgem(long a)
{
return a >= -1;
}
bool neqm(long a)
{
return a == -1;
}
#pragma native(neqm)
bool nltm(long a)
{
return a < -1;
}
#pragma native(nltm)
bool ngtm(long a)
{
return a > -1;
}
#pragma native(ngtm)
bool nlem(long a)
{
return a <= -1;
}
#pragma native(nlem)
bool ngem(long a)
{
return a >= -1;
}
#pragma native(ngem)
void cmpc(long a, long 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);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b); bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
@ -203,6 +294,27 @@ void cmp(long a, long b)
assert(bgef == ngef); assert(bgef == ngef);
} }
void cmpi(long a, long b)
{
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
assert(ieqf == neqf);
assert(iltf == nltf);
assert(igtf == ngtf);
assert(ilef == nlef);
assert(igef == ngef);
}
void cmp(long a, long b)
{
cmpc(a, b);
cmpi(a, b);
}
void cmpz(long a) void cmpz(long a)
{ {
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a); bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
@ -233,6 +345,21 @@ void cmp1(long a)
assert(bgef == ngef); assert(bgef == ngef);
} }
void cmpm(long a)
{
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
printf("NATIVE %ld, 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);
@ -327,6 +454,10 @@ int main(void)
cmp1(256); cmp1(256);
cmp1(10000); cmp1(10000);
cmp1(20000); cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1); cmp1(-1);
cmp1(-2); cmp1(-2);
cmp1(-3); cmp1(-3);
@ -334,6 +465,34 @@ int main(void)
cmp1(-256); cmp1(-256);
cmp1(-10000); cmp1(-10000);
cmp1(-20000); cmp1(-20000);
cmp1(-1000000l);
cmp1(-2000000l);
cmp1(-100000000l);
cmp1(-200000000l);
cmpm(0);
cmpm(1);
cmpm(2);
cmpm(3);
cmpm(255);
cmpm(256);
cmpm(10000);
cmpm(20000);
cmpm(1000000l);
cmpm(2000000l);
cmpm(100000000l);
cmpm(200000000l);
cmpm(-1);
cmpm(-2);
cmpm(-3);
cmpm(-255);
cmpm(-256);
cmpm(-10000);
cmpm(-20000);
cmpm(-1000000l);
cmpm(-2000000l);
cmpm(-100000000l);
cmpm(-200000000l);
return 0; return 0;

View File

@ -13347,6 +13347,71 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
} }
} }
else if (ins->mSrc[0].mType == IT_INT32) else if (ins->mSrc[0].mType == IT_INT32)
{
if ((op >= IA_CMPGES && op <= IA_CMPLS) &&
(ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst >= 0 && ins->mSrc[0].mIntConst < 256 ||
ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst >= 0 && ins->mSrc[1].mIntConst < 256))
{
NativeCodeBasicBlock* eblock3 = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock2 = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock1 = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock0 = nproc->AllocateBlock();
int li = 1, ri = 0;
if (ins->mSrc[1].mTemp < 0)
{
li = 0;
ri = 1;
op = MirrorRelational(op);
}
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 3));
if (op == IA_CMPGS || op == IA_CMPGES)
{
if (op == IA_CMPGES && ins->mSrc[ri].mIntConst == 0)
this->Close(ins, falseJump, trueJump, ASMIT_BMI);
else
{
this->Close(ins, falseJump, eblock3, ASMIT_BMI);
eblock3->Close(ins, trueJump, eblock2, ASMIT_BNE);
eblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 2));
eblock2->Close(ins, trueJump, eblock1, ASMIT_BNE);
eblock1->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
if (op == IA_CMPGS && ins->mSrc[ri].mIntConst == 255)
eblock1->Close(ins, trueJump, falseJump, ASMIT_BNE);
else
{
eblock1->Close(ins, trueJump, eblock0, ASMIT_BNE);
eblock0->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp]));
eblock0->mIns.Push(NativeCodeInstruction(ins, ASMIT_CMP, ASMIM_IMMEDIATE, ins->mSrc[ri].mIntConst + (op == IA_CMPGS)));
eblock0->Close(ins, trueJump, falseJump, ASMIT_BCS);
}
}
}
else
{
if (op == IA_CMPLS && ins->mSrc[ri].mIntConst == 0)
this->Close(ins, trueJump, falseJump, ASMIT_BMI);
else
{
this->Close(ins, trueJump, eblock3, ASMIT_BMI);
eblock3->Close(ins, falseJump, eblock2, ASMIT_BNE);
eblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 2));
eblock2->Close(ins, falseJump, eblock1, ASMIT_BNE);
eblock1->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp] + 1));
eblock1->Close(ins, falseJump, eblock0, ASMIT_BNE);
if (op == IA_CMPLES && ins->mSrc[ri].mIntConst == 255)
eblock1->Close(ins, falseJump, trueJump, ASMIT_BNE);
else
{
eblock0->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[li].mTemp]));
eblock0->mIns.Push(NativeCodeInstruction(ins, ASMIT_CMP, ASMIM_IMMEDIATE, ins->mSrc[ri].mIntConst + (op == IA_CMPLES)));
eblock0->Close(ins, falseJump, trueJump, ASMIT_BCS);
}
}
}
}
else
{ {
int li = 1, ri = 0; int li = 1, ri = 0;
if (op == IA_CMPLEU || op == IA_CMPGU || op == IA_CMPLES || op == IA_CMPGS) if (op == IA_CMPLEU || op == IA_CMPGU || op == IA_CMPLES || op == IA_CMPGS)
@ -13478,6 +13543,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
} }
} }
}
else if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst == 0 || ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == 0) else if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst == 0 || ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == 0)
{ {
int rt = ins->mSrc[1].mTemp; int rt = ins->mSrc[1].mTemp;