some more asmgen v2, and seemingly useless assignments to memory variables are no longer optimized away

This commit is contained in:
Irmen de Jong 2019-07-27 03:11:15 +02:00
parent f94e241fb2
commit 1c411897df
3 changed files with 79 additions and 43 deletions

View File

@ -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_HEX
import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_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_HEX
import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_PLUS1_HEX
import prog8.compiler.target.c64.Petscii import prog8.compiler.target.c64.Petscii
import prog8.functions.BuiltinFunctions import prog8.functions.BuiltinFunctions
import java.io.File import java.io.File
@ -495,7 +496,7 @@ internal class AsmGen2(val program: Program,
is RepeatLoop -> TODO() is RepeatLoop -> TODO()
is WhenStatement -> TODO() is WhenStatement -> TODO()
is BuiltinFunctionStatementPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore?") 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") is Block -> throw AssemblyError("block should have been handled elsewhere")
} }
} }
@ -615,6 +616,10 @@ internal class AsmGen2(val program: Program,
out(stmt.name) out(stmt.name)
} }
private fun translate(scope: AnonymousScope) {
scope.statements.forEach { translate(it) }
}
private fun translate(stmt: BranchStatement) { private fun translate(stmt: BranchStatement) {
if(stmt.truepart.containsNoCodeNorVars() && stmt.elsepart.containsCodeOrVars()) if(stmt.truepart.containsNoCodeNorVars() && stmt.elsepart.containsCodeOrVars())
throw AssemblyError("only else part contains code, shoud have been switched already") 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 // branch with only a jump
val instruction = branchInstruction(stmt.condition, false) val instruction = branchInstruction(stmt.condition, false)
out(" $instruction ${getJumpTarget(jump)}") out(" $instruction ${getJumpTarget(jump)}")
translate(stmt.elsepart)
} else { } 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) { private fun translate(stmt: ForLoop) {
out("; TODO for $stmt") // TODO out("; TODO forloop $stmt") // TODO
} }
private fun translate(stmt: PostIncrDecr) { 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.UBYTE, DataType.BYTE -> assignByteConstant(assign.target, numVal.number.toShort())
DataType.UWORD, DataType.WORD -> assignWordConstant(assign.target, numVal.number.toInt()) DataType.UWORD, DataType.WORD -> assignWordConstant(assign.target, numVal.number.toInt())
DataType.FLOAT -> assignFloatConstant(assign.target, numVal.number.toDouble()) DataType.FLOAT -> assignFloatConstant(assign.target, numVal.number.toDouble())
DataType.STR -> TODO() else -> throw AssemblyError("weird numval type")
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()
} }
} }
is RegisterExpr -> { is RegisterExpr -> {
@ -779,14 +791,8 @@ internal class AsmGen2(val program: Program,
DataType.UBYTE, DataType.BYTE -> assignByteVariable(assign.target, assign.value as IdentifierReference) DataType.UBYTE, DataType.BYTE -> assignByteVariable(assign.target, assign.value as IdentifierReference)
DataType.UWORD, DataType.WORD -> assignWordVariable(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.FLOAT -> assignFloatVariable(assign.target, assign.value as IdentifierReference)
DataType.STR -> TODO() in StringDatatypes -> TODO("str assignment")
DataType.STR_S -> TODO() else -> throw AssemblyError("unsupported assignment target type $type")
DataType.ARRAY_UB -> TODO()
DataType.ARRAY_B -> TODO()
DataType.ARRAY_UW -> TODO()
DataType.ARRAY_W -> TODO()
DataType.ARRAY_F -> TODO()
DataType.STRUCT -> TODO()
} }
} }
is AddressOf -> { is AddressOf -> {
@ -806,7 +812,7 @@ internal class AsmGen2(val program: Program,
} }
else -> { else -> {
translateExpression(read.addressExpression) 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) { private fun translateExpression(expr: PrefixExpression) {
translateExpression(expr.expression) 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) { 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) { private fun assignWordConstant(target: AssignTarget, word: Int) {
if(target.identifier!=null) { if(target.identifier!=null) {
val targetName = asmIdentifierName(target.identifier) val targetName = asmIdentifierName(target.identifier)
@ -1169,7 +1222,7 @@ internal class AsmGen2(val program: Program,
""") """)
} }
} else { } else {
out("; TODO assign byte $word to $target") // TODO out("; TODO assign word $word to $target") // TODO
} }
} }

View File

@ -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) return super.visit(decl)
} }

View File

@ -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") throw AstException("augmented assignments should have been converted to normal assignments before this optimizer")
if(assignment.target isSameAs assignment.value) { if(assignment.target isSameAs assignment.value) {
optimizationsDone++ if(assignment.target.isNotMemory(program.namespace)) {
return NopStatement.insteadOf(assignment) optimizationsDone++
return NopStatement.insteadOf(assignment)
}
} }
val targetDt = assignment.target.inferType(program, assignment) val targetDt = assignment.target.inferType(program, assignment)
val bexpr=assignment.value as? BinaryExpression val bexpr=assignment.value as? BinaryExpression