diff --git a/autotest/testint16cmp.c b/autotest/testint16cmp.c index 096c455d..d7512816 100644 --- a/autotest/testint16cmp.c +++ b/autotest/testint16cmp.c @@ -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); @@ -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; } diff --git a/include/stdio.c b/include/stdio.c index d8758319..a92edd85 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -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'; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 5274c37c..0052b7c9 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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: