From 6381d2b6ac81b0d384869af95cff0c9fc76f9bb5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 16 Mar 2021 18:15:47 +0100 Subject: [PATCH] improve word '<', word (u)word '<=' , uword '>=' codegen --- .../cpu6502/codegen/ExpressionsAsmGen.kt | 149 ++++++++++-------- docs/source/todo.rst | 4 +- 2 files changed, 89 insertions(+), 64 deletions(-) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 78b45e071..11ecbce89 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -501,6 +501,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateWordLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + + fun code(msbCpyOperand: String, lsbCmpOperand: String) { + asmgen.out(""" + cmp $lsbCmpOperand + tya + sbc $msbCpyOperand + bvc + + eor #$80 ++ bpl $jumpIfFalseLabel""") + } + if(rightConstVal!=null) { if(leftConstVal!=null) { if(rightConstVal>=leftConstVal) @@ -508,29 +519,22 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge return } else { if (left is IdentifierReference) { - val name = asmgen.asmVariableName(left) return if(rightConstVal.number.toInt()!=0) { - asmgen.out( - """ - lda $name - cmp #<${rightConstVal.number} - lda $name+1 - sbc #>${rightConstVal.number} - bvc + - eor #$80 -+ bpl $jumpIfFalseLabel""") + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + code("#>${rightConstVal.number}", "#<${rightConstVal.number}") } - else + else { + val name = asmgen.asmVariableName(left) asmgen.out(" lda $name+1 | bpl $jumpIfFalseLabel") + } } } } if(right is IdentifierReference) { - // TODO optimize comparison against identifier -// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) -// val varname = asmgen.asmVariableName(right) -// return code("$varname+1", varname) + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + val varname = asmgen.asmVariableName(right) + return code("$varname+1", varname) } asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) @@ -791,6 +795,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateUwordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + + fun code(msbCpyOperand: String, lsbCmpOperand: String) { + asmgen.out(""" + cpy $msbCpyOperand + beq + + bcs $jumpIfFalseLabel ++ cmp $lsbCmpOperand + bcs $jumpIfFalseLabel + bne $jumpIfFalseLabel""") + } + if(rightConstVal!=null) { if(leftConstVal!=null) { if(rightConstVal>leftConstVal) @@ -798,31 +813,27 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge return } else { if (left is IdentifierReference) { - val name = asmgen.asmVariableName(left) - return if(rightConstVal.number.toInt()!=0) - asmgen.out(""" - lda #>${rightConstVal.number} - cmp $name+1 - bcc $jumpIfFalseLabel - bne + - lda #<${rightConstVal.number} - cmp $name - bcc $jumpIfFalseLabel -+""") - else + return if(rightConstVal.number.toInt()!=0) { + // TODO is this correct? uword <= not-null + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + code("#>${rightConstVal.number}", "#<${rightConstVal.number}") + } + else { + val name = asmgen.asmVariableName(left) asmgen.out(""" lda $name ora $name+1 bne $jumpIfFalseLabel""") + } } } } if(right is IdentifierReference) { - // TODO optimize comparison against identifier -// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) -// val varname = asmgen.asmVariableName(right) -// return code("$varname+1", varname) + // TODO is this correct? uword <= variable + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + val varname = asmgen.asmVariableName(right) + return code("$varname+1", varname) } asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) @@ -831,6 +842,18 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateWordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + + fun code(msbCpyOperand: String, lsbCmpOperand: String) { + asmgen.out(""" + cmp $msbCpyOperand + tya + sbc $lsbCmpOperand + bvc + + eor #$80 ++ bpl $jumpIfFalseLabel""" + ) + } + if(rightConstVal!=null) { if(leftConstVal!=null) { if(rightConstVal>leftConstVal) @@ -838,17 +861,14 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge return } else { if (left is IdentifierReference) { - val name = asmgen.asmVariableName(left) - return if(rightConstVal.number.toInt()!=0) - asmgen.out(""" - lda #<${rightConstVal.number} - cmp $name - lda #>${rightConstVal.number} - sbc $name+1 - bvc + - eor #$80 - + bmi $jumpIfFalseLabel""") - else + return if(rightConstVal.number.toInt()!=0) { + // TODO is this correct? word <= not-null + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + code("#>${rightConstVal.number}", "#<${rightConstVal.number}") + } + else { + // TODO is this correct? word <= 0 (can be shorter?) + val name = asmgen.asmVariableName(left) asmgen.out(""" lda #0 cmp $name @@ -856,15 +876,16 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge bvc + eor #$80 + bmi $jumpIfFalseLabel""") + } } } } if(right is IdentifierReference) { - // TODO optimize comparison against identifier -// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) -// val varname = asmgen.asmVariableName(right) -// return code("$varname+1", varname) + // TODO is this correct? word <= variable + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + val varname = asmgen.asmVariableName(right) + return code("$varname+1", varname) } asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) @@ -944,6 +965,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } private fun translateUwordGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { + + fun code(msbCpyOperand: String, lsbCmpOperand: String) { + asmgen.out(""" + cpy $msbCpyOperand + beq + + bcc $jumpIfFalseLabel ++ cmp $lsbCmpOperand + bcc $jumpIfFalseLabel ++""") + } + if(rightConstVal!=null) { if(leftConstVal!=null) { if(rightConstVal${rightConstVal.number} - bcc $jumpIfFalseLabel - bne + - lda $name - cmp #<${rightConstVal.number} - bcc $jumpIfFalseLabel -+""") - return + if(rightConstVal.number.toInt()!=0) { + // TODO is this correct? uword >= not-0 + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + code("#>${rightConstVal.number}", "#<${rightConstVal.number}") + } } } } if(right is IdentifierReference) { - // TODO optimize comparison against identifier -// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) -// val varname = asmgen.asmVariableName(right) -// return code("$varname+1", varname) + // TODO is this correct? uword >= variable + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) + val varname = asmgen.asmVariableName(right) + return code("$varname+1", varname) } asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 434c626ef..d619902a5 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,8 +2,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() +- fix imageviewer only showing first image +- fix errors in comparison changes - add cx16 vload() - optimize several inner loops in gfx2