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",
|
||||
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||
loadBeforeTransfer(LDX, LDA, ConcernsX, State.X, TXA, Set(ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
||||
loadBeforeTransfer(LDA, LDX, ConcernsA, State.A, TAX, Set(ZeroPage, Absolute, IndexedY, AbsoluteY)),
|
||||
loadBeforeTransfer(LDY, LDA, ConcernsY, State.Y, TYA, Set(ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
||||
loadBeforeTransfer(LDA, LDY, ConcernsA, State.A, TAY, Set(ZeroPage, Absolute, ZeroPageX, IndexedX, AbsoluteX)),
|
||||
loadBeforeTransfer(LDX, LDA, ConcernsX, State.X, TXA, Set(Immediate, 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(Immediate, 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) =
|
||||
@ -916,9 +916,21 @@ object AlwaysGoodOptimizations {
|
||||
(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) =>
|
||||
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)
|
||||
},
|
||||
(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 => {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package millfork.test
|
||||
|
||||
import millfork.error.ErrorReporting
|
||||
import millfork.test.emu.EmuBenchmarkRun
|
||||
import org.scalatest.{FunSuite, Matchers}
|
||||
|
||||
@ -126,4 +125,26 @@ class BitPackingSuite extends FunSuite with Matchers {
|
||||
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