some more optimizations in expressions with memreads

This commit is contained in:
Irmen de Jong 2020-09-27 21:43:40 +02:00
parent d45fe4ce74
commit 6f75413c09
5 changed files with 69 additions and 22 deletions

View File

@ -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<String>()
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()

View File

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

View File

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

View File

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

View File

@ -1,12 +1,11 @@
%target c64
%import textio
%import syslib
%zeropage basicsafe
; %zeropage basicsafe
main {
sub start() {
txt.print("hello\n")
}
}