Skip to content

Commit

Permalink
Optimize native comparison against zero
Browse files Browse the repository at this point in the history
  • Loading branch information
drmortalwombat committed Sep 21, 2021
1 parent eebc39e commit 603b62b
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 7 deletions.
99 changes: 93 additions & 6 deletions autotest/testint16cmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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, %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, 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);
Expand Down Expand Up @@ -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;

}
2 changes: 1 addition & 1 deletion include/stdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
94 changes: 94 additions & 0 deletions oscar64/NativeCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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:

Expand Down

0 comments on commit 603b62b

Please sign in to comment.