From 9f72779cdc817ae5fe5d17a21e775a5cf1c080ec Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 15 Jan 2021 19:52:53 +0100 Subject: [PATCH] optimize assignment from memory pointer with fixed byte offset --- .../codegen/assignment/AssignmentAsmGen.kt | 37 +++++++++++++++---- examples/test.p8 | 1 + 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index dbd6b9046..9c3e1cc5f 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -112,6 +112,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } } SourceStorageKind.MEMORY -> { + fun assignViaExprEval(expression: Expression) { + assignExpressionToVariable(expression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, assign.target.scope) + if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) + asmgen.out(" lda (P8ZP_SCRATCH_W2)") + else + asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y") + assignRegisterByte(assign.target, CpuRegister.A) + } + val value = assign.source.memory!! when (value.addressExpression) { is NumericLiteralValue -> { @@ -121,14 +130,28 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen is IdentifierReference -> { assignMemoryByte(assign.target, null, value.addressExpression as IdentifierReference) } - else -> { - assignExpressionToVariable(value.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, assign.target.scope) - if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) - asmgen.out(" lda (P8ZP_SCRATCH_W2)") - else - asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y") - assignRegisterByte(assign.target, CpuRegister.A) + is BinaryExpression -> { + // try to optimize simple cases like assignment from ptr+1, ptr+2... + var optimized = false + val expr = value.addressExpression as BinaryExpression + if(expr.operator=="+") { + // we can assume const operand has been moved to the right. + val constOperand = expr.right.constValue(program) + if(constOperand!=null) { + val intIndex = constOperand.number.toInt() + if(intIndex in 1..255) { + assignExpressionToVariable(expr.left, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, assign.target.scope) + asmgen.out(" ldy #${intIndex} | lda (P8ZP_SCRATCH_W2),y") + assignRegisterByte(assign.target, CpuRegister.A) + optimized = true + } + } + } + + if(!optimized) + assignViaExprEval(expr) } + else -> assignViaExprEval(value.addressExpression) } } SourceStorageKind.EXPRESSION -> { diff --git a/examples/test.p8 b/examples/test.p8 index 00f1e59ad..26ed31d0a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -23,6 +23,7 @@ main { txt.nl() txt.nl() + txt.chrout(@(ptr)) txt.chrout(@(ptr+1)) txt.chrout(@(ptr+2))