mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-10 16:39:59 +00:00
Optimization improvements and fixes
This commit is contained in:
parent
fae7bb31c9
commit
a671ac1d06
@ -131,6 +131,7 @@ object OptimizationPresets {
|
||||
LaterOptimizations.IncreaseWithLimit,
|
||||
SingleAssignmentVariableOptimization,
|
||||
LocalVariableReadOptimization,
|
||||
LaterOptimizations.UseBit,
|
||||
)
|
||||
|
||||
val Good: List[AssemblyOptimization] = List[AssemblyOptimization](
|
||||
|
@ -123,6 +123,10 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasA(0xff) & HasOpcode(AND)) ~~> (code => code.map(_.copy(opcode = LDA))),
|
||||
(Elidable & HasA(0) & HasOpcode(AND)) ~~> (code => List(AssemblyLine.immediate(LDA, 0))),
|
||||
(Elidable & HasX(0) & HasOpcode(XAA)) ~~> (code => List(AssemblyLine.immediate(LDA, 0))),
|
||||
(Elidable & HasImmediate(0) & HasOpcode(AND)) ~~> (code => List(AssemblyLine.immediate(LDA, 0))),
|
||||
(Elidable & HasImmediate(0) & HasOpcode(XAA)) ~~> (code => List(AssemblyLine.immediate(LDA, 0))),
|
||||
(Elidable & HasImmediate(0xff) & HasOpcode(ORA)) ~~> (code => List(AssemblyLine.immediate(LDA, 0xff))),
|
||||
(Elidable & HasImmediate(0xff) & HasOpcode(EOR)) ~~> (code => List(AssemblyLine.immediate(LDA, 0xff))),
|
||||
)
|
||||
|
||||
val MathOperationOnTwoIdenticalMemoryOperands = new RuleBasedAssemblyOptimization("Math operation on two identical memory operands",
|
||||
@ -171,7 +175,7 @@ object AlwaysGoodOptimizations {
|
||||
(Linear & DoesntChangeIndexingInAddrMode(0) & DoesntChangeIndexingInAddrMode(2) &
|
||||
DoesNotConcernMemoryAt(0, 1) & DoesntChangeMemoryAt(2, 3)).* ~
|
||||
(Elidable & HasOpcode(ld2) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(st2) & MatchAddrMode(2) & MatchParameter(3)) ~~> (code => code.init),
|
||||
(Elidable & HasOpcode(st2) & MatchAddrMode(2) & MatchParameter(3)) ~~> (code => code.init)
|
||||
}
|
||||
|
||||
private def pointlessImmediateStoreToTheSameVariable(match1: AssemblyLinePattern, st1: Opcode.Value, match2: AssemblyLinePattern, st2: Opcode.Value) = {
|
||||
@ -806,12 +810,18 @@ object AlwaysGoodOptimizations {
|
||||
HasOpcode(RTS) ~~> ((code, ctx) => ctx.get[List[AssemblyLine]](1) ++ (AssemblyLine.implied(RTS) :: code.tail)),
|
||||
)
|
||||
|
||||
val PointlessRegisterTransfersBeforeCompare = new RuleBasedAssemblyOptimization("Pointless register transfers before compare",
|
||||
val PointlessRegisterTransfersBeforeCompare = new RuleBasedAssemblyOptimization("Pointless register transfers and loads before compare",
|
||||
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||
HasOpcodeIn(Set(DEX, INX, LDX, LAX)) ~
|
||||
(HasOpcode(TXA) & Elidable & DoesntMatterWhatItDoesWith(State.A)) ~~> (code => code.init),
|
||||
HasOpcodeIn(Set(DEY, INY, LDY)) ~
|
||||
(HasOpcode(TYA) & Elidable & DoesntMatterWhatItDoesWith(State.A)) ~~> (code => code.init),
|
||||
(HasOpcodeIn(Set(DEC, INC, ASL, ROL, ROR, LSR, SLO, SRE, RLA, RRA, ISC, DCP)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(HasOpcode(LDA) & Elidable & DoesntMatterWhatItDoesWith(State.A) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init),
|
||||
(HasOpcodeIn(Set(DEC, INC, ASL, ROL, ROR, LSR, SLO, SRE, RLA, RRA, ISC, DCP)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(HasOpcode(LDX) & Elidable & DoesntMatterWhatItDoesWith(State.X) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init),
|
||||
(HasOpcodeIn(Set(DEC, INC, ASL, ROL, ROR, LSR, SLO, SRE, RLA, RRA, ISC, DCP)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(HasOpcode(LDY) & Elidable & DoesntMatterWhatItDoesWith(State.Y) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init),
|
||||
)
|
||||
|
||||
private def stashing(tai: Opcode.Value, tia: Opcode.Value, readsI: AssemblyLinePattern, concernsI: AssemblyLinePattern, discardIF: Opcode.Value, withRts: Boolean, withBeq: Boolean) = {
|
||||
@ -983,6 +993,12 @@ object AlwaysGoodOptimizations {
|
||||
(Linear & Not(ChangesY) & Not(HasOpcode(DISCARD_YF)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||
(HasOpcode(LABEL) & MatchParameter(2)) ~
|
||||
(Elidable & HasOpcode(LDY) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.init),
|
||||
|
||||
(HasOpcodeIn(Set(LDA, STA)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(HasOpcodeIn(ShortBranching) & MatchParameter(3)) ~
|
||||
(Linear & Not(ChangesA) & Not(HasOpcode(DISCARD_AF)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||
(HasOpcode(LABEL) & MatchParameter(3) & HasCallerCount(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.init),
|
||||
)
|
||||
|
||||
val RearrangableLoadFromTheSameLocation = new RuleBasedAssemblyOptimization("Rearrangable load from the same location",
|
||||
@ -1031,6 +1047,9 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcodeIn(Set(CLC, SEC)) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_ => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(CLD, SED)) & DoesntMatterWhatItDoesWith(State.D)) ~~> (_ => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(CLV)) & DoesntMatterWhatItDoesWith(State.V)) ~~> (_ => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(ORA, EOR)) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil),
|
||||
(Elidable & HasOpcode(AND) & HasImmediate(0xff) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil),
|
||||
(Elidable & HasOpcode(ANC) & HasImmediate(0xff) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C)) ~~> (_ => Nil),
|
||||
)
|
||||
|
||||
val SimplifiableStackOperation = new RuleBasedAssemblyOptimization("Simplifiable stack operation",
|
||||
|
@ -460,7 +460,46 @@ object LaterOptimizations {
|
||||
code.tail.init ++ List(AssemblyLine.implied(DEX), code.last.copy(addrMode = IndexedX))
|
||||
},
|
||||
|
||||
(Elidable & HasOpcode(LDY) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsY)).* ~
|
||||
(Elidable & HasAddrMode(IndexedY) & MatchX(1) & DoesntMatterWhatItDoesWith(State.Y)) ~~> { (code, ctx)=>
|
||||
val lastLine = code.last
|
||||
code.tail.init ++ List(lastLine.copy(addrMode = IndexedX, parameter = lastLine.parameter - ctx.get[Int](1)))
|
||||
},
|
||||
|
||||
(Elidable & HasOpcode(LDY) & HasImmediate(0) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsY)).*.capture(2) ~
|
||||
(Elidable & HasAddrMode(IndexedY) & DoesntMatterWhatItDoesWith(State.Y, State.X)).capture(0) ~
|
||||
Linear.*.capture(3) ~
|
||||
(Elidable & HasOpcode(LDX) & MatchImmediate(1) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~~> { (code, ctx) =>
|
||||
val mainLine = ctx.get[List[AssemblyLine]](0).head
|
||||
ctx.get[List[AssemblyLine]](2) ++ List(
|
||||
code.last,
|
||||
mainLine.copy(addrMode = IndexedX, parameter = mainLine.parameter - ctx.get[Int](1))) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
|
||||
)
|
||||
|
||||
val UseBit = new RuleBasedAssemblyOptimization("Using BIT instruction",
|
||||
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||
(Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(Absolute, ZeroPage))) ~
|
||||
(Elidable & HasOpcode(AND) & HasImmediate(0x40)) ~
|
||||
(Elidable & HasOpcode(BNE) & DoesntMatterWhatItDoesWith(State.A, State.V, State.Z, State.N)) ~~> (code => List(
|
||||
code.head.copy(opcode = BIT),
|
||||
code.last.copy(opcode = BVS)
|
||||
)),
|
||||
(Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(Absolute, ZeroPage))) ~
|
||||
(Elidable & HasOpcode(AND) & HasImmediate(0x40)) ~
|
||||
(Elidable & HasOpcode(BEQ) & DoesntMatterWhatItDoesWith(State.A, State.V, State.Z, State.N)) ~~> (code => List(
|
||||
code.head.copy(opcode = BIT),
|
||||
code.last.copy(opcode = BVC)
|
||||
)),
|
||||
(Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(Absolute, ZeroPage))) ~
|
||||
(Elidable & HasOpcodeIn(Set(BMI, BPL)) & DoesntMatterWhatItDoesWith(State.A, State.V, State.Z, State.N)) ~~> (code => List(
|
||||
code.head.copy(opcode = BIT),
|
||||
code.last
|
||||
)),
|
||||
)
|
||||
|
||||
val All = List(
|
||||
@ -471,6 +510,7 @@ object LaterOptimizations {
|
||||
PointlessLoadAfterStore,
|
||||
PointessLoadingForShifting,
|
||||
LoadingAfterShifting,
|
||||
UseBit,
|
||||
UseXInsteadOfStack,
|
||||
UseYInsteadOfStack,
|
||||
UseZeropageAddressingMode)
|
||||
|
@ -178,7 +178,7 @@ object UndocumentedOptimizations {
|
||||
)
|
||||
|
||||
private def extraRmw(legal: Opcode.Value, illegal: Opcode.Value) =
|
||||
(Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(IndexedY, AbsoluteY, IndexedY)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & HasAddrModeIn(Set(IndexedX, IndexedY, AbsoluteY, IndexedY)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(legal) & HasAddrMode(Implied)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.A, State.N, State.Z, State.C, State.V)) ~~> { (code, ctx) =>
|
||||
code.head.copy(opcode = illegal) :: Nil
|
||||
@ -213,17 +213,30 @@ object UndocumentedOptimizations {
|
||||
trivialSequence2(ASL, ORA, Not(ConcernsC), SLO),
|
||||
trivialCommutativeSequence(ASL, ORA, SLO),
|
||||
extraRmw(ASL, SLO),
|
||||
(Elidable & HasOpcode(ASL) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(ASL) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory)).* ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
code.tail.init ++ List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SLO, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA) & Not(ReadsC) & Not(ReadsNOrZ)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(ASL) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SLO, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA) & Not(ChangesC)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SRE, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SLO, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(ASL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SLO, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
@ -240,15 +253,28 @@ object UndocumentedOptimizations {
|
||||
trivialSequence2(LSR, EOR, Not(ConcernsC), SRE),
|
||||
trivialCommutativeSequence(LSR, EOR, SRE),
|
||||
extraRmw(LSR, SRE),
|
||||
(Elidable & HasOpcode(LSR) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LSR) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory)).* ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
code.tail.init ++ List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SRE, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA) & Not(ReadsC) & Not(ReadsNOrZ)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(LSR) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SRE, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA) & Not(ChangesC)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SRE, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(LSR) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0), AssemblyLine(SRE, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
@ -262,14 +288,41 @@ object UndocumentedOptimizations {
|
||||
trivialSequence2(ROL, AND, Not(ConcernsC), RLA),
|
||||
trivialCommutativeSequence(ROL, AND, RLA),
|
||||
extraRmw(ROL, RLA),
|
||||
(Elidable & HasOpcode(ROL) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory)).* ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
code.tail.init ++ List(AssemblyLine.immediate(LDA, 0xff), AssemblyLine(RLA, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(ROL) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (code, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0xff), AssemblyLine(RLA, ctx.get[AddrMode.Value](0), ctx.get[Constant](1)))
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA) & Not(ConcernsC)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(ROL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C, State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0xff), AssemblyLine(RLA, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ConcernsA) & Not(ConcernsC)).*.capture(2) ~
|
||||
(Elidable & HasOpcode(ROL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.Z, State.N)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(ChangesA)).*.capture(3) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1)) ~~> { (_, ctx) =>
|
||||
List(AssemblyLine.immediate(LDA, 0xff), AssemblyLine(RLA, ctx.get[AddrMode.Value](0), ctx.get[Constant](1))) ++
|
||||
ctx.get[List[AssemblyLine]](2) ++
|
||||
ctx.get[List[AssemblyLine]](3)
|
||||
},
|
||||
)
|
||||
|
||||
val UseRra = new RuleBasedAssemblyOptimization("Using undocumented instruction RRA",
|
||||
needsFlowInfo = FlowInfoRequirement.BothFlows,
|
||||
// TODO: is it ok? carry flag and stuff?
|
||||
trivialSequence1(ROR, ADC, Not(ConcernsC), RRA),
|
||||
trivialSequence2(ROR, ADC, Not(ConcernsC), RRA),
|
||||
trivialCommutativeSequence(ROR, ADC, RRA),
|
||||
// trivialSequence1(ROR, ADC, Not(ConcernsC), RRA),
|
||||
// trivialSequence2(ROR, ADC, Not(ConcernsC), RRA),
|
||||
// trivialCommutativeSequence(ROR, ADC, RRA),
|
||||
extraRmw(ROR, RRA),
|
||||
)
|
||||
|
||||
@ -293,6 +346,10 @@ object UndocumentedOptimizations {
|
||||
(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(DEC) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||
(Elidable & HasOpcode(LDA) & Not(HasAddrMode(Immediate)) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.A)) ~~> { code =>
|
||||
List(AssemblyLine.immediate(LDA, 0), 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)) ~
|
||||
|
Loading…
x
Reference in New Issue
Block a user