diff --git a/src/main/scala/millfork/assembly/m6809/MLine.scala b/src/main/scala/millfork/assembly/m6809/MLine.scala index ea5eec99..a2b863b7 100644 --- a/src/main/scala/millfork/assembly/m6809/MLine.scala +++ b/src/main/scala/millfork/assembly/m6809/MLine.scala @@ -177,6 +177,7 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant case (EXG, TwoRegisters(r1, r2)) => overlaps(r1) || overlaps(r2) case (op, _) if MOpcode.ChangesAAlways(op) => overlaps(A) || addrMode.changesRegister(reg) case (op, _) if MOpcode.ChangesBAlways(op) => overlaps(B) || addrMode.changesRegister(reg) + case (LDA, _) => overlaps(A) || addrMode.changesRegister(reg) case (LDB, _) => overlaps(B) || addrMode.changesRegister(reg) case (LDD, _) => overlaps(D) || addrMode.changesRegister(reg) case (LDU | LEAU, _) => reg == U || addrMode.changesRegister(reg) diff --git a/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala b/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala index 0b153bf5..9489bce0 100644 --- a/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala +++ b/src/main/scala/millfork/assembly/m6809/opt/AlwaysGoodMOptimizations.scala @@ -4,6 +4,7 @@ package millfork.assembly.m6809.opt import millfork.assembly.AssemblyOptimization import millfork.assembly.m6809.MOpcode._ import millfork.assembly.m6809.{MLine, MState} +import millfork.node.M6809Register /** * @author Karol Stasiak @@ -27,6 +28,12 @@ object AlwaysGoodMOptimizations { (Elidable & HasOpcode(LDB) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.CF)) ~~> { _ => List(MLine.inherentB(CLR)) }, + (Elidable & HasOpcode(LDD) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.A, MState.CF)) ~~> { + _ => List(MLine.inherentB(CLR)) + }, + (Elidable & HasOpcode(LDD) & HasImmediate(0) & DoesntMatterWhatItDoesWith(MState.B, MState.CF)) ~~> { + _ => List(MLine.inherentA(CLR)) + }, (Elidable & HasOpcode(STA) & HasA(0) & DoesntMatterWhatItDoesWith(MState.CF)) ~~> { code => code.map(_.copy(opcode = CLR)) }, @@ -35,8 +42,21 @@ object AlwaysGoodMOptimizations { }, ) + val PointlessRegisterTransfers = new RuleBasedAssemblyOptimization("Pointless register transfers", + needsFlowInfo = FlowInfoRequirement.BackwardFlow, + (Elidable & IsTfr(M6809Register.D, M6809Register.X)) ~ + (Elidable & IsTfr(M6809Register.X, M6809Register.D)) ~~> (_.init), + (Elidable & IsTfr(M6809Register.A, M6809Register.B)) ~ + (Elidable & IsTfr(M6809Register.B, M6809Register.A)) ~~> (_.init), + (Elidable & IsTfrTo(M6809Register.B) & DoesntMatterWhatItDoesWith(MState.B)) ~~> (_ => Nil), + (Elidable & IsTfrTo(M6809Register.A) & DoesntMatterWhatItDoesWith(MState.A)) ~~> (_ => Nil), + (Elidable & IsTfrTo(M6809Register.D) & DoesntMatterWhatItDoesWith(MState.A, MState.B)) ~~> (_ => Nil), + (Elidable & IsTfrTo(M6809Register.X) & DoesntMatterWhatItDoesWith(MState.X)) ~~> (_ => Nil), + ) + val All: Seq[AssemblyOptimization[MLine]] = Seq( PointlessLoad, + PointlessRegisterTransfers, SimplifiableZeroStore ) } diff --git a/src/main/scala/millfork/assembly/m6809/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/m6809/opt/RuleBasedAssemblyOptimization.scala index 25eec99a..f455f82c 100644 --- a/src/main/scala/millfork/assembly/m6809/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/m6809/opt/RuleBasedAssemblyOptimization.scala @@ -1051,6 +1051,39 @@ case class HasAddrMode(am: MAddrMode) extends TrivialMLinePattern { override def hitRate: Double = 0.295 } +case class IsTfr(s: M6809Register.Value, t: M6809Register.Value) extends TrivialMLinePattern { + override def apply(line: MLine): Boolean = + line.opcode == MOpcode.TFR && line.addrMode == TwoRegisters(s, t) + + override def toString: String = s"(TFR $s,$t)" + + override def hitRate: Double = 0.006 +} + +case class IsTfrFrom(s: M6809Register.Value) extends TrivialMLinePattern { + override def apply(line: MLine): Boolean = + line.opcode == MOpcode.TFR && (line.addrMode match { + case TwoRegisters(s1, _) => s == s1 + case _ => false + }) + + override def toString: String = s"(TFR $s,_)" + + override def hitRate: Double = 0.006 +} + +case class IsTfrTo(t: M6809Register.Value) extends TrivialMLinePattern { + override def apply(line: MLine): Boolean = + line.opcode == MOpcode.TFR && (line.addrMode match { + case TwoRegisters(_, t1) => t == t1 + case _ => false + }) + + override def toString: String = s"(TFR _,$t)" + + override def hitRate: Double = 0.006 +} + case class HasAddrModeIn(ams: Set[MAddrMode]) extends TrivialMLinePattern { override def apply(line: MLine): Boolean = ams(line.addrMode)