diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 7a0856f35..399f326ee 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -966,7 +966,23 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // TODO optimize if right is variable or mem-read to avoid use of ZP location + if(right is IdentifierReference) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.A) + asmgen.out(" cmp ${asmgen.asmVariableName(right)} | bne $jumpIfFalseLabel") + return + } + var memread = right as? DirectMemoryRead + if(memread==null && right is TypecastExpression) + memread = right.expression as? DirectMemoryRead + if(memread!=null) { + val address = memread.addressExpression as? NumericLiteralValue + if(address!=null) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.A) + asmgen.out(" cmp ${address.number.toHex()} | bne $jumpIfFalseLabel") + return + } + } + asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel") @@ -998,7 +1014,23 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // TODO optimize if right is variable or mem-read to avoid use of ZP location + if(right is IdentifierReference) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.A) + asmgen.out(" cmp ${asmgen.asmVariableName(right)} | beq $jumpIfFalseLabel") + return + } + var memread = right as? DirectMemoryRead + if(memread==null && right is TypecastExpression) + memread = right.expression as? DirectMemoryRead + if(memread!=null) { + val address = memread.addressExpression as? NumericLiteralValue + if(address!=null) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.A) + asmgen.out(" cmp ${address.number.toHex()} | beq $jumpIfFalseLabel") + return + } + } + asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | beq $jumpIfFalseLabel") @@ -1032,7 +1064,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // TODO optimize if right is variable or mem-read to avoid use of ZP location + if(right is IdentifierReference) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + asmgen.out(""" + cmp ${asmgen.asmVariableName(right)} + bne $jumpIfFalseLabel + cpy ${asmgen.asmVariableName(right)}+1 + bne $jumpIfFalseLabel + """) + return + } + asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(""" @@ -1072,7 +1114,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - // TODO optimize if right is variable or mem-read to avoid use of ZP location + if(right is IdentifierReference) { + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + asmgen.out(""" + cmp ${asmgen.asmVariableName(right)} + bne + + cpy ${asmgen.asmVariableName(right)}+1 + beq $jumpIfFalseLabel ++""") + return + } + asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(""" diff --git a/examples/test.p8 b/examples/test.p8 index a6809277b..24adf5a26 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,6 +4,49 @@ main { sub start() { + word xx + word yy + + ; all comparisons with constant values are already optimized. + ; but for variables (and memreads) we can optimize further (don't use temporary ZP location) + + word value = 100 + + while xx==value { + yy++ + } + + while xx!=value { + yy++ + } + + do { + yy++ + } until xx==value + + do { + yy++ + } until xx!=value + + if xx==value + yy++ + + if xx!=value + yy++ + +; while xx>value { +; yy++ +; } +; do { +; yy++ +; } until xx>value +; +; if xx>value +; yy++ + } + + sub start3() { + byte xx byte yy @@ -16,11 +59,15 @@ main { yy++ } + while xx==@($2000) { + yy++ + } + while xx!=value { yy++ } - while xx>value { + while xx!=@($2000) { yy++ } @@ -32,18 +79,21 @@ main { yy++ } until xx!=value - do { - yy++ - } until xx>value - if xx==value yy++ if xx!=value yy++ - if xx>value - yy++ +; while xx>value { +; yy++ +; } +; do { +; yy++ +; } until xx>value +; +; if xx>value +; yy++ }