From 1c411897df400e4f5e53284d4feedf4ddde97f52 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 27 Jul 2019 03:11:15 +0200 Subject: [PATCH] some more asmgen v2, and seemingly useless assignments to memory variables are no longer optimized away --- .../compiler/target/c64/codegen2/AsmGen2.kt | 97 ++++++++++++++----- .../src/prog8/optimizer/ConstantFolding.kt | 19 ---- .../src/prog8/optimizer/StatementOptimizer.kt | 6 +- 3 files changed, 79 insertions(+), 43 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index c1069ecbd..6b109a35d 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -14,6 +14,7 @@ import prog8.compiler.target.c64.MachineDefinition.C64Zeropage import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_HEX import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_HEX import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX +import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS1_HEX import prog8.compiler.target.c64.Petscii import prog8.functions.BuiltinFunctions import java.io.File @@ -495,7 +496,7 @@ internal class AsmGen2(val program: Program, is RepeatLoop -> TODO() is WhenStatement -> TODO() is BuiltinFunctionStatementPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore?") - is AnonymousScope -> throw AssemblyError("anonscope should have been flattened") + is AnonymousScope -> translate(stmt) is Block -> throw AssemblyError("block should have been handled elsewhere") } } @@ -615,6 +616,10 @@ internal class AsmGen2(val program: Program, out(stmt.name) } + private fun translate(scope: AnonymousScope) { + scope.statements.forEach { translate(it) } + } + private fun translate(stmt: BranchStatement) { if(stmt.truepart.containsNoCodeNorVars() && stmt.elsepart.containsCodeOrVars()) throw AssemblyError("only else part contains code, shoud have been switched already") @@ -624,8 +629,22 @@ internal class AsmGen2(val program: Program, // branch with only a jump val instruction = branchInstruction(stmt.condition, false) out(" $instruction ${getJumpTarget(jump)}") + translate(stmt.elsepart) } else { - TODO("branch $stmt") + if(stmt.elsepart.containsNoCodeNorVars()) { + val instruction = branchInstruction(stmt.condition, true) + out(" $instruction _prog8_branch_else") + translate(stmt.truepart) + out("_prog8_branch_else") + } else { + val instruction = branchInstruction(stmt.condition, false) + out(" $instruction _prog8_branch_true") + translate(stmt.elsepart) + out(" jmp _prog8_branch_end") + out("_prog8_branch_true") + translate(stmt.truepart) + out("_prog8_branch_end") + } } } @@ -654,7 +673,7 @@ internal class AsmGen2(val program: Program, } private fun translate(stmt: ForLoop) { - out("; TODO for $stmt") // TODO + out("; TODO forloop $stmt") // TODO } private fun translate(stmt: PostIncrDecr) { @@ -760,14 +779,7 @@ internal class AsmGen2(val program: Program, DataType.UBYTE, DataType.BYTE -> assignByteConstant(assign.target, numVal.number.toShort()) DataType.UWORD, DataType.WORD -> assignWordConstant(assign.target, numVal.number.toInt()) DataType.FLOAT -> assignFloatConstant(assign.target, numVal.number.toDouble()) - DataType.STR -> TODO() - DataType.STR_S -> TODO() - DataType.ARRAY_UB -> TODO() - DataType.ARRAY_B -> TODO() - DataType.ARRAY_UW -> TODO() - DataType.ARRAY_W -> TODO() - DataType.ARRAY_F -> TODO() - DataType.STRUCT -> TODO() + else -> throw AssemblyError("weird numval type") } } is RegisterExpr -> { @@ -779,14 +791,8 @@ internal class AsmGen2(val program: Program, DataType.UBYTE, DataType.BYTE -> assignByteVariable(assign.target, assign.value as IdentifierReference) DataType.UWORD, DataType.WORD -> assignWordVariable(assign.target, assign.value as IdentifierReference) DataType.FLOAT -> assignFloatVariable(assign.target, assign.value as IdentifierReference) - DataType.STR -> TODO() - DataType.STR_S -> TODO() - DataType.ARRAY_UB -> TODO() - DataType.ARRAY_B -> TODO() - DataType.ARRAY_UW -> TODO() - DataType.ARRAY_W -> TODO() - DataType.ARRAY_F -> TODO() - DataType.STRUCT -> TODO() + in StringDatatypes -> TODO("str assignment") + else -> throw AssemblyError("unsupported assignment target type $type") } } is AddressOf -> { @@ -806,7 +812,7 @@ internal class AsmGen2(val program: Program, } else -> { translateExpression(read.addressExpression) - out("; TODO read memory byte from result and put that in ${assign.target}") // TODO + TODO("; TODO read memory byte from result and put that in ${assign.target}") } } } @@ -989,7 +995,38 @@ internal class AsmGen2(val program: Program, private fun translateExpression(expr: PrefixExpression) { translateExpression(expr.expression) - out("; TODO evaluate prefix ${expr.operator}") // TODO + val type = expr.inferType(program) + when(expr.operator) { + "+" -> {} + "-" -> { + when(type) { + in ByteDatatypes -> out(" jsr prog8_lib.neg_b") + in WordDatatypes -> out(" jsr prog8_lib.neg_w") + DataType.FLOAT -> out(" jsr c64flt.neg_f") + else -> throw AssemblyError("weird type") + } + } + "~" -> { + when(type) { + in ByteDatatypes -> + out(""" + lda $ESTACK_LO_PLUS1_HEX,x + eor #255 + sta $ESTACK_LO_PLUS1_HEX,x + """) + in WordDatatypes -> out(" jsr prog8_lib.inv_word") + else -> throw AssemblyError("weird type") + } + } + "not" -> { + when(type) { + in ByteDatatypes -> out(" jsr prog8_lib.not_byte") + in WordDatatypes -> out(" jsr prog8_lib.not_word") + else -> throw AssemblyError("weird type") + } + } + else -> throw AssemblyError("invalid prefix operator ${expr.operator}") + } } private fun assignEvalResult(target: AssignTarget) { @@ -1150,6 +1187,22 @@ internal class AsmGen2(val program: Program, } } + private fun saveRegister(register: Register) { + when(register) { + Register.A -> out(" pha") + Register.X -> out(" txa | pha") + Register.Y -> out(" tya | pha") + } + } + + private fun restoreRegister(register: Register) { + when(register) { + Register.A -> out(" pla") + Register.X -> out(" pla | tax") + Register.Y -> out(" pla | tay") + } + } + private fun assignWordConstant(target: AssignTarget, word: Int) { if(target.identifier!=null) { val targetName = asmIdentifierName(target.identifier) @@ -1169,7 +1222,7 @@ internal class AsmGen2(val program: Program, """) } } else { - out("; TODO assign byte $word to $target") // TODO + out("; TODO assign word $word to $target") // TODO } } diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFolding.kt index 29746f75b..df4ff36a2 100644 --- a/compiler/src/prog8/optimizer/ConstantFolding.kt +++ b/compiler/src/prog8/optimizer/ConstantFolding.kt @@ -150,25 +150,6 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { } } - //TODO ??? -// val decl2 = super.visit(decl) as VarDecl -// if(decl2.isArray) { -// val refvalue = decl2.value as? ReferenceLiteralValue -// if(refvalue!=null) { -// if (refvalue.isArray && refvalue.type!=decl2.datatype) { -// // fix the datatype of -// println("DECL ${decl2.datatype} - ${refvalue.type} - $array") -// } -// } -// } - - if(decl.isArray) { - val refvalue = decl.value as? ReferenceLiteralValue - if(refvalue!=null) { - println("VISIT DECL ${decl.position} ${decl.datatype} -> ${refvalue.type}") - } - } - return super.visit(decl) } diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index 2f0fee16f..0a5b0f9ab 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -487,8 +487,10 @@ internal class StatementOptimizer(private val program: Program, private val opti throw AstException("augmented assignments should have been converted to normal assignments before this optimizer") if(assignment.target isSameAs assignment.value) { - optimizationsDone++ - return NopStatement.insteadOf(assignment) + if(assignment.target.isNotMemory(program.namespace)) { + optimizationsDone++ + return NopStatement.insteadOf(assignment) + } } val targetDt = assignment.target.inferType(program, assignment) val bexpr=assignment.value as? BinaryExpression