From ebd9f1471b97ef43b94ebfa5d21d99a01b4b3a11 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 11 Mar 2023 15:19:41 +0100 Subject: [PATCH] fix crash when using const word as pointer and implement 2 missing assign codegen paths --- .../cpu6502/assignment/AssignmentAsmGen.kt | 13 +++++++++---- .../prog8/optimizer/ConstantIdentifierReplacer.kt | 15 +++++++++++++++ .../src/prog8/optimizer/UnusedCodeRemover.kt | 2 +- compiler/test/ast/TestVariousCompilerAst.kt | 1 + .../test/codegeneration/TestVariousCodeGen.kt | 14 +++++++++++--- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 271a15283..7ad524a51 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -2656,7 +2656,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, storeRegisterAInMemoryAddress(target.memory!!) } TargetStorageKind.ARRAY -> { - throw AssemblyError("no asm gen for assign memory byte at $address to array ${target.asmVarname}") + asmgen.out(" lda ${address.toHex()}") + assignRegisterByte(target, CpuRegister.A) } TargetStorageKind.REGISTER -> when(target.register!!) { RegisterOrPair.A -> asmgen.out(" lda ${address.toHex()}") @@ -2695,7 +2696,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, storeRegisterAInMemoryAddress(target.memory!!) } TargetStorageKind.ARRAY -> { - throw AssemblyError("no asm gen for assign memory byte $identifier to array ${target.asmVarname} ") + asmgen.loadByteFromPointerIntoA(identifier) + assignRegisterByte(target, CpuRegister.A) } TargetStorageKind.REGISTER -> { asmgen.loadByteFromPointerIntoA(identifier) @@ -2737,7 +2739,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, asmgen.out(" lda #0 | sta ${wordtarget.asmVarname}+1") } TargetStorageKind.ARRAY -> { - throw AssemblyError("no asm gen for assign memory byte at $address to word array ${wordtarget.asmVarname}") + asmgen.out(" lda ${address.toHex()} | ldy #0") + assignRegisterpairWord(wordtarget, RegisterOrPair.AY) } TargetStorageKind.REGISTER -> when(wordtarget.register!!) { RegisterOrPair.AX -> asmgen.out(" ldx #0 | lda ${address.toHex()}") @@ -2765,7 +2768,9 @@ internal class AssignmentAsmGen(private val program: PtProgram, asmgen.out(" lda #0 | sta ${wordtarget.asmVarname}+1") } TargetStorageKind.ARRAY -> { - throw AssemblyError("no asm gen for assign memory byte $identifier to word array ${wordtarget.asmVarname} ") + asmgen.loadByteFromPointerIntoA(identifier) + asmgen.out(" ldy #0") + assignRegisterpairWord(wordtarget, RegisterOrPair.AY) } TargetStorageKind.REGISTER -> { asmgen.loadByteFromPointerIntoA(identifier) diff --git a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt index 3324100c7..e3067a8f7 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -93,6 +93,21 @@ internal class ConstantIdentifierReplacer(private val program: Program, private try { val cval = identifier.constValue(program) ?: return noModifications + val arrayIdx = identifier.parent as? ArrayIndexedExpression + if(arrayIdx!=null && cval.type in NumericDatatypes) { + // special case when the identifier is used as a pointer var + // var = constpointer[x] --> var = @(constvalue+x) [directmemoryread] + // constpointer[x] = var -> @(constvalue+x) [directmemorywrite] = var + val add = BinaryExpression(NumericLiteral(cval.type, cval.number, identifier.position), "+", arrayIdx.indexer.indexExpr, identifier.position) + return if(arrayIdx.parent is AssignTarget) { + val memwrite = DirectMemoryWrite(add, identifier.position) + val assignTarget = AssignTarget(null, null, memwrite, identifier.position) + listOf(IAstModification.ReplaceNode(arrayIdx.parent, assignTarget, arrayIdx.parent.parent)) + } else { + val memread = DirectMemoryRead(add, identifier.position) + listOf(IAstModification.ReplaceNode(arrayIdx, memread, arrayIdx.parent)) + } + } return when (cval.type) { in NumericDatatypes -> listOf( IAstModification.ReplaceNode( diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index a33b7e2a0..cf546afdd 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -115,7 +115,7 @@ class UnusedCodeRemover(private val program: Program, if (!forceOutput && decl.origin==VarDeclOrigin.USERCODE && !decl.sharedWithAsm) { val usages = callgraph.usages(decl) if (usages.isEmpty()) { - // if(!decl.definingModule.isLibrary) + if(!decl.definingModule.isLibrary) errors.warn("removing unused variable '${decl.name}'", decl.position) return listOf(IAstModification.Remove(decl, parent as IStatementContainer)) } diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index d259ed25e..70018fcd1 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -208,6 +208,7 @@ main { sub start() { const uword pointer=$1000 cx16.r0L = pointer[2] + pointer[2] = cx16.r0L } } """ diff --git a/compiler/test/codegeneration/TestVariousCodeGen.kt b/compiler/test/codegeneration/TestVariousCodeGen.kt index a534f7622..d2fab5501 100644 --- a/compiler/test/codegeneration/TestVariousCodeGen.kt +++ b/compiler/test/codegeneration/TestVariousCodeGen.kt @@ -112,13 +112,21 @@ main { compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null } - test("assigning memory byte into array works") { + test("assigning memory byte into arrays works") { val text=""" main { sub start() { uword factor1 - ubyte[3] @shared factor124 - factor124[0] = @(factor1) + ubyte[3] bytearray + uword[3] wordarray + @(factor1) = bytearray[0] + bytearray[0] = @(factor1) + @(factor1) = lsb(wordarray[0]) + wordarray[0] = @(factor1) + @(5000) = bytearray[0] + @(5000) = lsb(wordarray[0]) + bytearray[0] = @(5000) + wordarray[0] = @(5000) } }""" compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null