1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-04-10 01:36:59 +00:00

Z80: Fix stack variable optimizations when addresses of stack variables are taken

This commit is contained in:
Karol Stasiak 2019-06-26 02:11:53 +02:00
parent a3b21c4810
commit afa871abcf
3 changed files with 43 additions and 2 deletions

View File

@ -241,6 +241,12 @@ object ByteVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
def unapply(c: Int): Option[Int] = if ("IY+" + c == vname) Some(c) else None
}
code match {
case (_, ZLine0(LD_16, TwoRegisters(_, SP), _)) :: _ if vname.contains("+") => None
case (_, ZLine0(LD_16, TwoRegisters(SP, _), _)) :: _ if vname.contains("+") => None
case (_, ZLine0(ADD_16 | SBC_16, TwoRegisters(_, SP), _)) :: _ if vname.contains("+") => None
case (_, ZLine0(LD_HLSP | LD_DESP, _, _)) :: _ if vname.contains("+") => None
case (_, ZLine0(EX_SP, _, _)) :: _ if vname.contains("+") => None
case (_, ZLine0(LD, TwoRegisters(A, MEM_ABS_8), ThisVar(_))) :: xs =>
canBeInlined(vname, synced, target, addressInHl, addressInBc, addressInDe, xs).map(add(CyclesAndBytes(9, 2)))
case (_, ZLine0(LD, TwoRegisters(MEM_ABS_8, A), ThisVar(_))) :: xs =>

View File

@ -58,12 +58,27 @@ object CompactStackFrame extends AssemblyOptimization[ZLine] {
def findUsedOffsets(code: List[ZLine], Mem: ZRegister.Value): Set[Int] = {
code.flatMap {
val used = code.flatMap {
case ZLine0(_, OneRegisterOffset(Mem, offset), _) => Some(offset)
case ZLine0(_, TwoRegistersOffset(_, Mem, offset), _) => Some(offset)
case ZLine0(_, TwoRegistersOffset(Mem, _, offset), _) => Some(offset)
case _ => None
}.toSet
import ZOpcode._
import ZRegister._
if (used.isEmpty){
used
} else if (code.exists {
case ZLine0(LD_16, TwoRegisters(_, SP), _) => true
case ZLine0(LD_16, TwoRegisters(SP, _), _) => true
case ZLine0(ADD_16 | SBC_16, TwoRegisters(_, SP), _) => true
case ZLine0(LD_HLSP | LD_DESP, _, _) => true
case ZLine0(EX_SP, _, _) => true
case _ => false
}){
(0 to used.max).toSet
} else used
}
def optimizeContinue(code: List[ZLine], Index: ZRegister.Value, sourceSize: Int, targetSize: Int, mapping: Map[Int, Int]): Option[List[ZLine]] = {

View File

@ -1,7 +1,7 @@
package millfork.test
import millfork.Cpu
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuSoftwareStackBenchmarkRun, EmuUnoptimizedCrossPlatformRun}
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuOptimizedZ80Run, EmuSoftwareStackBenchmarkRun, EmuUnoptimizedCrossPlatformRun}
import org.scalatest.{FunSuite, Matchers}
/**
@ -390,5 +390,25 @@ class StackVarSuite extends FunSuite with Matchers {
}
}
test("Pointers to stack variables 3") {
val m = EmuOptimizedZ80Run(
"""
| noinline byte f() = 6
| noinline void g(byte x) {}
| void main () {
| stack byte b
| stack byte a
| stack byte c
| b = b
| c = c
| a = f()
| a += 5
| a += a.addr.lo
| g(a)
| if f() == 0 { main() }
| }
""".stripMargin)
}
}