From 8e00408e3e2c80fb2f0ae429e8890275c43f7efa Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 3 Feb 2024 23:11:53 +0100 Subject: [PATCH] optimize pointer indexing a bit --- .../cpu6502/assignment/AssignmentAsmGen.kt | 51 ++++++++++++------- docs/source/todo.rst | 5 +- examples/test.p8 | 22 ++++---- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 3925f86ee..73b3c30d3 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -797,7 +797,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, else asmgen.out(" sec | sbc $arrayvarname,y") assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true) - } else if(expr.operator=="+" && leftMemByte!=null && right.type in ByteDatatypes && optimizedPointerIndexPlusByteIntoA(leftMemByte, right)) { + } else if(expr.operator=="+" && leftMemByte!=null && right.type in ByteDatatypes && optimizedPointerIndexPlusMinusByteIntoA(right, "+", leftMemByte)) { assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true) return true } else if(rightMemByte!=null && left.type in ByteDatatypes && optimizedPointerIndexPlusMinusByteIntoA(left, expr.operator, rightMemByte)) { @@ -987,29 +987,44 @@ internal class AssignmentAsmGen(private val program: PtProgram, return false } - private fun optimizedPointerIndexPlusByteIntoA(mem: PtMemoryByte, value: PtExpression): Boolean { - // special optimization for pointervar[y] + bytevalue (actually: @(address) + value) - return false // TODO implement this optimization? - } - private fun optimizedPointerIndexPlusMinusByteIntoA(value: PtExpression, operator: String, mem: PtMemoryByte): Boolean { // special optimization for bytevalue +/- pointervar[y] (actually: bytevalue +/- @(address) ) val address = mem.address as? PtBinaryExpression - if(address is PtBinaryExpression) { - val offset = address.right.asConstInteger() - if(offset!=null && offset<256) { - // we have value + @(ptr + 255), or value - @(ptr+255) -// TODO() - } else if(address.right.type in ByteDatatypes) { - // we have @(ptr + bytevar) ++ , or @(ptr+bytevar)-- -// TODO() - } else if((address.right as? PtTypeCast)?.value?.type in ByteDatatypes) { - // we have @(ptr + bytevar) ++ , or @(ptr+bytevar)-- -// TODO() + val ptrVar = address.left as? PtIdentifier + if(ptrVar!=null && asmgen.isZpVar(ptrVar)) { + assignExpressionToRegister(value, RegisterOrPair.A, false) + val pointername = asmgen.asmVariableName(ptrVar) + val constOffset = address.right.asConstInteger() + if (constOffset != null && constOffset < 256) { + // we have value + @(zpptr + 255), or value - @(zpptr+255) + asmgen.out(" ldy #$constOffset") + if (operator == "+") + asmgen.out(" clc | adc ($pointername),y") + else + asmgen.out(" sec | sbc ($pointername),y") + } else if (address.right.type in ByteDatatypes) { + // we have @(ptr + bytevar) ++ , or @(ptr+bytevar)-- + asmgen.out(" pha") + assignExpressionToRegister(address.right, RegisterOrPair.Y, false) + asmgen.out(" pla") + if (operator == "+") + asmgen.out(" clc | adc ($pointername),y") + else + asmgen.out(" sec | sbc ($pointername),y") + } else if ((address.right as? PtTypeCast)?.value?.type in ByteDatatypes) { + // we have @(ptr + bytevar as uword) ++ , or @(ptr+bytevar as uword)-- + asmgen.out(" pha") + assignExpressionToRegister((address.right as PtTypeCast).value, RegisterOrPair.Y, false) + asmgen.out(" pla") + if (operator == "+") + asmgen.out(" clc | adc ($pointername),y") + else + asmgen.out(" sec | sbc ($pointername),y") + } + return true } } - println("TODO: OPTIMIZE POINTER PLUSMINUS ${value.position}") return false } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bd4dc5d5f..81a34d384 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,10 +1,7 @@ TODO ==== -petaxian is now a lot larger since pointer[idx] is rewritten into @(ptr+idx). Missing some optimized code somewhere now? -VM textelite is now a lot larger too - -DO: "TODO implement this optimization" +VM textelite is now a lot larger due to the ptr[i] -> @(ptr+i) rewrite. Fix this. (after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type. diff --git a/examples/test.p8 b/examples/test.p8 index a60058068..437c7da47 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -10,15 +10,19 @@ main { ubyte @shared offset=4 uword @shared az = $4000 ubyte @shared value = 22 - @($4004) = 99 - az[4]-- - @(az + offset)-- - txt.print_ub(@($4004)) - txt.nl() - az[4]++ - @(az+offset)++ - txt.print_ub(@($4004)) - txt.nl() + + cx16.r0H = value*4 + az[value] + cx16.r0L = az[value] + value*4 + +; @($4004) = 99 +; az[4]-- +; @(az + offset)-- +; txt.print_ub(@($4004)) +; txt.nl() +; az[4]++ +; @(az+offset)++ +; txt.print_ub(@($4004)) +; txt.nl() ; cx16.r0L = az[4] + value*5 ; cx16.r1L = value*5 + az[4]