From fbd9fddf448812971ffad7a76a882da409717ccc Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Fri, 16 Mar 2018 19:03:50 +0100 Subject: [PATCH] Few optimization improvements and fixes --- .../assembly/opt/AlwaysGoodOptimizations.scala | 12 ++++++++++++ .../millfork/assembly/opt/ReverseFlowAnalyzer.scala | 10 +++++----- .../assembly/opt/UndocumentedOptimizations.scala | 12 ++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/scala/millfork/assembly/opt/AlwaysGoodOptimizations.scala b/src/main/scala/millfork/assembly/opt/AlwaysGoodOptimizations.scala index 469cc98f..57110934 100644 --- a/src/main/scala/millfork/assembly/opt/AlwaysGoodOptimizations.scala +++ b/src/main/scala/millfork/assembly/opt/AlwaysGoodOptimizations.scala @@ -1174,6 +1174,18 @@ object AlwaysGoodOptimizations { (Elidable & HasOpcode(TAY) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { code => List(AssemblyLine.implied(INY)) }, + (Elidable & HasOpcode(ADC) & HasImmediate(0) & HasA(0) & DoesntMatterWhatItDoesWith(State.V)) ~~> (_ => List(AssemblyLine.implied(ROL))), + (Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(CLC)).? ~ + (Elidable & HasOpcode(ADC) & MatchAddrMode(0) & MatchParameter(1) & HasClear(State.C) & HasClear(State.D) & DoesntMatterWhatItDoesWith(State.V)) ~~> { code => + List(code.head, AssemblyLine.implied(ASL)) + }, + (Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(ADC) & MatchAddrMode(0) & MatchParameter(1) & HasClear(State.D) & DoesntMatterWhatItDoesWith(State.V)) ~~> { code => + List(code.head, AssemblyLine.implied(ROL)) + }, + (Elidable & HasOpcode(ROL) & HasClear(State.C)) ~~> (code => code.map(_.copy(opcode = ASL))), + (Elidable & HasOpcode(ROR) & HasClear(State.C)) ~~> (code => code.map(_.copy(opcode = LSR))), ) val IndexSequenceOptimization = new RuleBasedAssemblyOptimization("Index sequence optimization", diff --git a/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzer.scala index a0619c5b..80d97fe5 100644 --- a/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzer.scala @@ -155,6 +155,11 @@ object ReverseFlowAnalyzer { } currentImportance = result + case AssemblyLine(ANC, _, NumericConstant(0, _), _) => + currentImportance = currentImportance.copy(c = Unimportant, n = Unimportant, z = Unimportant, a = Unimportant) + case AssemblyLine(AND, _, NumericConstant(0, _), _) => + currentImportance = currentImportance.copy(n = Unimportant, z = Unimportant, a = Unimportant) + case AssemblyLine(opcode, addrMode, _, _) if ReverseFlowAnalyzerPerOpcode.hasDefinition(opcode) => currentImportance = ReverseFlowAnalyzerPerOpcode.get(opcode)(currentImportance) if (addrMode == AbsoluteX || addrMode == LongAbsoluteX || addrMode == IndexedX || addrMode == ZeroPageX || addrMode == AbsoluteIndexedX) @@ -184,11 +189,6 @@ object ReverseFlowAnalyzer { if ((n & 0x40) != 0) currentImportance = currentImportance.copy(v = Unimportant) if ((n & 0x80) != 0) currentImportance = currentImportance.copy(n = Unimportant) - case AssemblyLine(ANC, _, NumericConstant(0, _), _) => - currentImportance = currentImportance.copy(c = Unimportant, n = Unimportant, z = Unimportant, a = Unimportant) - case AssemblyLine(AND, _, NumericConstant(0, _), _) => - currentImportance = currentImportance.copy(n = Unimportant, z = Unimportant, a = Unimportant) - case AssemblyLine(opcode, addrMode, _, _) => val reallyIgnoreC = currentImportance.c == Unimportant && diff --git a/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala b/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala index a4ce1e0c..cb3e568e 100644 --- a/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala +++ b/src/main/scala/millfork/assembly/opt/UndocumentedOptimizations.scala @@ -107,15 +107,15 @@ object UndocumentedOptimizations { Where(c => andConstant(c.get[Constant](0), 0x80).contains(0x80)) ~ (Elidable & HasOpcode(SEC)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), (Elidable & HasOpcode(AND) & MatchImmediate(0)) ~ - (Elidable & HasOpcode(CMP) & HasImmediate(0x80) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Int](0)))), + (Elidable & HasOpcode(CMP) & HasImmediate(0x80) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), (Elidable & HasOpcode(AND) & MatchImmediate(0)) ~ - (Elidable & HasOpcode(CMP) & HasImmediate(0x80) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Int](0)))), + (Elidable & HasOpcode(CMP) & HasImmediate(0x80) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), (Elidable & HasOpcode(AND) & MatchImmediate(0) & HasClear(State.C)) ~ - Where(c => andConstant(c.get[Constant](0), 0x80).contains(0)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Int](0)))), + Where(c => andConstant(c.get[Constant](0), 0x80).contains(0)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), (Elidable & HasOpcode(AND) & MatchImmediate(0) & HasSet(State.C)) ~ - Where(c => andConstant(c.get[Constant](0), 0x80).contains(0)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Int](0)))), + Where(c => andConstant(c.get[Constant](0), 0x80).contains(0)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), (Elidable & HasOpcode(AND) & MatchImmediate(0)) ~ - (Elidable & HasOpcodeIn(Set(ROL, ASL)) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.Z, State.N, State.A)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Int](0)))), + (Elidable & HasOpcodeIn(Set(ROL, ASL)) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.Z, State.N, State.A)) ~~> ((_, ctx) => List(AssemblyLine.immediate(ANC, ctx.get[Constant](0)))), ) val UseSbx = new RuleBasedAssemblyOptimization("Using undocumented instruction SBX", @@ -294,7 +294,7 @@ object UndocumentedOptimizations { needsFlowInfo = FlowInfoRequirement.BothFlows, trivialSequence1(INC, SBC, Not(ReadsC), ISC), trivialSequence2(INC, SBC, Not(ReadsC), ISC), - (Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(IndexedY, AbsoluteY, IndexedY)) & MatchAddrMode(0) & MatchParameter(1)) ~ + (Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(IndexedY, AbsoluteY, IndexedX)) & MatchAddrMode(0) & MatchParameter(1)) ~ (Elidable & HasOpcode(CLC)).? ~ (Elidable & HasOpcode(ADC) & HasImmediate(1) & HasClear(State.C) & HasClear(State.D)).? ~ (Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.A, State.N, State.Z, State.C, State.V)) ~~> { (code, ctx) =>