1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-12-25 06:29:17 +00:00

6502: Fix summing for-loops

This commit is contained in:
Karol Stasiak 2019-06-26 01:47:43 +02:00
parent 6cf746045f
commit 8304650b3e
2 changed files with 11 additions and 4 deletions

View File

@ -3,7 +3,7 @@ package millfork.compiler.mos
import millfork.CompilationFlag import millfork.CompilationFlag
import millfork.assembly.mos.{AddrMode, AssemblyLine, AssemblyLine0, Opcode} import millfork.assembly.mos.{AddrMode, AssemblyLine, AssemblyLine0, Opcode}
import millfork.compiler.{AbstractExpressionCompiler, BranchSpec, CompilationContext} import millfork.compiler.{AbstractExpressionCompiler, BranchSpec, CompilationContext}
import millfork.env.{Label, MemoryAddressConstant, NumericConstant, Type, Variable, VariableInMemory} import millfork.env.{Label, MemoryAddressConstant, MemoryVariable, NumericConstant, RelativeVariable, Type, Variable, VariableAllocationMethod, VariableInMemory}
import millfork.node._ import millfork.node._
import millfork.assembly.mos.Opcode._ import millfork.assembly.mos.Opcode._
@ -182,6 +182,13 @@ object MosBulkMemoryOperations {
import ForDirection._ import ForDirection._
val target = ctx.env.maybeGet[Variable](targetExpression.name).getOrElse(return None) val target = ctx.env.maybeGet[Variable](targetExpression.name).getOrElse(return None)
if (target.isVolatile) return None if (target.isVolatile) return None
val indexVariable = ctx.env.get[Variable](f.variable)
if (indexVariable.isVolatile || indexVariable.typ.size != 1) return None
indexVariable match {
case v: MemoryVariable =>
if (v.alloc == VariableAllocationMethod.Static) return None
case _ => return None
}
val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, source) val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, source)
if (sourceType.size != 1) return None if (sourceType.size != 1) return None
if (!sourceType.isArithmetic) return None if (!sourceType.isArithmetic) return None
@ -193,7 +200,6 @@ object MosBulkMemoryOperations {
if (!target.typ.isArithmetic) return None if (!target.typ.isArithmetic) return None
if (target.typ.size != 1) return None if (target.typ.size != 1) return None
} }
val indexVariable = ctx.env.get[Variable](f.variable)
val loadSource = MosExpressionCompiler.compileToA(ctx, source) match { val loadSource = MosExpressionCompiler.compileToA(ctx, source) match {
case List(AssemblyLine0(LDY, Absolute | ZeroPage, MemoryAddressConstant(index)), l@AssemblyLine0(LDA, AbsoluteY | IndexedY, _)) if index.name == indexVariable.name => l case List(AssemblyLine0(LDY, Absolute | ZeroPage, MemoryAddressConstant(index)), l@AssemblyLine0(LDA, AbsoluteY | IndexedY, _)) if index.name == indexVariable.name => l
case List(l@AssemblyLine0(LDA, Absolute | ZeroPage | Immediate, _)) => l case List(l@AssemblyLine0(LDA, Absolute | ZeroPage | Immediate, _)) => l

View File

@ -285,8 +285,9 @@ object MosStatementCompiler extends AbstractStatementCompiler[AssemblyLine] {
compileDoWhileStatement(ctx, s) compileDoWhileStatement(ctx, s)
case f@ForStatement(variable, _, _, _, List(Assignment(target: IndexedExpression, source: Expression))) if !source.containsVariable(variable) => case f@ForStatement(variable, _, _, _, List(Assignment(target: IndexedExpression, source: Expression))) if !source.containsVariable(variable) =>
MosBulkMemoryOperations.compileMemset(ctx, target, source, f) -> Nil MosBulkMemoryOperations.compileMemset(ctx, target, source, f) -> Nil
case f@ForStatement(variable, start, end, _, List(ExpressionStatement(FunctionCallExpression(operator@("+=" | "-=" | "+'=" | "-'=" | "|=" | "^=" | "&="), List(target: VariableExpression, source))))) case f@ForStatement(variable, start, end, _, List(ExpressionStatement(
if !target.containsVariable(variable) && !start.containsVariable(target.name) && !end.containsVariable(target.name) => FunctionCallExpression(operator@("+=" | "-=" | "+'=" | "-'=" | "|=" | "^=" | "&="), List(target: VariableExpression, source))
))) if !target.containsVariable(variable) && !source.containsVariable(variable) && !start.containsVariable(target.name) && !end.containsVariable(target.name) =>
MosBulkMemoryOperations.compileFold(ctx, target, operator, source, f) match { MosBulkMemoryOperations.compileFold(ctx, target, operator, source, f) match {
case Some(x) => x -> Nil case Some(x) => x -> Nil
case None => compileForStatement(ctx, f) case None => compileForStatement(ctx, f)