mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-11 12:29:46 +00:00
6502 Fix an optimization bug with the carry flag (fixes #46)
This commit is contained in:
parent
fb1ad18868
commit
63d4bf2317
@ -10,6 +10,7 @@ import millfork.assembly.mos.AddrMode._
|
|||||||
import millfork.env._
|
import millfork.env._
|
||||||
import millfork.error.FatalErrorReporting
|
import millfork.error.FatalErrorReporting
|
||||||
import millfork.node.LiteralExpression
|
import millfork.node.LiteralExpression
|
||||||
|
import millfork.node.MosNiceFunctionProperty.DoesntChangeA
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These optimizations should not remove opportunities for more complex optimizations to trigger.
|
* These optimizations should not remove opportunities for more complex optimizations to trigger.
|
||||||
@ -1863,9 +1864,17 @@ object AlwaysGoodOptimizations {
|
|||||||
ctx.get[List[AssemblyLine]](5) ++
|
ctx.get[List[AssemblyLine]](5) ++
|
||||||
ctx.get[List[AssemblyLine]](6) ++ (
|
ctx.get[List[AssemblyLine]](6) ++ (
|
||||||
if (elseLabelUseCount == 1) Nil
|
if (elseLabelUseCount == 1) Nil
|
||||||
else ctx.get[List[AssemblyLine]](10) ++ List(
|
else {
|
||||||
AssemblyLine.immediate(LDA, if (firstSet) (if (zeroIfSet) nonZero else 0) else (if (zeroIfSet) 0 else nonZero))
|
val storeAndSecondReturn = ctx.get[List[AssemblyLine]](5) ++ ctx.get[List[AssemblyLine]](6)
|
||||||
) ++ ctx.get[List[AssemblyLine]](5) ++ ctx.get[List[AssemblyLine]](6)
|
val set = Set(RTS, JSR, RTI, RTL, BSR)
|
||||||
|
if (storeAndSecondReturn.exists(p => set(p.opcode))) {
|
||||||
|
ctx.get[List[AssemblyLine]](10) ++ List(
|
||||||
|
AssemblyLine.immediate(LDA, if (firstSet) (if (zeroIfSet) nonZero else 0) else (if (zeroIfSet) 0 else nonZero))
|
||||||
|
) ++ ctx.get[List[AssemblyLine]](5) ++ ctx.get[List[AssemblyLine]](6)
|
||||||
|
} else {
|
||||||
|
ctx.get[List[AssemblyLine]](10)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package millfork.test
|
package millfork.test
|
||||||
|
|
||||||
import millfork.Cpu
|
import millfork.Cpu
|
||||||
import millfork.test.emu.{EmuBenchmarkRun, EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun, ShouldNotCompile}
|
import millfork.output.MemoryBank
|
||||||
|
import millfork.test.emu.{EmuBenchmarkRun, EmuCrossPlatformBenchmarkRun, EmuOptimizedAccordingToLevelRun, EmuOptimizedRun, EmuUnoptimizedCrossPlatformRun, ShouldNotCompile}
|
||||||
import org.scalatest.{FunSuite, Matchers}
|
import org.scalatest.{FunSuite, Matchers}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -178,4 +179,40 @@ class MacroSuite extends FunSuite with Matchers {
|
|||||||
m.readByte(0xc000) should equal(1)
|
m.readByte(0xc000) should equal(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("Issue #46") {
|
||||||
|
val src =
|
||||||
|
"""
|
||||||
|
|bool output
|
||||||
|
|
|
||||||
|
|byte input
|
||||||
|
|byte y
|
||||||
|
|
|
||||||
|
|void main() {
|
||||||
|
| bool result
|
||||||
|
| input = 13
|
||||||
|
| y = 12
|
||||||
|
| test(result, input)
|
||||||
|
|
|
||||||
|
| if (result) {
|
||||||
|
| output = true
|
||||||
|
| }
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
|macro void test(bool returnVal, byte x) {
|
||||||
|
| returnVal = x >= y
|
||||||
|
| returnVal = returnVal && x <= y + 8
|
||||||
|
|}
|
||||||
|
|""".stripMargin
|
||||||
|
|
||||||
|
|
||||||
|
def assertAtLeastOneTrueInZeroPage(m: MemoryBank): Unit = {
|
||||||
|
val countOfTrues = 0.to(0xff).count(a => m.readByte(a) == 1)
|
||||||
|
countOfTrues should be > (0)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertAtLeastOneTrueInZeroPage(EmuOptimizedAccordingToLevelRun(1)(src))
|
||||||
|
assertAtLeastOneTrueInZeroPage(EmuOptimizedAccordingToLevelRun(2)(src))
|
||||||
|
assertAtLeastOneTrueInZeroPage(EmuOptimizedAccordingToLevelRun(3)(src))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,21 @@ object EmuOptimizedRun extends EmuRun(
|
|||||||
OptimizationPresets.Good ++
|
OptimizationPresets.Good ++
|
||||||
OptimizationPresets.Good)
|
OptimizationPresets.Good)
|
||||||
|
|
||||||
|
case class EmuOptimizedAccordingToLevelRun(optLevel: Int) extends EmuRun(
|
||||||
|
Cpu.Ricoh,
|
||||||
|
OptimizationPresets.NodeOpt,
|
||||||
|
optLevel match {
|
||||||
|
case 0 => Nil
|
||||||
|
case 1 => OptimizationPresets.QuickPreset
|
||||||
|
case _ =>
|
||||||
|
val goodExtras = ZeropageRegisterOptimizations.All
|
||||||
|
val extras = Nil
|
||||||
|
val goodCycle = List.fill(optLevel - 2)(OptimizationPresets.Good ++ goodExtras).flatten
|
||||||
|
val mainCycle = List.fill(optLevel - 1)(OptimizationPresets.AssOpt ++ extras).flatten
|
||||||
|
goodCycle ++ mainCycle ++ goodCycle
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
object EmuSizeOptimizedRun extends EmuRun(
|
object EmuSizeOptimizedRun extends EmuRun(
|
||||||
Cpu.StrictMos,
|
Cpu.StrictMos,
|
||||||
OptimizationPresets.NodeOpt,
|
OptimizationPresets.NodeOpt,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user