diff --git a/src/main/scala/millfork/assembly/mos/opt/ZeropageRegisterOptimizations.scala b/src/main/scala/millfork/assembly/mos/opt/ZeropageRegisterOptimizations.scala index b9f02522..803e8800 100644 --- a/src/main/scala/millfork/assembly/mos/opt/ZeropageRegisterOptimizations.scala +++ b/src/main/scala/millfork/assembly/mos/opt/ZeropageRegisterOptimizations.scala @@ -164,14 +164,22 @@ object ZeropageRegisterOptimizations { (Elidable & HasOpcodeIn(STA, STX, SAX, STY, STZ) & RefersTo("__reg", 1) & DoesntMatterWhatItDoesWithReg(1)) ~~> (_.tail), (Elidable & HasOpcodeIn(STA, STX, SAX, STY, STZ) & RefersTo("__reg", 2) & DoesntMatterWhatItDoesWithReg(2)) ~~> (_.tail), (Elidable & HasOpcodeIn(STA, STX, SAX, STY, STZ) & RefersTo("__reg", 3) & DoesntMatterWhatItDoesWithReg(3)) ~~> (_.tail), - (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR) & RefersTo("__reg", 0) & DoesntMatterWhatItDoesWithReg(0) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR) & RefersTo("__reg", 1) & DoesntMatterWhatItDoesWithReg(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR) & RefersTo("__reg", 2) & DoesntMatterWhatItDoesWithReg(2) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR) & RefersTo("__reg", 3) & DoesntMatterWhatItDoesWithReg(3) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 0) & DoesntMatterWhatItDoesWithReg(0) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 1) & DoesntMatterWhatItDoesWithReg(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 2) & DoesntMatterWhatItDoesWithReg(2) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.tail), - (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 3) & DoesntMatterWhatItDoesWithReg(3) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_.tail), + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 0) & Not(DoesntMatterWhatItDoesWithReg(0))).* ~ + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 0) & DoesntMatterWhatItDoesWithReg(0) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 1) & Not(DoesntMatterWhatItDoesWithReg(1))).* ~ + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 1) & DoesntMatterWhatItDoesWithReg(1) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 2) & Not(DoesntMatterWhatItDoesWithReg(2))).* ~ + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 2) & DoesntMatterWhatItDoesWithReg(2) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 3) & Not(DoesntMatterWhatItDoesWithReg(3))).* ~ + (Elidable & HasOpcodeIn(ROL, ROR, ASL, LSR, INC, DEC) & RefersTo("__reg", 3) & DoesntMatterWhatItDoesWithReg(3) & DoesntMatterWhatItDoesWith(State.C, State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 0) & Not(DoesntMatterWhatItDoesWithReg(0))).* ~ + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 0) & DoesntMatterWhatItDoesWithReg(0) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 1) & Not(DoesntMatterWhatItDoesWithReg(1))).* ~ + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 1) & DoesntMatterWhatItDoesWithReg(1) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 2) & Not(DoesntMatterWhatItDoesWithReg(2))).* ~ + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 2) & DoesntMatterWhatItDoesWithReg(2) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil), + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 3) & Not(DoesntMatterWhatItDoesWithReg(3))).* ~ + (Elidable & HasOpcodeIn(INC, DEC) & RefersTo("__reg", 3) & DoesntMatterWhatItDoesWithReg(3) & DoesntMatterWhatItDoesWith(State.N, State.Z)) ~~> (_ => Nil), (Elidable & HasOpcode(LDY) & RefersTo("__reg", 0)) ~ (Linear & Not(ConcernsY) & Not(RefersToOrUses("__reg", 0))).*.capture(2) ~ diff --git a/src/test/scala/millfork/test/InliningSuite.scala b/src/test/scala/millfork/test/InliningSuite.scala index 9c5dcec0..a47e5870 100644 --- a/src/test/scala/millfork/test/InliningSuite.scala +++ b/src/test/scala/millfork/test/InliningSuite.scala @@ -59,4 +59,24 @@ class InliningSuite extends FunSuite with Matchers { m.readByte(0xc000) should equal(6.<<(6).>>(8)) } } + + test("Should inline this even weirder thing") { + EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80)( + """ + | byte output@$c000 + | inline word square(word x) { + | byte shiftAmount + | shiftAmount = x.lo + | return x << shiftAmount + | } + | inline void pokeSquared(byte x) { + | output = hi(square(x)) + | } + | void main() { + | pokeSquared(6) + | } + """.stripMargin) { m => + m.readByte(0xc000) should equal(6.<<(6).>>(8)) + } + } } \ No newline at end of file