From 3277544295ed8c4092d80dae45e38a7c250ed2b6 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 4 Nov 2023 00:33:50 +0100 Subject: [PATCH] optimize assigning word array value to byte variable --- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 20 ++++++++++++- .../cpu6502/assignment/AssignmentAsmGen.kt | 6 ++++ examples/test.p8 | 28 ++++++++++++++++--- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index d024d2b2e..6524689b7 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -1115,7 +1115,25 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, else -> throw AssemblyError("invalid reg") } } else { - when(resultRegister) { + if(arg is PtArrayIndexer && resultRegister in setOf(null, RegisterOrPair.A, RegisterOrPair.Y, RegisterOrPair.X)) { + // just read the lsb byte out of the word array + val arrayVar = if(arg.splitWords) asmgen.asmVariableName(arg.variable)+"_lsb" else asmgen.asmVariableName(arg.variable) + when(resultRegister) { + null, RegisterOrPair.A -> { + asmgen.loadScaledArrayIndexIntoRegister(arg, arg.type, CpuRegister.Y) + asmgen.out(" lda $arrayVar,y") + } + RegisterOrPair.Y -> { + asmgen.loadScaledArrayIndexIntoRegister(arg, arg.type, CpuRegister.X) + asmgen.out(" lda $arrayVar,x") + } + RegisterOrPair.X -> { + asmgen.loadScaledArrayIndexIntoRegister(arg, arg.type, CpuRegister.Y) + asmgen.out(" ldx $arrayVar,y") + } + else -> throw AssemblyError("invalid reg") + } + } else when(resultRegister) { null, RegisterOrPair.A -> { asmgen.assignExpressionToRegister(arg, RegisterOrPair.AY) // NOTE: we rely on the fact that the above assignment to AY, assigns the Lsb to A as the last instruction. diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 7634de89b..7d2416a2c 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -1787,6 +1787,12 @@ internal class AssignmentAsmGen(private val program: PtProgram, } } is PtNumber -> throw AssemblyError("a cast of a literal value should have been const-folded away") + is PtArrayIndexer -> { + if(targetDt in ByteDatatypes && valueDt in WordDatatypes) { + // just assign the lsb from the array value + return assignCastViaLsbFunc(value, target) + } + } else -> {} } diff --git a/examples/test.p8 b/examples/test.p8 index dbdd7b94c..81423210f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,10 +1,30 @@ %import syslib -%zpreserved $a0,$ff -%zpallowed $70,$b0 +%import textio +%zeropage basicsafe main { sub start() { - repeat { - } + uword[] wordarray = [0,1,2,3,4,5,6,7,8,9] + ubyte n = 5 + n = lsb(wordarray[n]) + n = wordarray[n] as ubyte + test(wordarray[n] as ubyte,wordarray[n] as ubyte,0) + test(lsb(wordarray[n]), lsb(wordarray[n]),0) + } + + asmsub test(ubyte a1 @A, ubyte a2 @X, ubyte a3 @Y) { + %asm {{ + phy + phx + jsr txt.print_ub + jsr txt.spc + pla + jsr txt.print_ub + jsr txt.spc + pla + jsr txt.print_ub + jsr txt.nl + rts + }} } }