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:
parent
a3b21c4810
commit
afa871abcf
@ -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 =>
|
||||
|
@ -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]] = {
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user