From 769453418c826e375365feb714f3fc0b41bb434b Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Sun, 1 Dec 2019 03:38:19 +0100 Subject: [PATCH] 8080: Optimization bugfix --- .../z80/opt/AlwaysGoodI80Optimizations.scala | 32 +++++++++---------- .../opt/RuleBasedAssemblyOptimization.scala | 3 ++ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala index a8e10949..afffa336 100644 --- a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala +++ b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala @@ -231,7 +231,7 @@ object AlwaysGoodI80Optimizations { for7Registers(register => (Elidable & Is8BitLoad(register, register)) ~~> (_ => Nil) ), - // 42-48 + // 42-47 for6Registers(register => (Elidable & Is8BitLoadTo(register) & MatchSourceRegisterAndOffset(0) & MatchParameterOrNothing(1)) ~ (Linear & Not(Concerns(register)) & DoesntChangeMatchedRegisterAndOffset(0)).* ~ @@ -241,7 +241,7 @@ object AlwaysGoodI80Optimizations { } ), - // 49-54 + // 48-51 MultipleAssemblyRules { import ZRegister._ val regs = Seq((BC, B, C), (DE, D, E), (HL, H, L)) @@ -261,34 +261,34 @@ object AlwaysGoodI80Optimizations { } } }, - // 55-59 + // 52-56 for5LargeRegisters(register => (Is16BitLoad(register, ZRegister.MEM_ABS_16) & MatchParameter(0)).captureLine(1) ~ (Linear & Not(Changes(register)) & DoesntChangeMemoryAt(1)).* ~ (Elidable & Is16BitLoad(register, ZRegister.MEM_ABS_16) & MatchParameter(0)) ~~> (_.init) ), - // 60 + // 57 (HasOpcode(LD) & MatchSourceRegisterAndOffset(0) & MatchTargetRegisterAndOffset(1)) ~ Where(ctx => ctx.get[RegisterAndOffset](0).register != ZRegister.MEM_ABS_8 && ctx.get[RegisterAndOffset](1).register != ZRegister.MEM_ABS_8) ~ (Elidable & HasOpcode(LD) & MatchSourceRegisterAndOffset(1) & MatchTargetRegisterAndOffset(0)) ~~> (_.init), - // 61: + // 58: (Elidable & HasOpcode(EX_DE_HL)) ~ (Elidable & Is8BitLoad(H, D)) ~ (Elidable & Is8BitLoad(L, E) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> (_ => Nil), - // 62: + // 59: (Elidable & HasOpcode(EX_DE_HL)) ~ (Elidable & Is8BitLoad(L, E)) ~ (Elidable & Is8BitLoad(H, D) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> (_ => Nil), - // 63: + // 60: (Elidable & HasOpcode(EX_DE_HL)) ~ (Elidable & Is8BitLoad(E, L)) ~ (Elidable & Is8BitLoad(D, H) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (_ => Nil), - // 64: + // 61: (Elidable & HasOpcode(EX_DE_HL)) ~ (Elidable & Is8BitLoad(D, H)) ~ (Elidable & Is8BitLoad(E, L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (_ => Nil), - // 65: + // 62: ((Is8BitLoad(D, H)) ~ (Is8BitLoad(E, L)) ~ (Linear & Not(Changes(HL)) & Not(Changes(DE))).* ~ @@ -298,7 +298,7 @@ object AlwaysGoodI80Optimizations { (Elidable & Is8BitLoad(L, E)) ~~> { (_, ctx) => ctx.get[List[ZLine]](2) :+ ZLine.register(DEC_16, HL) }, - // 66: + // 63: ((Is8BitLoad(B, H)) ~ (Is8BitLoad(C, L)) ~ (Linear & Not(Changes(HL)) & Not(Changes(BC))).* ~ @@ -309,29 +309,29 @@ object AlwaysGoodI80Optimizations { ctx.get[List[ZLine]](2) :+ ZLine.register(DEC_16, HL) }, - // 67 + // 64 (HasOpcode(LD) & MatchSourceRealRegister(0) & MatchTargetRealRegister(1)) ~ (Linear & Not(ChangesMatchedRegister(0)) & Not(ChangesMatchedRegister(1))).* ~ (Elidable & HasOpcode(LD) & MatchSourceRealRegister(1) & MatchTargetRealRegister(0)) ~~> (_.init), - // 68 + // 65 (Elidable & HasOpcode(LD) & Match8BitImmediate(1) & MatchTargetRegisterAndOffset(2)) ~ Where(ctx => ctx.get[RegisterAndOffset](2).isOneOfSeven) ~ (Elidable & HasOpcode(LD) & MatchSourceRegisterAndOffset(2) & MatchTargetRealRegister(3) & DoesntMatterWhatItDoesWithMatchedRegisterOffset(2)) ~~> {(code, ctx) => List(code.head.copy(registers = TwoRegisters(ctx.get[ZRegister.Value](3), IMM_8))) }, - //69 + // 66 (HasOpcode(LD) & MatchSourceRealRegister(2) & MatchTargetRealRegister(3)) ~ (Elidable & HasOpcode(LD) & MatchSourceRealRegister(3) & MatchTargetRealRegister(2)) ~~> (_.init), - // 70 + // 67 (HasOpcode(CP) & Match8BitImmediate(1)) ~ (HasOpcodeIn(Set(JP, JR, RET)) & HasRegisters(IfFlagClear(ZFlag.Z))) ~ (Elidable & HasOpcode(LD) & HasTargetRegister(A) & Match8BitImmediate(1)) ~~> (_.init), - // 71 - (HasOpcode(CP) & MatchSoleRegisterAndOffset(1)) ~ + // 68 + (HasOpcode(CP) & MatchSoleRegisterAndOffset(1) & Not(Match8BitImmediate(2))) ~ (HasOpcodeIn(Set(JP, JR, RET)) & HasRegisters(IfFlagClear(ZFlag.Z))) ~ (Elidable & HasOpcode(LD) & HasTargetRegister(A) & MatchSourceRegisterAndOffset(1)) ~~> (_.init), ) diff --git a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala index ab699bac..09b4fd8b 100644 --- a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala @@ -1235,6 +1235,7 @@ case class HasOpcodeIn(ops: Set[ZOpcode.Value]) extends TrivialAssemblyLinePatte case class Has8BitImmediate(i: Int) extends TrivialAssemblyLinePattern { override def apply(line: ZLine): Boolean = (line.registers match { case TwoRegisters(_, ZRegister.IMM_8) => true + case TwoRegistersOffset(_, ZRegister.IMM_8, _) => true case OneRegister(ZRegister.IMM_8) => true case _ => false }) && (line.parameter.quickSimplify match { @@ -1252,6 +1253,7 @@ case class Match8BitImmediate(i: Int) extends AssemblyLinePattern { override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = line.registers match { case TwoRegisters(_, ZRegister.IMM_8) => ctx.addObject(i, line.parameter) + case TwoRegistersOffset(_, ZRegister.IMM_8, _) => ctx.addObject(i, line.parameter) case OneRegister(ZRegister.IMM_8) => ctx.addObject(i, line.parameter) case _ => false } @@ -1263,6 +1265,7 @@ case class HasImmediateWhere(predicate: Int => Boolean) extends TrivialAssemblyL override def apply(line: ZLine): Boolean = (line.registers match { case TwoRegisters(_, ZRegister.IMM_8) => true + case TwoRegistersOffset(_, ZRegister.IMM_8, _) => true case OneRegister(ZRegister.IMM_8) => true case _ => false }) && (line.parameter.quickSimplify match {