1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-12-24 15:29:23 +00:00

6502 Fix an optimization bug with the carry flag (fixes #46)

This commit is contained in:
Karol Stasiak 2020-02-11 01:10:49 +01:00
parent fb1ad18868
commit 63d4bf2317
3 changed files with 65 additions and 4 deletions

View File

@ -10,6 +10,7 @@ import millfork.assembly.mos.AddrMode._
import millfork.env._
import millfork.error.FatalErrorReporting
import millfork.node.LiteralExpression
import millfork.node.MosNiceFunctionProperty.DoesntChangeA
/**
* 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]](6) ++ (
if (elseLabelUseCount == 1) Nil
else ctx.get[List[AssemblyLine]](10) ++ List(
else {
val storeAndSecondReturn = 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)
}
}
)
}
}

View File

@ -1,7 +1,8 @@
package millfork.test
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}
/**
@ -178,4 +179,40 @@ class MacroSuite extends FunSuite with Matchers {
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))
}
}

View File

@ -25,6 +25,21 @@ object EmuOptimizedRun extends EmuRun(
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(
Cpu.StrictMos,
OptimizationPresets.NodeOpt,