mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
some more optimizations in expressions with memreads
This commit is contained in:
parent
d45fe4ce74
commit
6f75413c09
@ -47,8 +47,8 @@ internal class AsmGen(private val program: Program,
|
|||||||
private val forloopsAsmGen = ForLoopsAsmGen(program, this)
|
private val forloopsAsmGen = ForLoopsAsmGen(program, this)
|
||||||
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
private val postincrdecrAsmGen = PostIncrDecrAsmGen(program, this)
|
||||||
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
||||||
private val assignmentAsmGen = AssignmentAsmGen(program, this)
|
|
||||||
private val expressionsAsmGen = ExpressionsAsmGen(program, this)
|
private val expressionsAsmGen = ExpressionsAsmGen(program, this)
|
||||||
|
private val assignmentAsmGen = AssignmentAsmGen(program, this, expressionsAsmGen)
|
||||||
internal val loopEndLabels = ArrayDeque<String>()
|
internal val loopEndLabels = ArrayDeque<String>()
|
||||||
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||||
|
|
||||||
|
@ -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")
|
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) {
|
when(expr.addressExpression) {
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
val address = (expr.addressExpression as NumericLiteralValue).number.toInt()
|
val address = (expr.addressExpression as NumericLiteralValue).number.toInt()
|
||||||
|
@ -8,12 +8,13 @@ import prog8.compiler.AssemblyError
|
|||||||
import prog8.compiler.target.CompilationTarget
|
import prog8.compiler.target.CompilationTarget
|
||||||
import prog8.compiler.target.CpuType
|
import prog8.compiler.target.CpuType
|
||||||
import prog8.compiler.target.c64.codegen.AsmGen
|
import prog8.compiler.target.c64.codegen.AsmGen
|
||||||
|
import prog8.compiler.target.c64.codegen.ExpressionsAsmGen
|
||||||
import prog8.compiler.toHex
|
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) {
|
fun translate(assignment: Assignment) {
|
||||||
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
||||||
|
@ -7,11 +7,13 @@ import prog8.compiler.AssemblyError
|
|||||||
import prog8.compiler.target.CompilationTarget
|
import prog8.compiler.target.CompilationTarget
|
||||||
import prog8.compiler.target.CpuType
|
import prog8.compiler.target.CpuType
|
||||||
import prog8.compiler.target.c64.codegen.AsmGen
|
import prog8.compiler.target.c64.codegen.AsmGen
|
||||||
|
import prog8.compiler.target.c64.codegen.ExpressionsAsmGen
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
internal class AugmentableAssignmentAsmGen(private val program: Program,
|
internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||||
private val assignmentAsmGen: AssignmentAsmGen,
|
private val assignmentAsmGen: AssignmentAsmGen,
|
||||||
|
private val exprAsmGen: ExpressionsAsmGen,
|
||||||
private val asmgen: AsmGen) {
|
private val asmgen: AsmGen) {
|
||||||
fun translate(assign: AsmAssignment) {
|
fun translate(assign: AsmAssignment) {
|
||||||
require(assign.isAugmentable)
|
require(assign.isAugmentable)
|
||||||
@ -104,6 +106,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
private fun inplaceModification(target: AsmAssignTarget, operator: String, value: Expression) {
|
private fun inplaceModification(target: AsmAssignTarget, operator: String, value: Expression) {
|
||||||
val valueLv = (value as? NumericLiteralValue)?.number
|
val valueLv = (value as? NumericLiteralValue)?.number
|
||||||
val ident = value as? IdentifierReference
|
val ident = value as? IdentifierReference
|
||||||
|
val memread = value as? DirectMemoryRead
|
||||||
|
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
@ -112,7 +115,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_byte_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt())
|
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)
|
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 -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value)
|
inplaceModification_byte_value_to_variable(target.asmVarname, target.datatype, operator, value)
|
||||||
@ -124,18 +127,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_word_litval_to_variable(target.asmVarname, target.datatype, operator, valueLv.toInt())
|
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)
|
ident != null -> inplaceModification_word_variable_to_variable(target.asmVarname, target.datatype, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
memread != null -> inplaceModification_word_memread_to_variable(target.asmVarname, target.datatype, operator, memread)
|
||||||
// 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, )
|
|
||||||
// }
|
|
||||||
value is TypecastExpression -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value)
|
inplaceModification_word_value_to_variable(target.asmVarname, target.datatype, operator, value)
|
||||||
@ -147,7 +139,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble())
|
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble())
|
||||||
ident != null -> inplaceModification_float_variable_to_variable(target.asmVarname, operator, ident)
|
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 -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_float_value_to_variable(target.asmVarname, operator, value)
|
inplaceModification_float_value_to_variable(target.asmVarname, operator, value)
|
||||||
@ -196,7 +187,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_byte_litval_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, valueLv.toInt())
|
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)
|
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 -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
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) {
|
private fun inplaceModification_word_litval_to_variable(name: String, dt: DataType, operator: String, value: Int) {
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
%target c64
|
|
||||||
%import textio
|
%import textio
|
||||||
%import syslib
|
%import syslib
|
||||||
%zeropage basicsafe
|
; %zeropage basicsafe
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
|
txt.print("hello\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user