From fae7bb31c97afee90f1e03dcd18d02f7e191fd0d Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Mon, 14 May 2018 02:19:39 +0200 Subject: [PATCH] Flow analysis fixes --- .../assembly/opt/CoarseFlowAnalyzer.scala | 26 ++++--- .../millfork/assembly/opt/CpuStatus.scala | 73 +++++++++++++++++++ .../assembly/opt/FlowAnalyzerForTheRest.scala | 2 +- .../opt/ReverseFlowAnalyzerPerOpcode.scala | 8 ++ 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/src/main/scala/millfork/assembly/opt/CoarseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/opt/CoarseFlowAnalyzer.scala index 4f67cb6d..00dc1272 100644 --- a/src/main/scala/millfork/assembly/opt/CoarseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/opt/CoarseFlowAnalyzer.scala @@ -10,21 +10,27 @@ import millfork.env.{Label, MemoryAddressConstant, NormalFunction, NumericConsta object CoarseFlowAnalyzer { def analyze(f: NormalFunction, code: List[AssemblyLine], compilationOptions: CompilationOptions): List[CpuStatus] = { - val emptyIz: Status[Int] = if (compilationOptions.flag(CompilationFlag.Emit65CE02Opcodes)) UnknownStatus else SingleStatus(0) - val emptyStatus = CpuStatus(iz = emptyIz) + val ceFlag = compilationOptions.flag(CompilationFlag.Emit65CE02Opcodes) + val cmosFlag = compilationOptions.flag(CompilationFlag.EmitCmosOpcodes) + val initialStatus = + if (compilationOptions.flag(CompilationFlag.Emit65CE02Opcodes)) CpuStatus.initialStatusCE + else CpuStatus.initialStatusStandard + val functionStartStatus = + if (f.interrupt) { + if (ceFlag) CpuStatus.initialInterruptStatusCE + else if (cmosFlag) CpuStatus.initialInterruptStatusCE + else CpuStatus.initialInterruptStatusStandard + } else initialStatus + val emptyStatus = + if (compilationOptions.flag(CompilationFlag.Emit65CE02Opcodes)) CpuStatus.emptyStatusCE + else CpuStatus.emptyStatusStandard val flagArray = Array.fill[CpuStatus](code.length)(emptyStatus) val codeArray = code.toArray - val initialStatus = CpuStatus( - d = SingleStatus(false), - m = SingleStatus(true), - w = SingleStatus(true), - iz = emptyIz - ) var changed = true while (changed) { changed = false - var currentStatus: CpuStatus = if (f.interrupt) emptyStatus else initialStatus + var currentStatus: CpuStatus = functionStartStatus for (i <- codeArray.indices) { import millfork.assembly.Opcode._ import millfork.assembly.AddrMode._ @@ -38,7 +44,7 @@ object CoarseFlowAnalyzer { currentStatus = codeArray.indices.flatMap(j => codeArray(j) match { case AssemblyLine(_, _, MemoryAddressConstant(Label(L)), _) => Some(flagArray(j)) case _ => None - }).fold(emptyStatus)(_ ~ _) + }).fold(currentStatus)(_ ~ _) case AssemblyLine(JSR | BYTE, _, _, _) => currentStatus = initialStatus diff --git a/src/main/scala/millfork/assembly/opt/CpuStatus.scala b/src/main/scala/millfork/assembly/opt/CpuStatus.scala index e704bda3..dca8c93a 100644 --- a/src/main/scala/millfork/assembly/opt/CpuStatus.scala +++ b/src/main/scala/millfork/assembly/opt/CpuStatus.scala @@ -364,3 +364,76 @@ case class CpuStatus(a: Status[Int] = UnknownStatus, case _ => false } } + +object CpuStatus { + val initialStatusStandard = CpuStatus( + a = AnyStatus, + x = AnyStatus, + y = AnyStatus, + c = AnyStatus, + v = AnyStatus, + z = AnyStatus, + n = AnyStatus, + d = SingleStatus(false), + m = SingleStatus(true), + w = SingleStatus(true), + iz = SingleStatus(0) + ) + val initialStatusCE = CpuStatus( + a = AnyStatus, + x = AnyStatus, + y = AnyStatus, + c = AnyStatus, + v = AnyStatus, + z = AnyStatus, + n = AnyStatus, + d = SingleStatus(false), + m = SingleStatus(true), + w = SingleStatus(true), + iz = AnyStatus + ) + + val initialInterruptStatusStandard = CpuStatus( + a = AnyStatus, + x = AnyStatus, + y = AnyStatus, + c = AnyStatus, + v = AnyStatus, + z = AnyStatus, + n = AnyStatus, + d = AnyStatus, + m = AnyStatus, + w = AnyStatus, + iz = SingleStatus(0) + ) + val initialInterruptStatusCmos = CpuStatus( + a = AnyStatus, + x = AnyStatus, + y = AnyStatus, + c = AnyStatus, + v = AnyStatus, + z = AnyStatus, + n = AnyStatus, + d = SingleStatus(false), + m = AnyStatus, + w = AnyStatus, + iz = SingleStatus(0) + ) + val initialInterruptStatusCE = CpuStatus( + a = AnyStatus, + x = AnyStatus, + y = AnyStatus, + c = AnyStatus, + v = AnyStatus, + z = AnyStatus, + n = AnyStatus, + d = SingleStatus(false), + m = AnyStatus, + w = AnyStatus, + iz = AnyStatus + ) + + val emptyStatusStandard = CpuStatus(iz = SingleStatus(0)) + + val emptyStatusCE = CpuStatus(iz = AnyStatus) +} \ No newline at end of file diff --git a/src/main/scala/millfork/assembly/opt/FlowAnalyzerForTheRest.scala b/src/main/scala/millfork/assembly/opt/FlowAnalyzerForTheRest.scala index 40300578..a0671f57 100644 --- a/src/main/scala/millfork/assembly/opt/FlowAnalyzerForTheRest.scala +++ b/src/main/scala/millfork/assembly/opt/FlowAnalyzerForTheRest.scala @@ -262,7 +262,7 @@ object FlowAnalyzerForTheRest { CPX -> (_.copy(c = AnyStatus, n = AnyStatus, z = AnyStatus, src = AnyStatus)), CPY -> (_.copy(c = AnyStatus, n = AnyStatus, z = AnyStatus, src = AnyStatus)), CPZ -> (_.copy(c = AnyStatus, n = AnyStatus, z = AnyStatus, src = AnyStatus)), - BIT -> (_.copy(c = AnyStatus, v = AnyStatus, n = AnyStatus, z = AnyStatus, src = AnyStatus)), + BIT -> (_.copy(v = AnyStatus, n = AnyStatus, z = AnyStatus, src = AnyStatus)), TRB -> (_.copy(z = AnyStatus, src = AnyStatus)), TSB -> (_.copy(z = AnyStatus, src = AnyStatus)), JMP -> (_ => CpuStatus()), diff --git a/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzerPerOpcode.scala b/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzerPerOpcode.scala index 23b76c0a..a681e3ec 100644 --- a/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzerPerOpcode.scala +++ b/src/main/scala/millfork/assembly/opt/ReverseFlowAnalyzerPerOpcode.scala @@ -150,6 +150,14 @@ object ReverseFlowAnalyzerPerOpcode { n = Unimportant, z = Unimportant, m = Important) }), + BIT -> (currentImportance => { + currentImportance.copy( + a = currentImportance.z, + n = Unimportant, + z = Unimportant, + v = Unimportant, + m = Important) + }), ADC -> (currentImportance => { val ignoreOutput = allAddingOutputsUnimportant(currentImportance)