diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt index 5e14d1945..37c0c401e 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt @@ -43,6 +43,13 @@ internal fun optimizeAssembly(lines: MutableList, machine: IMachineDefin numberOfOptimizations++ } + mods = optimizeUnneededTempvarInAdd(linesByFour) + if(mods.isNotEmpty()) { + apply(mods, lines) + linesByFour = getLinesBy(lines, 4) + numberOfOptimizations++ + } + var linesByFourteen = getLinesBy(lines, 14) mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable) if(mods.isNotEmpty()) { @@ -508,4 +515,27 @@ private fun optimizeUselessPushPopStack(linesByFour: List>>): List { + // sequence: sta P8ZP_SCRATCH_XX / lda something / clc / adc P8ZP_SCRATCH_XX + // this can be performed without the scratch variable: clc / adc something + val mods = mutableListOf() + + for(lines in linesByFour) { + val first = lines[0].value.trimStart() + val second = lines[1].value.trimStart() + val third = lines[2].value.trimStart() + val fourth = lines[3].value.trimStart() + if(first.startsWith("sta P8ZP_SCRATCH_") && second.startsWith("lda") && third.startsWith("clc") && fourth.startsWith("adc P8ZP_SCRATCH_") ) { + if(fourth.substring(4)==first.substring(4)) { + mods.add(Modification(lines[0].index, false, " clc")) + mods.add(Modification(lines[1].index, false, " adc ${second.substring(3).trimStart()}")) + mods.add(Modification(lines[2].index, true, null)) + mods.add(Modification(lines[3].index, true, null)) + } + } + } + + return mods +} diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index 24dadd533..aa5d0ca52 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -707,6 +707,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) { + // TODO optimize: don't use scratch var if possible val tmpVar = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG" asmgen.assignExpressionToVariable(value, tmpVar, value.type) asmgen.out(" lda $name") @@ -1080,6 +1081,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } "-" -> { asmgen.translateDirectMemReadExpressionToRegA(memread) + // TODO optimize: don't use scratch var if possible val tmpByte = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG" asmgen.out(""" sta $tmpByte @@ -2025,8 +2027,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, // the other variable is a BYTE type so optimize for that when (operator) { "+" -> { - asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt) - if(valueDt==DataType.UBYTE) + if(valueDt==DataType.UBYTE) { + // TODO optimize: don't use scratch var + asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt) asmgen.out(""" lda $name clc @@ -2035,7 +2038,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, bcc + inc $name+1 +""") - else + } else { + // TODO optimize: don't use scratch var + asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt) asmgen.out(""" ldy #0 lda P8ZP_SCRATCH_B1 @@ -2047,8 +2052,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, tya adc $name+1 sta $name+1""") + } } "-" -> { + // TODO optimize: don't use scratch var asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt) if(valueDt==DataType.UBYTE) asmgen.out(""" diff --git a/docs/source/todo.rst b/docs/source/todo.rst index b39bf7e97..96dba71d7 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,5 +1,7 @@ TODO ==== + +- optimize: search for TODO optimize: don't use scratch var - prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm? - allow 'chained' array indexing for expressions: value = ptrarray[0][0] - allow 'chained' array indexing for assign targets: ptrarray[0][0] = 42 this is just evaluating the lhs as a uword pointer expression diff --git a/examples/test.p8 b/examples/test.p8 index 7303eba07..05a038515 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,42 +4,11 @@ main { sub start() { - uword w1 - uword w2 + ubyte index + ubyte[] t_index = [1,2,3,4,5] + ubyte nibble = 0 - ubyte b1 - ubyte b2 - - b1 = 255 - b2 = 1 - txt.print_ub(b1&b2!=0) ; true - txt.spc() - txt.print_ub(b1&b2==0) ; false - txt.nl() - - b1 = 255 - b2 = 0 - txt.print_ub(b1&b2!=0) ; false - txt.spc() - txt.print_ub(b1&b2==0) ; true - txt.nl() - - w1 = $ff0f - w2 = $0101 - txt.print_ub(w1&w2!=0) ; true - txt.spc() - txt.print_ub(w1&w2==0) ; false - txt.nl() - - w1 = $ff0f - w2 = $00f0 - txt.print_ub(w1&w2!=0) ; false - txt.spc() - txt.print_ub(w1&w2==0) ; true - txt.nl() - - -; if w1 & w2 -; cx16.r0++ + index -= t_index[4] + index -= t_index[nibble] } }