mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-24 15:29:23 +00:00
Optimization improvements
This commit is contained in:
parent
f9835ebf7e
commit
3d056a7eee
@ -33,6 +33,22 @@ object LaterOptimizations {
|
|||||||
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDA, Not(ChangesA), LDY, TAY),
|
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDA, Not(ChangesA), LDY, TAY),
|
||||||
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDX, Not(ChangesX), LDA, TXA),
|
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDX, Not(ChangesX), LDA, TXA),
|
||||||
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDY, Not(ChangesY), LDA, TYA),
|
TwoDifferentLoadsWhoseFlagsWillNotBeChecked(LDY, Not(ChangesY), LDA, TYA),
|
||||||
|
|
||||||
|
(HasOpcodeIn(Set(LDA, STA)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Linear & Not(ChangesA) & Not(HasOpcode(LDX)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcode(LDX) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init :+ AssemblyLine.implied(TAX)),
|
||||||
|
|
||||||
|
(HasOpcodeIn(Set(LDA, STA)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Linear & Not(ChangesA) & Not(HasOpcode(LDY)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcode(LDY) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init :+ AssemblyLine.implied(TAY)),
|
||||||
|
|
||||||
|
(HasOpcodeIn(Set(LDX, STX)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Linear & Not(ChangesX) & Not(HasOpcode(LDA)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init :+ AssemblyLine.implied(TXA)),
|
||||||
|
|
||||||
|
(HasOpcodeIn(Set(LDY, STY)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Linear & Not(ChangesY) & Not(HasOpcode(LDA)) & DoesntChangeIndexingInAddrMode(0) & DoesntChangeMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~~> (code => code.init :+ AssemblyLine.implied(TYA)),
|
||||||
)
|
)
|
||||||
|
|
||||||
private def a2x(line: AssemblyLine) = line.opcode match {
|
private def a2x(line: AssemblyLine) = line.opcode match {
|
||||||
|
@ -53,6 +53,8 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
AHX, SHY, SHX, LAS, TAS,
|
AHX, SHY, SHX, LAS, TAS,
|
||||||
TRB, TSB)
|
TRB, TSB)
|
||||||
|
|
||||||
|
private val opcodesCommutative = Set(AND, ORA, EOR, ADC)
|
||||||
|
|
||||||
private val LdxAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteY, ZeroPageY)
|
private val LdxAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteY, ZeroPageY)
|
||||||
private val LdyAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteX, ZeroPageX)
|
private val LdyAddrModes = Set(ZeroPage, Absolute, Immediate, AbsoluteX, ZeroPageX)
|
||||||
|
|
||||||
@ -288,6 +290,20 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
// if a register is populated with something else than a variable, then no variable cannot be assigned to that register
|
// if a register is populated with something else than a variable, then no variable cannot be assigned to that register
|
||||||
None
|
None
|
||||||
|
|
||||||
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
|
if opcodesCommutative(op) =>
|
||||||
|
if (th.name == vx || th.name == vy) {
|
||||||
|
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
||||||
|
else None
|
||||||
|
} else canBeInlined(xCandidate, yCandidate, xs)
|
||||||
|
|
||||||
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(CLC, _, _, _),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
|
if opcodesCommutative(op) =>
|
||||||
|
if (th.name == vx || th.name == vy) {
|
||||||
|
if (elidable && elidable2) canBeInlined(xCandidate, yCandidate, xs).map(_ + 2)
|
||||||
|
else None
|
||||||
|
} else canBeInlined(xCandidate, yCandidate, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), elidable), _) :: (AssemblyLine(TAX, _, _, elidable2), _) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), elidable), _) :: (AssemblyLine(TAX, _, _, elidable2), _) :: xs
|
||||||
if xCandidate.isDefined =>
|
if xCandidate.isDefined =>
|
||||||
// a variable cannot be inlined if there is TAX not after LDA of that variable
|
// a variable cannot be inlined if there is TAX not after LDA of that variable
|
||||||
@ -416,6 +432,20 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
|
if opcodesCommutative(op) =>
|
||||||
|
if (th.name == candidate) {
|
||||||
|
if (elidable && elidable2) canBeInlinedToAccumulator(options, start = false, synced = true, candidate, xs).map(_ + 3)
|
||||||
|
else None
|
||||||
|
} else canBeInlinedToAccumulator(options, start = false, synced = synced, candidate, xs)
|
||||||
|
|
||||||
|
case (AssemblyLine(LDA, _, _, elidable),_) :: (AssemblyLine(CLC, _, _, _),_) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), elidable2),_) :: xs
|
||||||
|
if opcodesCommutative(op) =>
|
||||||
|
if (th.name == candidate) {
|
||||||
|
if (elidable && elidable2) canBeInlinedToAccumulator(options, start = false, synced = true, candidate, xs).map(_ + 3)
|
||||||
|
else None
|
||||||
|
} else canBeInlinedToAccumulator(options, start = false, synced = synced, candidate, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), imp) :: xs
|
case (AssemblyLine(LDA, Absolute | ZeroPage, MemoryAddressConstant(th), true), imp) :: xs
|
||||||
if th.name == candidate =>
|
if th.name == candidate =>
|
||||||
// removing LDA saves 3 cycles
|
// removing LDA saves 3 cycles
|
||||||
@ -505,6 +535,30 @@ object VariableToRegisterOptimization extends AssemblyOptimization {
|
|||||||
if th.name == vx =>
|
if th.name == vx =>
|
||||||
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
AssemblyLine.implied(TXA) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == va =>
|
||||||
|
l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == va =>
|
||||||
|
l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == vx =>
|
||||||
|
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == vx =>
|
||||||
|
AssemblyLine.implied(TXA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == vy =>
|
||||||
|
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
|
case (l@AssemblyLine(LDA, _, _, _), _) :: (clc@AssemblyLine(CLC, _, _, _), _) :: (AssemblyLine(op, Absolute | ZeroPage, MemoryAddressConstant(th), _), _) :: xs
|
||||||
|
if opcodesCommutative(op) && th.name == vy =>
|
||||||
|
AssemblyLine.implied(TYA) :: l.copy(opcode = op) :: clc :: inlineVars(xCandidate, yCandidate, aCandidate, xs)
|
||||||
|
|
||||||
case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
case (AssemblyLine(LDA | STA, Absolute | ZeroPage, MemoryAddressConstant(th), _), imp) :: xs
|
||||||
if th.name == va =>
|
if th.name == va =>
|
||||||
if (imp.z == Unimportant && imp.n == Unimportant) {
|
if (imp.z == Unimportant && imp.n == Unimportant) {
|
||||||
|
Loading…
Reference in New Issue
Block a user