1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Flow analysis fixes

This commit is contained in:
Karol Stasiak 2018-05-14 02:19:39 +02:00
parent 8cc3399239
commit fae7bb31c9
4 changed files with 98 additions and 11 deletions

View File

@ -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

View File

@ -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)
}

View File

@ -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()),

View File

@ -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)