diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index d9b570c29..175037976 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -2487,41 +2487,66 @@ internal class AssignmentAsmGen(private val program: PtProgram, TargetStorageKind.ARRAY -> { if(assignAsWord) TODO("assign register as word into Array not yet supported") - if (target.constArrayIndexValue!=null) { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") + if(target.array!!.splitWords) + TODO("assign register into split words ${target.position}") + if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) { + // assigning an indexed pointer var + if (target.constArrayIndexValue!=null) { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") + } + if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { + asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y") + } else { + asmgen.out(""" + ldy ${target.asmVarname} + sty P8ZP_SCRATCH_W1 + ldy ${target.asmVarname}+1 + sty P8ZP_SCRATCH_W1+1 + ldy #${target.constArrayIndexValue} + sta (P8ZP_SCRATCH_W1),y""") + } } - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y") - } else { - asmgen.out(""" - ldy ${target.asmVarname} - sty P8ZP_SCRATCH_W1 - ldy ${target.asmVarname}+1 - sty P8ZP_SCRATCH_W1+1 - ldy #${target.constArrayIndexValue} - sta (P8ZP_SCRATCH_W1),y""") + else { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") + } + val indexVar = target.array!!.index as PtIdentifier + if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { + asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y") + } else { + asmgen.out(""" + ldy ${target.asmVarname} + sty P8ZP_SCRATCH_W1 + ldy ${target.asmVarname}+1 + sty P8ZP_SCRATCH_W1+1 + ldy ${asmgen.asmVariableName(indexVar)} + sta (P8ZP_SCRATCH_W1),y""") + } } - } - else { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") + return + } else { + // assign regular array indexing + if (target.constArrayIndexValue!=null) { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") + } + asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}") } - val indexVar = target.array!!.index as PtIdentifier - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y") - } else { - asmgen.out(""" - ldy ${target.asmVarname} - sty P8ZP_SCRATCH_W1 - ldy ${target.asmVarname}+1 - sty P8ZP_SCRATCH_W1+1 - ldy ${asmgen.asmVariableName(indexVar)} - sta (P8ZP_SCRATCH_W1),y""") + else { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") + } + val indexVar = target.array!!.index as PtIdentifier + asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y") } } } diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index df3577760..e33b39b5b 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -108,9 +108,6 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati checker2.visit(this) if(errors.noErrors()) { - val transforms = AstOnetimeTransforms(this, options) - transforms.visit(this) - transforms.applyModifications() val lit2decl = LiteralsToAutoVars(this, options.compTarget, errors) lit2decl.visit(this) if(errors.noErrors()) diff --git a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt b/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt deleted file mode 100644 index 6c8b0b989..000000000 --- a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt +++ /dev/null @@ -1,62 +0,0 @@ -package prog8.compiler.astprocessing - -import prog8.ast.Node -import prog8.ast.Program -import prog8.ast.expressions.* -import prog8.ast.statements.AssignTarget -import prog8.ast.statements.Assignment -import prog8.ast.statements.DirectMemoryWrite -import prog8.ast.statements.VarDecl -import prog8.ast.walk.AstWalker -import prog8.ast.walk.IAstModification -import prog8.code.core.CompilationOptions -import prog8.code.core.DataType -import prog8.code.target.VMTarget - - -internal class AstOnetimeTransforms(private val program: Program, private val options: CompilationOptions) : AstWalker() { - - override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { - if(parent !is VarDecl) { - if(options.compTarget.name == VMTarget.NAME) - return noModifications // vm codegen deals correctly with all cases - // Don't replace the initializer value in a vardecl - this will be moved to a separate - // assignment statement soon in after(VarDecl) - return replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression, parent) - } - return noModifications - } - - private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { - // note: The CodeDesugarer already does something similar, but that is meant ONLY to take - // into account the case where the index value is a word type. - // The replacement here is to fix missing cases in the 6502 codegen. (VM codegen doesn't use this workaround) - // TODO make the 6502 codegen better so this workaround can be removed - val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program) - if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) { - if(parent is AssignTarget) { - val assignment = parent.parent as? Assignment - if(assignment?.value is NumericLiteral || assignment?.value is IdentifierReference) { - // the codegen contains correct optimized code ONLY for a constant assignment, or direct variable assignment. - return noModifications - } - // Other cases aren't covered correctly by the 6502 codegen, and there are a LOT of cases. - // So rewrite assignment target pointervar[index] into @(pointervar+index) - // (the 6502 codegen covers all cases correctly for a direct memory assignment). - val indexer = arrayIndexedExpression.indexer - val add: Expression = - if(indexer.indexExpr.constValue(program)?.number==0.0) - arrayIndexedExpression.arrayvar.copy() - else - BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position) - val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) - val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) - return listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) - } - } - - return noModifications - } -} - - diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 657588a06..b3457fff1 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,7 @@ TODO ==== +- bugfixes: assem crashing, imageviewer not loading past boat image, rockrunner music borked. - stackless: describe the changes in the manual. - IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction