From da1620807fb044f2ddad2ed97ff36fd959a60cb7 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 3 Mar 2024 00:33:35 +0100 Subject: [PATCH] fixed all todos in ifelse gen --- .../src/prog8/codegen/cpu6502/IfElseAsmGen.kt | 156 ++++++++++++------ docs/source/todo.rst | 11 +- examples/test.p8 | 51 ++---- 3 files changed, 125 insertions(+), 93 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt index db586ee9c..5c5063463 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt @@ -187,7 +187,6 @@ internal class IfElseAsmGen(private val program: PtProgram, } in LogicalOperators -> { val regAtarget = AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.BOOL, stmt.definingISub(), condition.position, register=RegisterOrPair.A) - // TODO optimize this better for if statements to not require the A register to hold the intermediate boolean result if (assignmentAsmGen.optimizedLogicalExpr(condition, regAtarget)) { if (jumpAfterIf != null) translateJumpElseBodies("bne", "beq", jumpAfterIf, stmt.elseScope) @@ -779,29 +778,27 @@ _jump jmp ($asmLabel) } private fun wordLessEqualsZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) { - return if(signed) { + if(signed) { // word <= 0 - if(value is PtIdentifier) { - // special optimization to compare msb/lsb separately - // TODO also do this for array? + fun compareLsbMsb(valueLsb: String, valueMsb: String) { if(jump!=null) { val (asmLabel, indirect) = asmgen.getJumpTarget(jump) if(indirect) { asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi + bne ++ - lda ${value.name} + lda $valueLsb bne ++ + jmp ($asmLabel) +""") } else { asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi $asmLabel bne + - lda ${value.name} + lda $valueLsb beq $asmLabel +""") } @@ -812,10 +809,10 @@ _jump jmp ($asmLabel) // if and else blocks val elseLabel = asmgen.makeLabel("else") asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi + bne $elseLabel - lda ${value.name} + lda $valueLsb bne $elseLabel +""") asmgen.translate(stmt.ifScope) @@ -825,19 +822,40 @@ _jump jmp ($asmLabel) } else { // no else block asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi + bne $afterIfLabel - lda ${value.name} + lda $valueLsb bne $afterIfLabel +""") asmgen.translate(stmt.ifScope) } asmgen.out(afterIfLabel) } - return } - + + if(value is PtIdentifier) + return compareLsbMsb(value.name, value.name+"+1") + if(value is PtArrayIndexer) { + val constIndex = value.index.asConstInteger() + val varname = asmgen.asmVariableName(value.variable) + if(constIndex!=null) { + if(value.splitWords) { + return compareLsbMsb("${varname}_lsb+$constIndex", "${varname}_msb+$constIndex") + } else { + val offset = constIndex * program.memsizer.memorySize(value.type) + return compareLsbMsb("$varname+$offset", "$varname+$offset+1") + } + } else { + asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y) + if(value.splitWords) { + return compareLsbMsb("${varname}_lsb,y", "${varname}_msb,y") + } else { + return compareLsbMsb("$varname,y", "$varname+1,y") + } + } + } + asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true) if(jump!=null) { val (asmLabel, indirect) = asmgen.getJumpTarget(jump) @@ -898,26 +916,25 @@ _jump jmp ($asmLabel) private fun wordGreaterZero(value: PtExpression, signed: Boolean, jump: PtJump?, stmt: PtIfElse) { if(signed) { // word > 0 - if(value is PtIdentifier) { - // special optimization to compare msb/lsb separately - // TODO also do this for array? + + fun compareLsbMsb(valueLsb: String, valueMsb: String) { if(jump!=null) { val (asmLabel, indirect) = asmgen.getJumpTarget(jump) if(indirect) { asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi ++ bne + - lda ${value.name} + lda $valueLsb beq ++ + jmp ($asmLabel) +""") } else { asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi + bne $asmLabel - lda ${value.name} + lda $valueLsb bne $asmLabel +""") } @@ -928,10 +945,10 @@ _jump jmp ($asmLabel) // if and else blocks val elseLabel = asmgen.makeLabel("else") asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi $elseLabel bne + - lda ${value.name} + lda $valueLsb beq $elseLabel +""") asmgen.translate(stmt.ifScope) @@ -941,10 +958,10 @@ _jump jmp ($asmLabel) } else { // no else block asmgen.out(""" - lda ${value.name}+1 + lda $valueMsb bmi $afterIfLabel bne + - lda ${value.name} + lda $valueLsb beq $afterIfLabel +""") asmgen.translate(stmt.ifScope) @@ -954,6 +971,28 @@ _jump jmp ($asmLabel) return } + if(value is PtIdentifier) + return compareLsbMsb(value.name, value.name+"+1") + if(value is PtArrayIndexer) { + val constIndex = value.index.asConstInteger() + val varname = asmgen.asmVariableName(value.variable) + if(constIndex!=null) { + if(value.splitWords) { + return compareLsbMsb("${varname}_lsb+$constIndex", "${varname}_msb+$constIndex") + } else { + val offset = constIndex * program.memsizer.memorySize(value.type) + return compareLsbMsb("$varname+$offset", "$varname+$offset+1") + } + } else { + asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y) + if(value.splitWords) { + return compareLsbMsb("${varname}_lsb,y", "${varname}_msb,y") + } else { + return compareLsbMsb("$varname,y", "$varname+1,y") + } + } + } + asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true) if(jump!=null) { val (asmLabel, indirect) = asmgen.getJumpTarget(jump) @@ -1291,7 +1330,7 @@ _jump jmp ($asmLabel) lda ${left.name} cmp ${right.name} bne $afterIfLabel - lda ${left.name} + lda ${left.name}+1 cmp ${right.name}+1 bne $afterIfLabel""") asmgen.translate(stmt.ifScope) @@ -1432,26 +1471,33 @@ _jump jmp ($asmLabel) translateAYEquals("$varName+$offset", "$varName+$offset+1") } } - else { - when(right) { - is PtNumber -> { - asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) - val value = right.number.toInt() - if(notEquals) - translateAYNotEquals("#<$value", "#>$value") - else - translateAYEquals("#<$value", "#>$value") - } - is PtIdentifier -> { - asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) - if(notEquals) - translateAYNotEquals(right.name,right.name + "+1") - else - translateAYEquals(right.name, right.name + "+1") - } - else -> { - TODO("non-fallback code for array ${left.index} ${left.position}") - } + else return when(right) { + is PtNumber -> { + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) + val value = right.number.toInt() + if(notEquals) + translateAYNotEquals("#<$value", "#>$value") + else + translateAYEquals("#<$value", "#>$value") + } + is PtIdentifier -> { + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) + if(notEquals) + translateAYNotEquals(right.name,right.name + "+1") + else + translateAYEquals(right.name, right.name + "+1") + } + else -> { + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) + asmgen.saveRegisterStack(CpuRegister.A, false) + asmgen.saveRegisterStack(CpuRegister.Y, false) + asmgen.assignExpressionToVariable(right,"P8ZP_SCRATCH_W1", right.type) + asmgen.restoreRegisterStack(CpuRegister.Y, false) + asmgen.restoreRegisterStack(CpuRegister.A, false) + if(notEquals) + translateAYNotEquals("P8ZP_SCRATCH_W1", "P8ZP_SCRATCH_W1+1") + else + translateAYNotEquals("P8ZP_SCRATCH_W1", "P8ZP_SCRATCH_W1+1") } } } @@ -1493,7 +1539,13 @@ _jump jmp ($asmLabel) translateAYNotEquals(right.name, right.name + "+1") } else -> { - TODO("non-fallback code for ${left} ${left.position}") + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) + asmgen.saveRegisterStack(CpuRegister.A, false) + asmgen.saveRegisterStack(CpuRegister.Y, false) + asmgen.assignExpressionToVariable(right,"P8ZP_SCRATCH_W1", right.type) + asmgen.restoreRegisterStack(CpuRegister.Y, false) + asmgen.restoreRegisterStack(CpuRegister.A, false) + translateAYNotEquals("P8ZP_SCRATCH_W1", "P8ZP_SCRATCH_W1+1") } } } @@ -1535,7 +1587,13 @@ _jump jmp ($asmLabel) translateAYEquals(right.name, right.name + "+1") } else -> { - TODO("non-fallback code for ${left} ${left.position}") + asmgen.assignExpressionToRegister(left, RegisterOrPair.AY, signed) + asmgen.saveRegisterStack(CpuRegister.A, false) + asmgen.saveRegisterStack(CpuRegister.Y, false) + asmgen.assignExpressionToVariable(right,"P8ZP_SCRATCH_W1", right.type) + asmgen.restoreRegisterStack(CpuRegister.Y, false) + asmgen.restoreRegisterStack(CpuRegister.A, false) + translateAYEquals("P8ZP_SCRATCH_W1", "P8ZP_SCRATCH_W1+1") } } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 738d8f16b..7658515b4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,7 +1,10 @@ TODO ==== -imageviewer is larger after the master-rebase! +behind a -nostrictbool command line option: + re-allow conversion of const true/false back to ubytes 1 and 0? + re-allow conversion of const ubyte 0/1 to false/true boolean? + re-allow implicit typecast of boolean type to ubyte, and vice versa? @@ -47,9 +50,3 @@ ok ok testmonogfx works ok . check program sizes vs. master branch ===== ====== ======= - -re-allow typecast of const true/false back to ubytes 1 and 0? -re-allow typecast of const ubyte 0/1 to false/true boolean? - - -optimize translateIfByte() handling of shortcircuiting logical operators. diff --git a/examples/test.p8 b/examples/test.p8 index b12ca79f3..52b8543cb 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,4 +1,3 @@ -%import string %import textio %option no_sysinit %zeropage basicsafe @@ -6,44 +5,22 @@ main { sub start() { - bool @shared ba1, ba2, ba3, ba4, bb1, bb2, bb3, bb4 - ba1 = cx16.r0L >= 128 - ba2 = cx16.r0L >= cx16.r1L - ba3 = cx16.r0L >= @($2000) - ba4 = cx16.r0L >= @(cx16.r1) - bb1 = cx16.r0L < 128 - bb2 = cx16.r0L < cx16.r1L - bb3 = cx16.r0L < @($2000) - bb4 = cx16.r0L < @(cx16.r1) + word @shared w = -20 + word[] warr = [-1111, -2222, -3333] + word[] @split swarr = [-1111, -2222, -3333] + cx16.r0L=1 + if warr[cx16.r0L] > 0 + txt.print("yep1") -; -; ubyte[] barray = [11,22,33] -; uword[] warray = [1111,2222,3333] -; -; if any(barray) -; cx16.r0++ -; -; -; if barray[2] == 33 -; cx16.r0++ -; else -; cx16.r1++ -; -; if warray[2] == 3333 -; cx16.r0++ -; else -; cx16.r1++ -; -; if barray[cx16.r0L] == 33 -; cx16.r0++ -; else -; cx16.r1++ -; -; if warray[cx16.r0L] == 3333 -; cx16.r0++ -; else -; cx16.r1++ + if warr[cx16.r0L] <= 0 + txt.print("yep2") + + if swarr[cx16.r0L] > 0 + txt.print("yep3") + + if swarr[cx16.r0L] <= 0 + txt.print("yep4") } }