diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt index 236b0f092..3348c4b85 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt @@ -79,7 +79,7 @@ internal class IfElseAsmGen(private val program: PtProgram, } private fun fallbackTranslate(stmt: PtIfElse, warning: Boolean) { - if(warning) println("WARN: FALLBACK IF: ${stmt.position}") // TODO should have no more of these + if(warning) println("WARN: SLOW FALLBACK IF: ${stmt.position}. Ask for support.") // TODO should have no more of these val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump assignConditionValueToRegisterAndTest(stmt.condition) if(jumpAfterIf!=null) @@ -733,7 +733,10 @@ _jump jmp ($asmLabel) is PtArrayIndexer -> { val varname = asmgen.asmVariableName(value.variable) asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y) - asmgen.out(" lda $varname+1,y") + if(value.splitWords) + asmgen.out(" lda ${varname}_msb,y") + else + asmgen.out(" lda $varname+1,y") } is PtIdentifier -> { val varname = asmgen.asmVariableName(value) @@ -1013,10 +1016,14 @@ _jump jmp ($asmLabel) is PtArrayIndexer -> { val constIndex = value.index.asConstInteger() if(constIndex!=null) { - val offset = constIndex * program.memsizer.memorySize(value.type) - if(offset<256) { - val varName = asmgen.asmVariableName(value.variable) - return translateLoadFromVar("$varName+$offset", "bne", "beq") + if(value.splitWords) { + TODO("split word array != 0") + } else { + val offset = constIndex * program.memsizer.memorySize(value.type) + if (offset < 256) { + val varName = asmgen.asmVariableName(value.variable) + return translateLoadFromVar("$varName+$offset", "bne", "beq") + } } } viaScratchReg("bne", "beq") @@ -1029,15 +1036,19 @@ _jump jmp ($asmLabel) } else { when (value) { is PtArrayIndexer -> { - val constIndex = value.index.asConstInteger() - if(constIndex!=null) { - val offset = constIndex * program.memsizer.memorySize(value.type) - if(offset<256) { - val varName = asmgen.asmVariableName(value.variable) - return translateLoadFromVar("$varName+$offset", "beq", "bne") + if(value.splitWords) { + TODO("split word array ==0") + } else { + val constIndex = value.index.asConstInteger() + if (constIndex != null) { + val offset = constIndex * program.memsizer.memorySize(value.type) + if (offset < 256) { + val varName = asmgen.asmVariableName(value.variable) + return translateLoadFromVar("$varName+$offset", "beq", "bne") + } } + viaScratchReg("beq", "bne") } - viaScratchReg("beq", "bne") } is PtIdentifier -> { return translateLoadFromVar(asmgen.asmVariableName(value), "beq", "bne") @@ -1156,16 +1167,19 @@ _jump jmp ($asmLabel) if(notEquals) { when(left) { is PtArrayIndexer -> { - asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) val constIndex = left.index.asConstInteger() if(constIndex!=null) { + asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) + if(left.splitWords) { + TODO("split word array !=") + } val offset = constIndex * program.memsizer.memorySize(left.type) if(offset<256) { val varName = asmgen.asmVariableName(left.variable) return translateNotEquals("$varName+$offset", "$varName+$offset+1") } } - fallbackTranslate(stmt, false) + fallbackTranslate(stmt, true) } is PtIdentifier -> { asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) @@ -1176,13 +1190,9 @@ _jump jmp ($asmLabel) if(left.isFromArrayElement) fallbackTranslate(stmt, false) else { - if(left.isFromArrayElement) - fallbackTranslate(stmt, false) - else { - asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) - val varname = asmgen.asmVariableName(left.identifier) - return translateNotEquals("#<$varname", "#>$varname") - } + asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) + val varname = asmgen.asmVariableName(left.identifier) + return translateNotEquals("#<$varname", "#>$varname") } } else -> fallbackTranslate(stmt, false) @@ -1190,16 +1200,19 @@ _jump jmp ($asmLabel) } else { when(left) { is PtArrayIndexer -> { - asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) val constIndex = left.index.asConstInteger() if(constIndex!=null) { + asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) + if(left.splitWords) { + TODO("split word array ==") + } val offset = constIndex * program.memsizer.memorySize(left.type) if(offset<256) { val varName = asmgen.asmVariableName(left.variable) return translateEquals("$varName+$offset", "$varName+$offset+1") } } - fallbackTranslate(stmt, false) + fallbackTranslate(stmt, true) } is PtIdentifier -> { asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index fd016e7da..a301352a8 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,7 +1,8 @@ TODO ==== -test if any()... code size +add peephole asm optimizer that removes a cmp #0 directly after a lda (same for cpx cpy) +check all comparisons for split word arrays (signed+unsigned, all 4 variants) floatparse is slightly larger @@ -9,7 +10,6 @@ snow is a lot larger neofetch is sligthly larger - explore possible optimizations for words when comparing to a constant number (BeforeAsmAstChanger) @@ -17,6 +17,10 @@ add tests for comparison that do an assignment rather than an if assign to variable, and barray[indexvar], test if they're both correct (bb = value > -100 --> contains a beq +++ that shouldn't be there??) +optimize assignOptimizedComparisonWords for when comparing to simple things like number and identifier. +optimize optimizedPlusMinExpr for when comparing to simple things like number and identifier. +optimize the IfElseAsmgen's fallbackTranslate even more (for arrays without const index for example?) + ===== ====== ======= diff --git a/examples/test.p8 b/examples/test.p8 index 70f4b74a6..711e8eea9 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,12 +6,32 @@ main { sub start() { + ubyte[] barray = [11,22,33] + uword[] warray = [1111,2222,3333] - if not string.isdigit(cx16.r0L) - goto done - - cx16.r0L++ -done: + 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++ } }