fix byte in array assignment,

remove no longer needed array assignment ast transformation
This commit is contained in:
Irmen de Jong 2023-07-28 22:22:30 +02:00
parent c5219dfb3f
commit 46c12a8899
4 changed files with 58 additions and 97 deletions

View File

@ -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")
}
}
}

View File

@ -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())

View File

@ -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<IAstModification> {
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<IAstModification> {
// 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
}
}

View File

@ -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