mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-13 05:39:54 +00:00
6809: implement retun dispatch statements
This commit is contained in:
parent
b7a34457fb
commit
b9bf433308
@ -0,0 +1,58 @@
|
||||
package millfork.compiler.m6809
|
||||
|
||||
import millfork.assembly.m6809.MLine
|
||||
import millfork.compiler.{AbstractReturnDispatch, CompilationContext}
|
||||
import millfork.env.{Constant, InitializedArray, ThingInMemory, VariableType}
|
||||
import millfork.node.{Expression, M6809Register, ReturnDispatchStatement}
|
||||
import millfork.output.NoAlignment
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object M6809ReturnDispatch extends AbstractReturnDispatch[MLine] {
|
||||
override def compileImpl(ctx: CompilationContext,
|
||||
stmt: ReturnDispatchStatement,
|
||||
label: String,
|
||||
actualMin: Int,
|
||||
actualMax: Int,
|
||||
paramArrays: IndexedSeq[InitializedArray],
|
||||
paramMins: IndexedSeq[Int],
|
||||
map: mutable.Map[Int, (Option[ThingInMemory], List[Expression])]): List[MLine] = {
|
||||
import millfork.assembly.m6809.MOpcode._
|
||||
import M6809Register.{A, B, D, X}
|
||||
val env = ctx.env.root
|
||||
val b = env.get[VariableType]("byte")
|
||||
val ctxForStoringParams = ctx.neverCheckArrayBounds
|
||||
val loadIndex = M6809ExpressionCompiler.compileToX(ctx, stmt.indexer)
|
||||
|
||||
val pair = stmt.params.zipWithIndex.foldLeft(List[List[MLine]]()) { (p1, p2) =>
|
||||
(p1, p2) match {
|
||||
case (reversedResult, (paramVar, paramIndex)) =>
|
||||
val storeParam = M6809ExpressionCompiler.stashXIfNeeded(ctx, M6809ExpressionCompiler.storeB(ctxForStoringParams, paramVar))
|
||||
if (storeParam.exists(l => l.changesRegister(B))) {
|
||||
ctx.log.error("Invalid/too complex target parameter variable", paramVar.position)
|
||||
storeParam.foreach(l => ctx.log.debug(l.toString))
|
||||
}
|
||||
val nextArray = (paramArrays(paramIndex).toAddress - paramMins(paramIndex)).quickSimplify
|
||||
((
|
||||
MLine.indexedX(LDB, nextArray) ::
|
||||
storeParam
|
||||
) :: reversedResult)
|
||||
}
|
||||
}
|
||||
val copyParams = pair.reverse.flatten
|
||||
// TODO: would it be better to use one table of words and do TFR X,D / LEAX D,X / LDX array,X ?
|
||||
val jumpTableLo = InitializedArray(label + "$jl.array", None, (actualMin to actualMax).map(i => lobyte0(map(i)._1)).toList, ctx.function.declaredBank, b, b, readOnly = true, NoAlignment)
|
||||
val jumpTableHi = InitializedArray(label + "$jh.array", None, (actualMin to actualMax).map(i => hibyte0(map(i)._1)).toList, ctx.function.declaredBank, b, b, readOnly = true, NoAlignment)
|
||||
env.registerUnnamedArray(jumpTableLo)
|
||||
env.registerUnnamedArray(jumpTableHi)
|
||||
val moveOffsetToLo = (jumpTableLo.toAddress - actualMin).quickSimplify
|
||||
val moveOffsetToHi = (jumpTableHi.toAddress - actualMin).quickSimplify
|
||||
val loadAddressToD = List(
|
||||
MLine.indexedX(LDB, moveOffsetToLo),
|
||||
MLine.indexedX(LDA, moveOffsetToHi))
|
||||
loadIndex ++ copyParams ++ loadAddressToD ++ List(MLine.tfr(D, X), MLine.indexedX(JMP, 0))
|
||||
}
|
||||
}
|
@ -107,6 +107,8 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
|
||||
case None =>
|
||||
(M6809ExpressionCompiler.compileToX(ctx, s.target) :+ MLine.indexedX(JMP, 0)) -> Nil
|
||||
}
|
||||
case s: ReturnDispatchStatement =>
|
||||
M6809ReturnDispatch.compile(ctx, s) -> Nil
|
||||
case _ =>
|
||||
println(statement)
|
||||
ctx.log.error("Not implemented yet", statement.position)
|
||||
|
@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
|
||||
class ReturnDispatchSuite extends FunSuite with Matchers {
|
||||
|
||||
test("Trivial test") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| void main () {
|
||||
@ -28,7 +28,7 @@ class ReturnDispatchSuite extends FunSuite with Matchers {
|
||||
}
|
||||
}
|
||||
test("Parameter test") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| array output [200] @$c000
|
||||
| sbyte param
|
||||
@ -74,7 +74,7 @@ class ReturnDispatchSuite extends FunSuite with Matchers {
|
||||
}
|
||||
|
||||
test("Enum test") {
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
|
||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
|
||||
"""
|
||||
| byte output @$c000
|
||||
| enum ugly {
|
||||
|
Loading…
x
Reference in New Issue
Block a user