diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 6c43183f7..260725d6b 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -136,28 +136,140 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateUbyteLess(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { - // TODO compare with optimized asm + if(rightConstVal!=null) { + if(leftConstVal!=null) { + if(rightConstVal>=leftConstVal) + asmgen.out(" jmp $jumpIfFalseLabel") + return + } else { + if (left is IdentifierReference) { + val name = asmgen.asmVariableName(left) + if(rightConstVal.number.toInt()!=0) + asmgen.out(""" + lda $name + cmp #${rightConstVal.number} + bcs $jumpIfFalseLabel""") + return + } + else if (left is DirectMemoryRead) { + if(rightConstVal.number.toInt()!=0) { + translateDirectMemReadExpression(left, false) + asmgen.out(" cmp #${rightConstVal.number} | bcs $jumpIfFalseLabel") + } + return + } + } + } + asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_ub | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } private fun translateByteLess(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { - // TODO compare with optimized asm + if(rightConstVal!=null) { + if(leftConstVal!=null) { + if(rightConstVal>=leftConstVal) + asmgen.out(" jmp $jumpIfFalseLabel") + return + } else { + if (left is IdentifierReference) { + val name = asmgen.asmVariableName(left) + if(rightConstVal.number.toInt()!=0) + asmgen.out(""" + lda $name + sec + sbc #${rightConstVal.number} + bvc + + eor #$80 ++ bmi + + bpl $jumpIfFalseLabel ++""") + else + asmgen.out(" lda $name | bpl $jumpIfFalseLabel") + return + } + else if (left is DirectMemoryRead) { + translateDirectMemReadExpression(left, false) + if(rightConstVal.number.toInt()!=0) { + asmgen.out(""" + sec + sbc #${rightConstVal.number} + bvc + + eor #$80 ++ bmi + + bpl $jumpIfFalseLabel ++""") + } + else + asmgen.out(" bpl $jumpIfFalseLabel") + return + } + } + } + asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_b | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } private fun translateUwordLess(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { - // TODO compare with optimized asm + if(rightConstVal!=null) { + if(leftConstVal!=null) { + if(rightConstVal>=leftConstVal) + asmgen.out(" jmp $jumpIfFalseLabel") + return + } else { + if (left is IdentifierReference) { + val name = asmgen.asmVariableName(left) + if(rightConstVal.number.toInt()!=0) + asmgen.out(""" + lda $name+1 + cmp #>${rightConstVal.number} + bcc + + bne $jumpIfFalseLabel + lda $name + cmp #<${rightConstVal.number} + bcc + + bcs $jumpIfFalseLabel ++""") + return + } + } + } + asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_uw | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") } private fun translateWordLess(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { - // TODO compare with optimized asm + if(rightConstVal!=null) { + if(leftConstVal!=null) { + if(rightConstVal>=leftConstVal) + asmgen.out(" jmp $jumpIfFalseLabel") + return + } else { + if (left is IdentifierReference) { + val name = asmgen.asmVariableName(left) + if(rightConstVal.number.toInt()!=0) + asmgen.out(""" + lda $name + cmp #<${rightConstVal.number} + lda $name+1 + sbc #>${rightConstVal.number} + bvc + + eor #$80 ++ bmi + + bpl $jumpIfFalseLabel ++""") + else + asmgen.out(" lda $name+1 | bpl $jumpIfFalseLabel") + return + } + } + } + asmgen.translateExpression(left) asmgen.translateExpression(right) asmgen.out(" jsr prog8_lib.less_w | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") @@ -502,8 +614,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge asmgen.out(" lda #<$name | sta P8ESTACK_LO,x | lda #>$name | sta P8ESTACK_HI,x | dex") } - // internal fun translateExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { - internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { + private fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { when(expr.addressExpression) { is NumericLiteralValue -> { val address = (expr.addressExpression as NumericLiteralValue).number.toInt() diff --git a/examples/test.p8 b/examples/test.p8 index 0ab4fe3cf..228d168b0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -10,120 +10,194 @@ main { sub start() { byte bb= -22 + ubyte ubb = 22 word ww= -2222 + uword uww = 2222 float ff = -1.2345 - ubyte qq = bb==22 - qq = ww==2222 - qq = ff==2.222 + repeat(25) + txt.chrout('\n') - if bb== -22 { + if bb < -1 { txt.print("1 ok\n") } else { txt.print("1 fail\n") } - if bb==99 { + if bb < -99 { txt.print("2 fail\n") } else { txt.print("2 ok\n") } - if bb==0 { - txt.print("2b fail\n") - } else { + if bb<0 { txt.print("2b ok\n") + } else { + txt.print("2b fail\n") } - if ww== -2222 { + if ww < -1 { txt.print("3 ok\n") } else { txt.print("3 fail\n") } - if ww==16384 { + if ww < -9999 { txt.print("4 fail\n") } else { txt.print("4 ok\n") } - if ww==0 { - txt.print("4b fail\n") - } else { + if ww < 0 { txt.print("4b ok\n") + } else { + txt.print("4b fail\n") } - if ff==-1.2345 { + if ff < -1.0 { txt.print("4c ok\n") } else { txt.print("4c fail\n") } - if ff==9999.9 { + if ff < -9999.9 { txt.print("4d fail\n") } else { txt.print("4d ok\n") } - if ff==0.0 { - txt.print("4e fail\n") - } else { + if ff < 0.0 { txt.print("4e ok\n") + } else { + txt.print("4e fail\n") + } + + if ubb < 100 { + txt.print("4f ok\n") + } else { + txt.print("4f fail\n") + } + + if ubb < 2 { + txt.print("4g fail\n") + } else { + txt.print("4g ok\n") + } + + if ubb<0 { + txt.print("4h fail\n") + } else { + txt.print("4h ok\n") + } + + if uww < 10000 { + txt.print("4i ok\n") + } else { + txt.print("4i fail\n") + } + + if uww < 2 { + txt.print("4j fail\n") + } else { + txt.print("4j ok\n") + } + + if uww < 0 { + txt.print("4k fail\n") + } else { + txt.print("4k ok\n") } - if bb!= 99 { + + if bb > -99 { txt.print("5 ok\n") } else { txt.print("5 fail\n") } - if bb!=-22 { + if bb > -1 { txt.print("6 fail\n") } else { txt.print("6 ok\n") } - if bb!=0 { - txt.print("6b ok\n") - } else { + if bb > 0 { txt.print("6b fail\n") + } else { + txt.print("6b ok\n") } - if ww!=16384 { + if ww > -9999 { txt.print("7 ok\n") } else { txt.print("7 fail\n") } - if ww!= -2222 { + if ww > -1 { txt.print("8 fail\n") } else { txt.print("8 ok\n") } - if ww!=0 { - txt.print("8b ok\n") - } else { + if ww>0 { txt.print("8b fail\n") + } else { + txt.print("8b ok\n") } - if ff!=-1.2345 { + if ff > -1.0 { txt.print("8c fail\n") } else { txt.print("8c ok\n") } - if ff==9999.9 { - txt.print("8d fail\n") - } else { + if ff > -9999.9 { txt.print("8d ok\n") + } else { + txt.print("8d fail\n") } - if ff!=0.0 { - txt.print("8e ok\n") - } else { + if ff > 0.0 { txt.print("8e fail\n") + } else { + txt.print("8e ok\n") + } + + if ubb > 5 { + txt.print("8f ok\n") + } else { + txt.print("8f fail\n") + } + + if ubb > 250 { + txt.print("8g fail\n") + } else { + txt.print("8g ok\n") + } + + if ubb > 0 { + txt.print("8h ok\n") + } else { + txt.print("8h fail\n") + } + + if uww > 5 { + txt.print("8i ok\n") + } else { + txt.print("8i fail\n") + } + + if uww > 9999 { + txt.print("8j fail\n") + } else { + txt.print("8j ok\n") + } + + if uww>0 { + txt.print("8b ok\n") + } else { + txt.print("8b fail\n") } ; @($c000) *= 99 ; TODO implement