From 02d6b5b71c641ba24b34d7f316aba46de978f287 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Tue, 7 Aug 2018 21:37:25 +0200 Subject: [PATCH] 6502: Crank up the optimizations --- src/main/scala/millfork/Main.scala | 3 ++- .../scala/millfork/OptimizationPresets.scala | 6 +++++ .../mos/opt/AlwaysGoodOptimizations.scala | 2 +- .../scala/millfork/test/WordMathSuite.scala | 24 ++++++++++++++++++- .../test/emu/EmuOptimizedInlinedRun.scala | 9 ++++++- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/main/scala/millfork/Main.scala b/src/main/scala/millfork/Main.scala index 50b5e656..ca26feed 100644 --- a/src/main/scala/millfork/Main.scala +++ b/src/main/scala/millfork/Main.scala @@ -186,7 +186,8 @@ object Main { if (options.flag(CompilationFlag.DangerousOptimizations)) DangerousOptimizations.All else Nil ).flatten val goodCycle = List.fill(optLevel - 2)(OptimizationPresets.Good ++ goodExtras).flatten - goodCycle ++ OptimizationPresets.AssOpt ++ extras ++ goodCycle + val mainCycle = List.fill(optLevel - 1)(OptimizationPresets.AssOpt ++ extras).flatten + goodCycle ++ mainCycle ++ goodCycle } // compile diff --git a/src/main/scala/millfork/OptimizationPresets.scala b/src/main/scala/millfork/OptimizationPresets.scala index d60ac20d..c9c95283 100644 --- a/src/main/scala/millfork/OptimizationPresets.scala +++ b/src/main/scala/millfork/OptimizationPresets.scala @@ -114,6 +114,9 @@ object OptimizationPresets { AlwaysGoodOptimizations.PoinlessStoreBeforeStore, LaterOptimizations.PointlessLoadAfterStore, AlwaysGoodOptimizations.PoinlessLoadBeforeAnotherLoad, + AlwaysGoodOptimizations.UnconditionalJumpRemoval, + AlwaysGoodOptimizations.AlwaysTakenJumpRemoval, + AlwaysGoodOptimizations.UnusedLabelRemoval, LaterOptimizations.LoadingAfterShifting, AlwaysGoodOptimizations.PointlessAccumulatorShifting, @@ -147,6 +150,9 @@ object OptimizationPresets { AlwaysGoodOptimizations.IncrementingIndexRegistersAfterTransfer, AlwaysGoodOptimizations.MathOperationOnTwoIdenticalMemoryOperands, LaterOptimizations.UseZeropageAddressingMode, + AlwaysGoodOptimizations.UnconditionalJumpRemoval, + AlwaysGoodOptimizations.AlwaysTakenJumpRemoval, + AlwaysGoodOptimizations.UnusedLabelRemoval, LaterOptimizations.UseXInsteadOfStack, LaterOptimizations.UseYInsteadOfStack, diff --git a/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala b/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala index a8ef6dae..75da9f38 100644 --- a/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala +++ b/src/main/scala/millfork/assembly/mos/opt/AlwaysGoodOptimizations.scala @@ -680,7 +680,7 @@ object AlwaysGoodOptimizations { val UnconditionalJumpRemoval = new RuleBasedAssemblyOptimization("Unconditional jump removal", needsFlowInfo = FlowInfoRequirement.NoRequirement, - (Elidable & HasOpcode(JMP) & HasAddrMode(Absolute) & MatchParameter(0)) ~ + (Elidable & HasOpcode(JMP) & HasAddrModeIn(Absolute, Relative, LongAbsolute, LongRelative) & MatchParameter(0)) ~ (Elidable & LinearOrBranch).* ~ (HasOpcode(LABEL) & MatchParameter(0)) ~~> (code => List(code.last)), (Elidable & HasOpcode(BRA) & MatchParameter(0)) ~ diff --git a/src/test/scala/millfork/test/WordMathSuite.scala b/src/test/scala/millfork/test/WordMathSuite.scala index f436b45b..38eb4cea 100644 --- a/src/test/scala/millfork/test/WordMathSuite.scala +++ b/src/test/scala/millfork/test/WordMathSuite.scala @@ -102,9 +102,11 @@ class WordMathSuite extends FunSuite with Matchers { test("nesdev.com example") { EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(""" | byte output @$c000 + | byte tile @$C3A6 | array map [256] @$c300 | array b[2] | void main () { + | tile = 77 | output = get(5, 6) | } | byte get(byte mx, byte my) { @@ -114,7 +116,27 @@ class WordMathSuite extends FunSuite with Matchers { | p += map | return p[my] | } - """.stripMargin)(m => ()) + """.stripMargin) { m => + m.readByte(0xc3a6) should equal(77) + } + } + + test("nesdev.com example 2") { + EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(""" + | byte output @$c000 + | byte tile @$C3A6 + | array map [256] @$c300 + | array b[2] + | void main () { + | tile = 77 + | output = get(5, 6) + | } + | byte get(byte mx, byte my) { + | return map[((mx + 00000) << 5) + my] + | } + """.stripMargin){ m => + m.readByte(0xc3a6) should equal(77) + } } test("hi()/lo()") { diff --git a/src/test/scala/millfork/test/emu/EmuOptimizedInlinedRun.scala b/src/test/scala/millfork/test/emu/EmuOptimizedInlinedRun.scala index fb502b17..308fb10b 100644 --- a/src/test/scala/millfork/test/emu/EmuOptimizedInlinedRun.scala +++ b/src/test/scala/millfork/test/emu/EmuOptimizedInlinedRun.scala @@ -14,13 +14,20 @@ object EmuOptimizedInlinedRun extends EmuRun( ZeropageRegisterOptimizations.All ++ OptimizationPresets.Good ++ OptimizationPresets.Good ++ + OptimizationPresets.AssOpt ++ OptimizationPresets.Good ++ LaterOptimizations.Nmos ++ ZeropageRegisterOptimizations.All ++ + OptimizationPresets.AssOpt ++ OptimizationPresets.Good ++ LaterOptimizations.Nmos ++ ZeropageRegisterOptimizations.All ++ + OptimizationPresets.AssOpt ++ + OptimizationPresets.AssOpt ++ + OptimizationPresets.AssOpt ++ + OptimizationPresets.Good ++ + ZeropageRegisterOptimizations.All ++ OptimizationPresets.Good ++ ZeropageRegisterOptimizations.All ++ - OptimizationPresets.Good) { + OptimizationPresets.AssOpt) { override def inline: Boolean = true override def blastProcessing: Boolean = true }