diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index c0b96961d..b5d69202d 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -47,8 +47,8 @@ internal class AsmGen(private val program: Program, private val forloopsAsmGen = ForLoopsAsmGen(program, this) private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this) private val functioncallAsmGen = FunctionCallAsmGen(program, this) - private val assignmentAsmGen = AssignmentAsmGen(program, this) private val expressionsAsmGen = ExpressionsAsmGen(program, this) + private val assignmentAsmGen = AssignmentAsmGen(program, this, expressionsAsmGen) internal val loopEndLabels = ArrayDeque() private val blockLevelVarInits = mutableMapOf>() diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 5208f7268..6c1e95b3d 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -1065,7 +1065,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge asmgen.out(" lda #<$name | sta P8ESTACK_LO,x | lda #>$name | sta P8ESTACK_HI,x | dex") } - private fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { + internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { when(expr.addressExpression) { is NumericLiteralValue -> { val address = (expr.addressExpression as NumericLiteralValue).number.toInt() 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 50da5ab11..b8b9a9de8 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -8,12 +8,13 @@ import prog8.compiler.AssemblyError import prog8.compiler.target.CompilationTarget import prog8.compiler.target.CpuType import prog8.compiler.target.c64.codegen.AsmGen +import prog8.compiler.target.c64.codegen.ExpressionsAsmGen import prog8.compiler.toHex -internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen) { +internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen, private val exprAsmgen: ExpressionsAsmGen) { - private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen) + private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, exprAsmgen, asmgen) fun translate(assignment: Assignment) { val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt index 6f728b120..ef1626e47 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -7,11 +7,13 @@ import prog8.compiler.AssemblyError import prog8.compiler.target.CompilationTarget import prog8.compiler.target.CpuType import prog8.compiler.target.c64.codegen.AsmGen +import prog8.compiler.target.c64.codegen.ExpressionsAsmGen import prog8.compiler.toHex import kotlin.math.absoluteValue internal class AugmentableAssignmentAsmGen(private val program: Program, private val assignmentAsmGen: AssignmentAsmGen, + private val exprAsmGen: ExpressionsAsmGen, private val asmgen: AsmGen) { fun translate(assign: AsmAssignment) { require(assign.isAugmentable) @@ -104,6 +106,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, private fun inplaceModification(target: AsmAssignTarget, operator: String, value: Expression) { val valueLv = (value as? NumericLiteralValue)?.number val ident = value as? IdentifierReference + val memread = value as? DirectMemoryRead when(target.kind) { TargetStorageKind.VARIABLE -> { @@ -112,7 +115,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, when { valueLv != null -> inplaceModification_byte_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt()) ident != null -> inplaceModification_byte_variable_to_variable(target.asmVarname, target.datatype, operator, ident) - // TODO more specialized code for types such as memory read etc. + memread != null -> inplaceModification_byte_memread_to_variable(target.asmVarname, target.datatype, operator, memread) value is TypecastExpression -> { if (tryRemoveRedundantCast(value, target, operator)) return inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value) @@ -124,18 +127,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, when { valueLv != null -> inplaceModification_word_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt()) ident != null -> inplaceModification_word_variable_to_variable(target.asmVarname, target.datatype, operator, ident) - // TODO more specialized code for types such as memory read etc. -// value is DirectMemoryRead -> { -// println("warning: slow stack evaluation used (8): $name $operator= ${value::class.simpleName} at ${value.position}") -// // assignmentAsmGen.translateOtherAssignment(origAssign) -// asmgen.translateExpression(value.addressExpression) -// asmgen.out(""" -// jsr prog8_lib.read_byte_from_address_on_stack -// sta ... -// inx -// """) -// inplaceModification_word_value_to_variable(name, operator, ) -// } + memread != null -> inplaceModification_word_memread_to_variable(target.asmVarname, target.datatype, operator, memread) value is TypecastExpression -> { if (tryRemoveRedundantCast(value, target, operator)) return inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value) @@ -147,7 +139,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, when { valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble()) ident != null -> inplaceModification_float_variable_to_variable(target.asmVarname, operator, ident) - // TODO more specialized code for types such as memory read etc. value is TypecastExpression -> { if (tryRemoveRedundantCast(value, target, operator)) return inplaceModification_float_value_to_variable(target.asmVarname, operator, value) @@ -196,7 +187,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, when { valueLv != null -> inplaceModification_byte_litval_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, valueLv.toInt()) ident != null -> inplaceModification_byte_variable_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, ident) - // TODO more specialized code for types such as memory read etc. + memread != null -> inplaceModification_byte_memread_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, memread) value is TypecastExpression -> { if (tryRemoveRedundantCast(value, target, operator)) return inplaceModification_byte_value_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value) @@ -636,6 +627,62 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, } } + private fun inplaceModification_byte_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) { + when(operator) { + "+" -> { + exprAsmGen.translateDirectMemReadExpression(memread, false) + asmgen.out(""" + clc + adc $name + sta $name""") + } + "-" -> { + exprAsmGen.translateDirectMemReadExpression(memread, false) + asmgen.out(""" + sta P8ZP_SCRATCH_B1 + lda $name + sec + sbc P8ZP_SCRATCH_B1 + sta $name""") + // TODO: more operators + } + else -> { + inplaceModification_byte_value_to_variable(name, dt, operator, memread); + } + } + } + + private fun inplaceModification_word_memread_to_variable(name: String, dt: DataType, operator: String, memread: DirectMemoryRead) { + when(operator) { + "+" -> { + exprAsmGen.translateDirectMemReadExpression(memread, false) + asmgen.out(""" + clc + adc $name + sta $name + bcc + + inc $name+1 ++""") + } + "-" -> { + exprAsmGen.translateDirectMemReadExpression(memread, false) + asmgen.out(""" + sta P8ZP_SCRATCH_B1 + lda $name + sec + sbc P8ZP_SCRATCH_B1 + sta $name + bcc + + dec $name+1 ++""") + // TODO: more operators + } + else -> { + inplaceModification_word_value_to_variable(name, dt, operator, memread); + } + } + } + private fun inplaceModification_word_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) { when (operator) { // note: ** (power) operator requires floats. diff --git a/examples/test.p8 b/examples/test.p8 index e3eb61773..6d7e538a3 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,12 +1,11 @@ -%target c64 %import textio %import syslib -%zeropage basicsafe +; %zeropage basicsafe main { sub start() { - + txt.print("hello\n") } }