From 1fcbf9fd5b3a1972593a88d35a198a9b73c58def Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Wed, 28 Mar 2018 18:56:11 +0200 Subject: [PATCH] More uses for the DCP instruction --- .../opt/UndocumentedOptimizations.scala | 24 +++++++++++++++++-- .../scala/millfork/test/IllegalSuite.scala | 15 ++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala b/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala index cb3e568e..df135529 100644 --- a/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala +++ b/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala @@ -185,9 +185,9 @@ object UndocumentedOptimizations { } private def trivialSequence1(o1: Opcode.Value, o2: Opcode.Value, extra: AssemblyLinePattern, combined: Opcode.Value) = - (Elidable & HasOpcode(o1) & HasAddrMode(Absolute) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(o1) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchAddrMode(0) & MatchParameter(1)) ~ (Linear & DoesNotConcernMemoryAt(0, 1) & extra).* ~ - (Elidable & HasOpcode(o2) & HasAddrMode(Absolute) & MatchParameter(1)) ~~> { (code, ctx) => + (Elidable & HasOpcode(o2) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchParameter(1)) ~~> { (code, ctx) => code.tail.init :+ AssemblyLine(combined, Absolute, ctx.get[Constant](1)) } @@ -288,6 +288,26 @@ object UndocumentedOptimizations { (Elidable & HasOpcode(DEC) & HasAddrMode(AbsoluteX) & DoesntMatterWhatItDoesWith(State.A, State.Y, State.X, State.C, State.Z, State.N, State.V)) ~~> { code => List(code.head.copy(opcode = LDY), code.last.copy(opcode = DCP, addrMode = AbsoluteY)) }, + (Elidable & HasOpcode(DEC) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(LDA) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(CMP) & MatchAddrMode(2) & MatchParameter(3) & DoesntMatterWhatItDoesWith(State.C, State.N, State.A)) ~~> { code => + List(code(2).copy(opcode = LDA), code(1).copy(opcode = DCP)) + }, + (Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & HasAddrModeIn(Set(ZeroPage, Absolute))) ~ + (Elidable & HasOpcode(BNE) & MatchParameter(2)) ~ + (Elidable & HasOpcode(DEC) & MatchAddrMode(30) & MatchParameter(31) & DoesntChangeMemoryAt(0, 1)) ~ + (Elidable & HasOpcode(LABEL) & MatchParameter(2) & HasCallerCount(1)) ~ + (Elidable & HasOpcode(DEC) & HasAddrModeIn(Set(ZeroPage, Absolute)) & MatchParameter(1) & + DoesntChangeMemoryAt(30, 31) & + DoesntMatterWhatItDoesWith(State.Z, State.C, State.N, State.A)) ~~> { code => + List( + AssemblyLine.immediate(LDA, 0xff), + code.head.copy(opcode = DCP), + code(1), // BNE + code(2), // DEC ptr+1 + code(3) // LABEL + ) + }, ) val UseIsc = new RuleBasedAssemblyOptimization("Using undocumented instruction ISC", diff --git a/src/test/scala/millfork/test/IllegalSuite.scala b/src/test/scala/millfork/test/IllegalSuite.scala index df095e36..af743af2 100644 --- a/src/test/scala/millfork/test/IllegalSuite.scala +++ b/src/test/scala/millfork/test/IllegalSuite.scala @@ -101,6 +101,21 @@ class IllegalSuite extends FunSuite with Matchers { m.readByte(0xc000) should equal(28) } + + test("DCP test 2") { + val m = EmuUndocumentedRun(""" + | byte output @$c000 + | void main () { + | pointer p + | p = init() + | p -= 1 + | p[0] = 28 + | } + | noinline word init() { return output.addr + 1 } + """.stripMargin) + m.readByte(0xc000) should equal(28) + } + test("SLO test") { val m = EmuUndocumentedRun(""" | long output @$c000