From 0dc16e9af2470a36f4eb3dc8f6ccd10b30d23352 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Fri, 28 Dec 2018 11:38:52 +0100 Subject: [PATCH] 8080: Don't change BC/DE when not allowed to --- .../assembly/z80/opt/ChangeRegisterPair.scala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/scala/millfork/assembly/z80/opt/ChangeRegisterPair.scala b/src/main/scala/millfork/assembly/z80/opt/ChangeRegisterPair.scala index d892960b..26b19454 100644 --- a/src/main/scala/millfork/assembly/z80/opt/ChangeRegisterPair.scala +++ b/src/main/scala/millfork/assembly/z80/opt/ChangeRegisterPair.scala @@ -1,6 +1,6 @@ package millfork.assembly.z80.opt -import millfork.assembly.{AssemblyOptimization, OptimizationContext} +import millfork.assembly.{AssemblyOptimization, Elidability, OptimizationContext} import millfork.assembly.z80._ import millfork.env.{AssemblyParamSignature, NormalFunction, NormalParamSignature} import millfork.error.Logger @@ -48,11 +48,11 @@ class ChangeRegisterPair(preferBC2DE: Boolean) extends AssemblyOptimization[ZLin if (f.params.isInstanceOf[AssemblyParamSignature]) return code val usesBC = code.exists(l => (l.readsRegister(BC) || l.changesRegister(BC)) && l.opcode != CALL) val usesDE = code.exists(l => (l.readsRegister(DE) || l.changesRegister(DE)) && l.opcode != CALL) - val canDE2BC = f.returnType.size < 3 && canOptimize(code, DE2BC, Loaded()) && (f.params match { + val canDE2BC = f.returnType.size < 3 && canOptimize(code, DE2BC, Loaded()) && canOptimize2(code, DE2BC) && (f.params match { case NormalParamSignature(List(p)) => p.typ.size < 3 case _ => true }) - val canBC2DE = canOptimize(code, BC2DE, Loaded()) + val canBC2DE = canOptimize(code, BC2DE, Loaded()) && canOptimize2(code, BC2DE) implicit val log: Logger = optimizationContext.log (canDE2BC, canBC2DE) match { case (false, false) => code @@ -124,6 +124,16 @@ class ChangeRegisterPair(preferBC2DE: Boolean) extends AssemblyOptimization[ZLin case _ => true } + private def canOptimize2(code: List[ZLine], dir: PairDirection): Boolean = code match { + case ZLine0(CALL, _, _) :: xs => canOptimize2(xs, dir) + case x :: xs if dir == DE2BC && (x.readsRegister(DE) || x.changesRegister(DE)) => + (x.elidability == Elidability.Elidable || x.elidability == Elidability.Volatile) && canOptimize2(xs, dir) + case x :: xs if dir == BC2DE && (x.readsRegister(BC) || x.changesRegister(BC)) => + (x.elidability == Elidability.Elidable || x.elidability == Elidability.Volatile) && canOptimize2(xs, dir) + case x :: xs => canOptimize2(xs, dir) + case Nil => true + } + private def switchBC2DE(code: List[ZLine]): List[ZLine] = { code match { case (x@ZLine0(_, OneRegister(B), _)) :: xs =>