From 98585fcc382d651df7335769f4d884c7b701b593 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Wed, 19 Dec 2018 22:29:49 +0100 Subject: [PATCH] 8080: better handling of separate byte pairs --- .../compiler/z80/Z80ExpressionCompiler.scala | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala index fafdc2e2..b0a9a0f0 100644 --- a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala @@ -451,21 +451,60 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] { val hi = compileToA(ctx, h) val lo = compileToA(ctx, l) - def xxx(hr: ZRegister.Value, lr: ZRegister.Value): List[ZLine] = { + def xxx(hr: ZRegister.Value, lr: ZRegister.Value, allowRedirect: Boolean = false): List[ZLine] = { if (!lo.exists(x => x.changesRegister(hr) || x.readsRegister(hr))) { hi ++ List(ZLine.ld8(hr, ZRegister.A)) ++ lo ++ List(ZLine.ld8(lr, ZRegister.A)) } else if (!hi.exists(x => x.changesRegister(lr) || x.readsRegister(lr))) { lo ++ List(ZLine.ld8(lr, ZRegister.A)) ++ hi ++ List(ZLine.ld8(hr, ZRegister.A)) - } else ??? + } else if (allowRedirect) { + hr match { + case ZRegister.H => + val viaDe = xxx(ZRegister.D, ZRegister.E) + if (viaDe.nonEmpty) { + viaDe ++ List(ZLine.ld8(ZRegister.L, ZRegister.E), ZLine.ld8(ZRegister.H, ZRegister.D)) + } else { + val viaBc = xxx(ZRegister.B, ZRegister.C) + if (viaBc.nonEmpty) { + viaBc ++ List(ZLine.ld8(ZRegister.L, ZRegister.C), ZLine.ld8(ZRegister.H, ZRegister.B)) + } else { + ??? + } + } + case ZRegister.B => + val viaHl = xxx(ZRegister.H, ZRegister.L) + if (viaHl.nonEmpty) { + viaHl ++ List(ZLine.ld8(ZRegister.C, ZRegister.L), ZLine.ld8(ZRegister.B, ZRegister.H)) + } else { + val viaDe = xxx(ZRegister.D, ZRegister.E) + if (viaDe.nonEmpty) { + viaDe ++ List(ZLine.ld8(ZRegister.C, ZRegister.E), ZLine.ld8(ZRegister.B, ZRegister.D)) + } else { + ??? + } + } + case ZRegister.D => + val viaHl = xxx(ZRegister.H, ZRegister.L) + if (viaHl.nonEmpty) { + viaHl ++ List(ZLine.ld8(ZRegister.E, ZRegister.L), ZLine.ld8(ZRegister.D, ZRegister.H)) + } else { + val viaBc = xxx(ZRegister.B, ZRegister.C) + if (viaBc.nonEmpty) { + viaBc ++ List(ZLine.ld8(ZRegister.E, ZRegister.C), ZLine.ld8(ZRegister.D, ZRegister.B)) + } else { + ??? + } + } + } + } else Nil } target match { case ZExpressionTarget.NOTHING => hi ++ lo - case ZExpressionTarget.HL => xxx(ZRegister.H, ZRegister.L) - case ZExpressionTarget.DE => xxx(ZRegister.D, ZRegister.E) - case ZExpressionTarget.BC => xxx(ZRegister.B, ZRegister.C) + case ZExpressionTarget.HL => xxx(ZRegister.H, ZRegister.L, allowRedirect = true) + case ZExpressionTarget.DE => xxx(ZRegister.D, ZRegister.E, allowRedirect = true) + case ZExpressionTarget.BC => xxx(ZRegister.B, ZRegister.C, allowRedirect = true) } case f@FunctionCallExpression(name, params) => name match {