mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-10 20:29:35 +00:00
More bit-packing and transfer optimizations
This commit is contained in:
parent
4676b0d48e
commit
d696704af9
@ -528,10 +528,10 @@ object AlwaysGoodOptimizations {
|
|||||||
|
|
||||||
val PointlessLoadBeforeTransfer = new RuleBasedAssemblyOptimization("Pointless load before transfer",
|
val PointlessLoadBeforeTransfer = new RuleBasedAssemblyOptimization("Pointless load before transfer",
|
||||||
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||||
loadBeforeTransfer(LDX, LDA, ConcernsX, State.X, TXA, Set(ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
loadBeforeTransfer(LDX, LDA, ConcernsX, State.X, TXA, Set(Immediate, ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
||||||
loadBeforeTransfer(LDA, LDX, ConcernsA, State.A, TAX, Set(ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
loadBeforeTransfer(LDA, LDX, ConcernsA, State.A, TAX, Set(Immediate, ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
||||||
loadBeforeTransfer(LDY, LDA, ConcernsY, State.Y, TYA, Set(ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
loadBeforeTransfer(LDY, LDA, ConcernsY, State.Y, TYA, Set(Immediate, ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
||||||
loadBeforeTransfer(LDA, LDY, ConcernsA, State.A, TAY, Set(ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
loadBeforeTransfer(LDA, LDY, ConcernsA, State.A, TAY, Set(Immediate, ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
||||||
)
|
)
|
||||||
|
|
||||||
private def immediateLoadBeforeTwoTransfers(ld1: Opcode.Value, ld2: Opcode.Value, concerns1: AssemblyLinePattern, overwrites1: State.Value, t12: Opcode.Value, t21: Opcode.Value) =
|
private def immediateLoadBeforeTwoTransfers(ld1: Opcode.Value, ld2: Opcode.Value, concerns1: AssemblyLinePattern, overwrites1: State.Value, t12: Opcode.Value, t21: Opcode.Value) =
|
||||||
@ -916,9 +916,21 @@ object AlwaysGoodOptimizations {
|
|||||||
(Elidable & (HasOpcode(ORA) | HasOpcode(ADC) & HasClear(State.C) & HasClear(State.D)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
(Elidable & (HasOpcode(ORA) | HasOpcode(ADC) & HasClear(State.C) & HasClear(State.D)) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z, State.V, State.A)) ~~> { (code, ctx) =>
|
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z, State.V, State.A)) ~~> { (code, ctx) =>
|
||||||
ctx.get[List[AssemblyLine]](3) ++
|
ctx.get[List[AssemblyLine]](3) ++
|
||||||
List(AssemblyLine.implied(ROR), code.head.copy(opcode = ROL)) ++
|
List(AssemblyLine.implied(LSR), code.head.copy(opcode = ROL)) ++
|
||||||
ctx.get[List[AssemblyLine]](2)
|
ctx.get[List[AssemblyLine]](2)
|
||||||
},
|
},
|
||||||
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||||
|
(Linear & DoesNotConcernMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcodeIn(Set(ROL, ASL)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||||
|
code.last :: code.drop(2).init
|
||||||
|
},
|
||||||
|
(Elidable & HasOpcode(LDA) & MatchAddrMode(0) & MatchParameter(1)) ~
|
||||||
|
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.A)) ~
|
||||||
|
(Linear & DoesNotConcernMemoryAt(0, 1)).* ~
|
||||||
|
(Elidable & HasOpcodeIn(Set(ROR, LSR)) & DoesntMatterWhatItDoesWith(State.N, State.Z, State.C) & MatchAddrMode(0) & MatchParameter(1)) ~~> {code =>
|
||||||
|
code.last :: code.drop(2).init
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
private def blockIsIdempotentWhenItComesToIndexRegisters(i: Int) = Where(ctx => {
|
private def blockIsIdempotentWhenItComesToIndexRegisters(i: Int) = Where(ctx => {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package millfork.test
|
package millfork.test
|
||||||
|
|
||||||
import millfork.error.ErrorReporting
|
|
||||||
import millfork.test.emu.EmuBenchmarkRun
|
import millfork.test.emu.EmuBenchmarkRun
|
||||||
import org.scalatest.{FunSuite, Matchers}
|
import org.scalatest.{FunSuite, Matchers}
|
||||||
|
|
||||||
@ -126,4 +125,26 @@ class BitPackingSuite extends FunSuite with Matchers {
|
|||||||
m.readByte(0xc000) should equal(0x56)
|
m.readByte(0xc000) should equal(0x56)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("Reverse byte") {
|
||||||
|
EmuBenchmarkRun("""
|
||||||
|
| word output_addr @$C000
|
||||||
|
| void main () {
|
||||||
|
| byte i
|
||||||
|
| byte input
|
||||||
|
| byte output
|
||||||
|
| output_addr = output.addr
|
||||||
|
| input = $5A
|
||||||
|
| output = 0
|
||||||
|
| for i,0,paralleluntil,8 {
|
||||||
|
| output <<= 1
|
||||||
|
| output |= input & 1
|
||||||
|
| input >>= 1
|
||||||
|
| }
|
||||||
|
| }
|
||||||
|
""".stripMargin){m =>
|
||||||
|
val addr = m.readWord(0xc000)
|
||||||
|
m.readByte(addr) should equal(0x5A)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user