diff --git a/compiler/res/prog8lib/c64/graphics.p8 b/compiler/res/prog8lib/c64/graphics.p8 index 4593cf563..a4d86d3b6 100644 --- a/compiler/res/prog8lib/c64/graphics.p8 +++ b/compiler/res/prog8lib/c64/graphics.p8 @@ -67,11 +67,14 @@ graphics { if positive_ix { repeat { internal_plot(y1) - if internal_plotx==x2 - return + cmp(internal_plotx,x2) + if_eq return +; if internal_plotx==x2 +; return internal_plotx++ d += dy2 - if d > dx { + cmp(d,dx) + if_pl { y1++ d -= dx2 } @@ -79,11 +82,14 @@ graphics { } else { repeat { internal_plot(y1) - if internal_plotx==x2 - return + cmp(internal_plotx,x2) + if_eq return +; if internal_plotx==x2 +; return internal_plotx-- d += dy2 - if d > dx { + cmp(d,dx) + if_pl { y1++ d -= dx2 } @@ -94,11 +100,14 @@ graphics { if positive_ix { repeat { internal_plot(y1) - if y1 == y2 - return + cmp(y1,y2) + if_eq return +; if y1 == y2 +; return y1++ d += dx2 - if d > dy { + cmp(d,dy) + if_pl { internal_plotx++ d -= dy2 } @@ -106,11 +115,14 @@ graphics { } else { repeat { internal_plot(y1) - if y1 == y2 - return + cmp(y1,y2) + if_eq return +; if y1 == y2 +; return y1++ d += dx2 - if d > dy { + cmp(d,dy) + if_pl { internal_plotx-- d -= dy2 } diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 72dd193fb..7a0856f35 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -32,8 +32,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) { - // first, if it is of the form: X , swap the operands around, - // so that the constant value is always the right operand. + // This is a helper routine called from while, do-util, and if expressions to generate optimized conditional branching code. + // First, if it is of the form: X , then flip the expression so the constant is always the right operand. var left = expr.left var right = expr.right var operator = expr.operator @@ -396,6 +396,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | bcs $jumpIfFalseLabel") @@ -425,6 +426,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -461,6 +463,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel") @@ -491,6 +494,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") @@ -526,6 +530,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -560,6 +565,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -602,6 +608,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel") @@ -638,6 +645,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel") @@ -680,6 +688,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -717,6 +726,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -756,6 +766,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") @@ -792,6 +803,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") @@ -822,6 +834,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | bcc $jumpIfFalseLabel") @@ -854,6 +867,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(""" @@ -888,6 +902,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel") @@ -919,6 +934,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } + // TODO optimize this so it doesn't call a comparison-subroutine asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel") @@ -950,6 +966,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel") @@ -981,6 +998,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out(" cmp P8ZP_SCRATCH_B1 | beq $jumpIfFalseLabel") @@ -1014,6 +1032,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(""" @@ -1053,6 +1072,7 @@ 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 asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.out(""" diff --git a/docs/source/todo.rst b/docs/source/todo.rst index d6bd0e539..434c626ef 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,8 @@ TODO ==== - optimize comparisons followed by a conditional jump ; try to not have to jsr to the comparison routines. (so if/while/do-until are faster) + see: ExpressionAsmGen translateXXXXXJump() routines, all called from translateComparisonExpressionWithJumpIfFalse() +- add cx16 vload() - optimize several inner loops in gfx2 - hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine) diff --git a/examples/test.p8 b/examples/test.p8 index 09990dd4e..a6809277b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,21 +3,12 @@ main { sub start() { - byte xx - word yy - - uword addr = $3000 - cmp(xx, @($2000)) - cmp(@($2000), xx) - cmp(yy, @($2000)) - cmp(@($2000), yy) - } - sub start3() { byte xx byte yy - ; all comparisons with constant values are already optimized + ; all comparisons with constant values are already optimized. + ; but for variables (and memreads) we can optimize further (don't use temporary ZP location) byte value = 100