1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-12-23 23:30:22 +00:00

Few more optimizations

This commit is contained in:
Karol Stasiak 2019-06-28 23:19:58 +02:00
parent 7cd1324c4e
commit 3e0dad4cb0
2 changed files with 54 additions and 2 deletions

View File

@ -34,12 +34,24 @@ object AlwaysGoodOptimizations {
(HasOpcode(CLC) & Elidable) ~
(HasOpcode(ADC) & Elidable & DoesntMatterWhatItDoesWith(State.C, State.Z, State.V, State.N)) ~~> (code => code(2).copy(opcode = LDA) :: code.drop(3)),
(HasOpcode(CLC) & Elidable) ~
(HasOpcode(ADC) & MatchImmediate(0) & Elidable) ~
(HasOpcode(ADC) & MatchImmediate(0) & Elidable) ~
(HasOpcode(CLC) & Elidable) ~
(HasOpcode(ADC) & MatchImmediate(1) & Elidable & DoesntMatterWhatItDoesWith(State.C, State.V)) ~~> ((code, ctx) => List(
AssemblyLine.implied(CLC),
AssemblyLine.immediate(ADC, (ctx.get[Constant](0) + ctx.get[Constant](1)).quickSimplify),
)),
(HasOpcode(AND) & HasImmediate(0x7F) & Elidable & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
(Linear & Not(ConcernsA)).* ~
(HasOpcodeIn(ASL, ROL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.tail),
(HasOpcodeIn(ORA, EOR) & HasImmediate(0x80) & Elidable & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
(Linear & Not(ConcernsA)).* ~
(HasOpcodeIn(ASL, ROL) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.tail),
(HasOpcode(AND) & HasImmediate(0xFE) & Elidable & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
(Linear & Not(ConcernsA)).* ~
(HasOpcodeIn(LSR, ROR) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.tail),
(HasOpcodeIn(ORA, EOR) & HasImmediate(1) & Elidable & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~
(Linear & Not(ConcernsA)).* ~
(HasOpcodeIn(LSR, ROR) & HasAddrMode(Implied) & DoesntMatterWhatItDoesWith(State.C)) ~~> (_.tail),
))
val PointlessAccumulatorShifting = new RuleBasedAssemblyOptimization("Pointless accumulator shifting",
@ -2735,7 +2747,7 @@ object AlwaysGoodOptimizations {
(HasOpcode(LDA) & MatchImmediate(0)) ~
(HasOpcode(STA) & HasAddrModeIn(Absolute, ZeroPage) & MatchParameter(4)) ~
(HasOpcode(LDA) & MatchImmediate(1) & HasAddrModeIn(Absolute, ZeroPage)) ~
(HasOpcode(LDA) & MatchImmediate(1)) ~
(HasOpcode(STA) & HasAddrModeIn(Absolute, ZeroPage) & MatchParameter(5)) ~
Where(ctx => {
ctx.addObject(3, ZeroPage)
@ -2757,6 +2769,30 @@ object AlwaysGoodOptimizations {
code.init :+ last.copy(parameter = addr, addrMode = if (last.addrMode == IndexedZ) Absolute else AbsoluteY)
},
(HasOpcode(LDA) & MatchImmediate(1)) ~
(HasOpcode(STA) & HasAddrModeIn(Absolute, ZeroPage) & MatchParameter(5)) ~
(HasOpcode(LDA) & MatchImmediate(0)) ~
(HasOpcode(STA) & HasAddrModeIn(Absolute, ZeroPage) & MatchParameter(4)) ~
Where(ctx => {
ctx.addObject(3, ZeroPage)
(ctx.get[Constant](4) + 1).quickSimplify == ctx.get[Constant](5)
}) ~
(Linear & DoesNotConcernMemoryAt(3, 4) & DoesNotConcernMemoryAt(3, 5)).* ~
Where(ctx => {
val lo = ctx.get[Constant](0)
val hi = ctx.get[Constant](1)
ctx.addObject(2, (hi.asl(8) + lo).quickSimplify)
true
}) ~
(Elidable & MatchParameter(4) & HasAddrModeIn(IndexedZ, IndexedY) & MatchAddrMode(9)) ~
Where(ctx => {
ctx.get[AddrMode.Value](9) == IndexedY || !ctx.compilationOptions.flag(CompilationFlag.Emit65CE02Opcodes)
}) ~~> { (code, ctx) =>
val addr = ctx.get[Constant](2)
val last = code.last
code.init :+ last.copy(parameter = addr, addrMode = if (last.addrMode == IndexedZ) Absolute else AbsoluteY)
},
)
val ReplacingArithmeticsWithBitOps = new RuleBasedAssemblyOptimization("Replacing arithmetics with bit ops",

View File

@ -708,4 +708,20 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
}
}
test("Optimize certain indexing operations") {
EmuBenchmarkRun(
"""
|array arr16[$100]
|noinline word getValue(word index) {
| word tmp
| tmp.hi = arr16[((index & 0x7f)<<1)+1]
| tmp.lo = arr16[(index & 0x7f)<<1]
| return (tmp & 0xff) >> 1;
|}
|void main() {
| getValue(1)
|}
""".stripMargin){ m => }
}
}