mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-23 23:30:22 +00:00
Multiple improvements:
- fixed some invalid LDX(zp),Y instructions - better error reporting - removing unused extern functions - a new testcase
This commit is contained in:
parent
775707801c
commit
5dc1bba8ed
@ -695,7 +695,7 @@ object ExpressionCompiler {
|
||||
case Register.A =>
|
||||
List(AssemblyLine.indexedY(LDA, reg))
|
||||
case Register.X =>
|
||||
List(AssemblyLine.indexedY(LDX, reg))
|
||||
List(AssemblyLine.indexedY(LDA, reg), AssemblyLine.implied(TAX))
|
||||
case Register.Y =>
|
||||
List(AssemblyLine.indexedY(LDA, reg), AssemblyLine.implied(TAY))
|
||||
}
|
||||
@ -716,7 +716,7 @@ object ExpressionCompiler {
|
||||
case Register.Y =>
|
||||
List(AssemblyLine.immediate(LDY, constantIndex), AssemblyLine.indexedY(LDA, p.addr), AssemblyLine.implied(TAY))
|
||||
case Register.X =>
|
||||
List(AssemblyLine.immediate(LDY, constantIndex), AssemblyLine.indexedY(LDX, p.addr))
|
||||
List(AssemblyLine.immediate(LDY, constantIndex), AssemblyLine.indexedY(LDA, p.addr), AssemblyLine.implied(TAX))
|
||||
}
|
||||
case (p:VariablePointy, Some(_), 0 | 1, _) =>
|
||||
val calculatingIndex = compile(ctx, indexExpr, Some(b, RegisterVariable(Register.Y, b)), NoBranching)
|
||||
@ -724,7 +724,7 @@ object ExpressionCompiler {
|
||||
case Register.A =>
|
||||
calculatingIndex :+ AssemblyLine.indexedY(LDA, p.addr)
|
||||
case Register.X =>
|
||||
calculatingIndex :+ AssemblyLine.indexedY(LDX, p.addr)
|
||||
calculatingIndex ++ List(AssemblyLine.indexedY(LDA, p.addr), AssemblyLine.implied(TAX))
|
||||
case Register.Y =>
|
||||
calculatingIndex ++ List(AssemblyLine.indexedY(LDA, p.addr), AssemblyLine.implied(TAY))
|
||||
}
|
||||
@ -1270,7 +1270,7 @@ object ExpressionCompiler {
|
||||
|
||||
def expressionStorageFromAX(ctx: CompilationContext, exprTypeAndVariable: Option[(Type, Variable)], position: Option[Position]): List[AssemblyLine] = {
|
||||
exprTypeAndVariable.fold(noop) {
|
||||
case (VoidType, _) => ???
|
||||
case (VoidType, _) => ErrorReporting.fatal("Cannot assign word to void", position)
|
||||
case (_, RegisterVariable(Register.A, _)) => noop
|
||||
case (_, RegisterVariable(Register.AW, _)) => List(AssemblyLine.implied(XBA), AssemblyLine.implied(TXA), AssemblyLine.implied(XBA))
|
||||
case (_, RegisterVariable(Register.X, _)) => List(AssemblyLine.implied(TAX))
|
||||
@ -1421,7 +1421,7 @@ object ExpressionCompiler {
|
||||
def lookupFunction(ctx: CompilationContext, f: FunctionCallExpression): MangledFunction = {
|
||||
val paramsWithTypes = f.expressions.map(x => getExpressionType(ctx, x) -> x)
|
||||
ctx.env.lookupFunction(f.functionName, paramsWithTypes).getOrElse(
|
||||
ErrorReporting.fatal(s"Cannot find function `${f.functionName}` with given params `${paramsWithTypes.map(_._1)}`", f.position))
|
||||
ErrorReporting.fatal(s"Cannot find function `${f.functionName}` with given params `${paramsWithTypes.map(_._1).mkString("(", ",", ")")}`", f.position))
|
||||
}
|
||||
|
||||
def arrayBoundsCheck(ctx: CompilationContext, pointy: Pointy, register: Register.Value, index: Expression): List[AssemblyLine] = {
|
||||
|
@ -13,7 +13,7 @@ object UnusedFunctions extends NodeOptimization {
|
||||
override def optimize(nodes: List[Node], options: CompilationOptions): List[Node] = {
|
||||
val panicRequired = options.flags(CompilationFlag.CheckIndexOutOfBounds)
|
||||
val allNormalFunctions = nodes.flatMap {
|
||||
case v: FunctionDeclarationStatement => if (v.address.isDefined || v.interrupt || v.name == "main" || panicRequired && v.name == "_panic") Nil else List(v.name)
|
||||
case v: FunctionDeclarationStatement => if (v.address.isDefined && v.statements.isDefined || v.interrupt || v.name == "main" || panicRequired && v.name == "_panic") Nil else List(v.name)
|
||||
case _ => Nil
|
||||
}.toSet
|
||||
val allCalledFunctions = getAllCalledFunctions(nodes).toSet
|
||||
|
@ -15,7 +15,7 @@ class TextCodec(val name: String, private val map: String, private val extra: Ma
|
||||
if (index >= 0) {
|
||||
List(index)
|
||||
} else {
|
||||
ErrorReporting.fatal("Invalid character in string")
|
||||
ErrorReporting.fatal("Invalid character in string", position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,26 @@ class ByteMathSuite extends FunSuite with Matchers {
|
||||
""".stripMargin)(_.readByte(0xc001) should equal(42))
|
||||
}
|
||||
|
||||
test("LHS evaluation during in-place byte addition") {
|
||||
EmuBenchmarkRun(
|
||||
"""
|
||||
| array output[1] @$c000
|
||||
| byte call_count @$c001
|
||||
| void main () {
|
||||
| output[0] = 1
|
||||
| output[identity(0)] += identity(1)
|
||||
| }
|
||||
| noinline byte identity(byte a) {
|
||||
| call_count += 1
|
||||
| return a
|
||||
| }
|
||||
""".stripMargin){m =>
|
||||
m.readByte(0xc000) should equal(2)
|
||||
// TODO: currently the compiler emits separate evaluations of the left hand side for reading and writing
|
||||
// m.readByte(0xc001) should equal(2)
|
||||
}
|
||||
}
|
||||
|
||||
test("Parameter order") {
|
||||
EmuBenchmarkRun(
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user