1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-16 20:29:04 +00:00

6502: fix invalid short jumps

This commit is contained in:
Karol Stasiak 2019-07-19 15:45:57 +02:00
parent 20f4baf2b2
commit 09f5ab269d
2 changed files with 37 additions and 29 deletions

View File

@ -2,12 +2,11 @@ package millfork.assembly.mos.opt
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import millfork.assembly.mos.{AddrMode, AssemblyLine, AssemblyLine0, Opcode}
import millfork.assembly.mos.Opcode._
import millfork.env.{Label, MemoryAddressConstant, NormalFunction}
import millfork.error.ConsoleLogger
import millfork.CompilationOptions import millfork.CompilationOptions
import millfork.assembly.Elidability import millfork.assembly.Elidability
import millfork.assembly.mos.Opcode._
import millfork.assembly.mos.{AddrMode, AssemblyLine, AssemblyLine0, Opcode}
import millfork.env.{Label, MemoryAddressConstant, NormalFunction, ThingInMemory}
/** /**
* @author Karol Stasiak * @author Karol Stasiak
@ -46,12 +45,10 @@ object JumpFixing {
case _ => None case _ => None
}.toMap }.toMap
var changed = false var changed = false
val result = code.zipWithIndex.flatMap {
case (line@AssemblyLine(op, AddrMode.Relative, MemoryAddressConstant(Label(label)), Elidability.Elidable, _), ix) => def makeLong(line: AssemblyLine) = {
labelOffsets.get(label).fold(List(line)) { labelOffset =>
val thisOffset = offsets(ix)
if (invalidShortJump(thisOffset, labelOffset)) {
changed = true changed = true
val op = line.opcode
val long: List[AssemblyLine] = op match { val long: List[AssemblyLine] = op match {
case BRA => List(line.copy(opcode = JMP, addrMode = AddrMode.Absolute)) case BRA => List(line.copy(opcode = JMP, addrMode = AddrMode.Absolute))
case BSR => List(line.copy(opcode = JSR, addrMode = AddrMode.Absolute)) case BSR => List(line.copy(opcode = JSR, addrMode = AddrMode.Absolute))
@ -70,8 +67,19 @@ object JumpFixing {
long.foreach(l => options.log.trace(l.toString)) long.foreach(l => options.log.trace(l.toString))
} }
long long
} else List(line)
} }
val result = code.zipWithIndex.flatMap {
case (line@AssemblyLine(_, AddrMode.Relative, MemoryAddressConstant(th: ThingInMemory), Elidability.Elidable, _), ix) =>
labelOffsets.get(th.name) match {
case None => makeLong(line)
case Some(labelOffset) =>
val thisOffset = offsets(ix)
if (invalidShortJump(thisOffset, labelOffset)) makeLong(line)
else List(line)
}
case (line@AssemblyLine(_, AddrMode.Relative, _, Elidability.Elidable, _), _) =>
makeLong(line)
case (line, _) => List(line) case (line, _) => List(line)
} }
if (changed) apply(f, result, options) else result if (changed) apply(f, result, options) else result

View File

@ -92,7 +92,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
case AssertByte(inner) => case AssertByte(inner) =>
val value = deepConstResolve(inner) val value = deepConstResolve(inner)
if (value.toByte == value) value else { if (value.toByte == value) value else {
log.error("Invalid relative jump: " + c) log.error("Invalid relative jump: " + c + " calculated offset: " + value)
-2 // spin -2 // spin
} }
case MemoryAddressConstant(th) => case MemoryAddressConstant(th) =>