1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-11-01 05:05:32 +00:00

6502: Detect pointer variables that have to be in the zeropage more accurately

This commit is contained in:
Karol Stasiak 2020-03-19 20:00:28 +01:00
parent 85030d3147
commit 769f31717d
3 changed files with 44 additions and 6 deletions

View File

@ -1083,8 +1083,8 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
def collectPointies(stmts: Seq[Statement]): Set[String] = {
val pointies: mutable.Set[String] = new mutable.HashSet()
pointies ++= stmts.flatMap(_.getAllPointies)
pointies ++ getAliases.filterKeys(pointies).values
pointies ++= stmts.flatMap(_.getAllPointies)
pointies ++= getAliases.filterKeys(pointies).values
log.trace("Collected pointies: " + pointies)
pointies.toSet
}
@ -1133,7 +1133,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
} else {
new Environment(Some(this), name + "$", cpuFamily, options)
}
stmt.params.foreach(p => env.registerParameter(p, options))
stmt.params.foreach(p => env.registerParameter(p, options, pointies))
def params: ParamSignature = if (stmt.assembly) {
AssemblyParamSignature(stmt.params.map {
pd =>
@ -1423,14 +1423,14 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
}
}
def registerParameter(stmt: ParameterDeclaration, options: CompilationOptions): Unit = {
def registerParameter(stmt: ParameterDeclaration, options: CompilationOptions, pointies: Set[String]): Unit = {
val typ = get[Type](stmt.typ)
val b = get[Type]("byte")
val w = get[Type]("word")
val p = get[Type]("pointer")
stmt.assemblyParamPassingConvention match {
case ByVariable(name) =>
val zp = typ.isPointy // TODO
val zp = typ.isPointy || pointies(name) // TODO
val v = UninitializedMemoryVariable(prefix + name, typ, if (zp) VariableAllocationMethod.Zeropage else VariableAllocationMethod.Auto, None, defaultVariableAlignment(options, 2), isVolatile = false)
addThing(v, stmt.position)
registerAddressConstant(v, stmt.position, options, Some(typ))

View File

@ -612,6 +612,18 @@ case class FunctionDeclarationStatement(name: String,
override def getAllExpressions: List[Expression] = address.toList ++ statements.getOrElse(Nil).flatMap(_.getAllExpressions)
override def withChangedBank(bank: String): BankedDeclarationStatement = copy(bank = Some(bank))
override def getAllPointies: Seq[String] = statements match {
case None => Seq.empty
case Some(stmts) =>
val locals = stmts.flatMap{
case s:VariableDeclarationStatement => Some(s.name)
case s:ArrayDeclarationStatement => Some(s.name)
case _ => None
}.toSet
val pointies = stmts.flatMap(_.getAllPointies).toSet
(pointies -- locals).toSeq
}
}
sealed trait ExecutableStatement extends Statement

View File

@ -1,7 +1,7 @@
package millfork.test
import millfork.Cpu
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun, ShouldNotCompile}
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun, EmuUnoptimizedRun, ShouldNotCompile}
import org.scalatest.{AppendedClues, FunSuite, Matchers}
/**
@ -427,4 +427,30 @@ class PointerSuite extends FunSuite with Matchers with AppendedClues {
m.readWord(0xc100) should equal(0x400)
}
}
test("Pointers should remain at zero page if used as pointers in assembly") {
val m = EmuUnoptimizedRun(
"""
| word output @$c000
| pointer p
| volatile pointer q1
| volatile pointer q2
| volatile pointer q3
| volatile pointer q4
| volatile pointer q5
| volatile pointer q6
| volatile pointer q7
| volatile pointer q8
| array arr [250] @$0
| void main () {
| asm {
| lda (p),y
| }
| output = p.addr
| q1 = q2 + q3 + q4 + q5 + q6 + q7 + q8
| }
|""".stripMargin)
m.readWord(0xc000) should be <(256)
}
}