1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-04-06 20:37:12 +00:00

6809: Various improvements

This commit is contained in:
Karol Stasiak 2019-10-08 01:43:09 +02:00
parent c61d044226
commit f08caa0b7a
14 changed files with 365 additions and 75 deletions

View File

@ -3,7 +3,7 @@ package millfork.assembly.m6809
import millfork.CompilationFlag
import millfork.assembly.{AbstractCode, Elidability, SourceLine}
import millfork.compiler.CompilationContext
import millfork.env.{Constant, Label, MemoryVariable, NumericConstant, StackVariable, Variable, VariableInMemory}
import millfork.env.{Constant, Label, MemoryVariable, NumericConstant, StackVariable, ThingInMemory, Variable, VariableInMemory}
import millfork.node.{M6809Register, Position}
/**
@ -56,6 +56,8 @@ object MLine {
def absolute(opcode: MOpcode.Value, param: Constant): MLine = MLine(opcode, Absolute(false), param)
def absolute(opcode: MOpcode.Value, param: ThingInMemory): MLine = MLine(opcode, Absolute(false), param.toAddress)
//def userstack(opcode: MOpcode.Value, offset: Int): MLine = MLine(opcode, Indexed(M6809Register.U, indirect = false), Constant(offset))
def variablestack(ctx: CompilationContext, opcode: MOpcode.Value, offset: Int): MLine = {
@ -112,12 +114,12 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
case Absolute(true) => s" [$parameter]"
case Indexed(base, false) => s" $parameter,$base"
case Indexed(base, true) => s" [$parameter,$base]"
case DAccumulatorIndexed(base, false) => " D,$base"
case DAccumulatorIndexed(base, true) => " [D,$base]"
case AAccumulatorIndexed(base, false) => " A,$base"
case AAccumulatorIndexed(base, true) => " [A,$base]"
case BAccumulatorIndexed(base, false) => " B,$base"
case BAccumulatorIndexed(base, true) => " [B,$base]"
case DAccumulatorIndexed(base, false) => s" D,$base"
case DAccumulatorIndexed(base, true) => s" [D,$base]"
case AAccumulatorIndexed(base, false) => s" A,$base"
case AAccumulatorIndexed(base, true) => s" [A,$base]"
case BAccumulatorIndexed(base, false) => s" B,$base"
case BAccumulatorIndexed(base, true) => s" [B,$base]"
case PreDecremented(base, 1, false) => s" ,-$base"
case PreDecremented(base, 2, false) => s" ,--$base"
case PreDecremented(base, 1, true) => s" [-$base]"
@ -146,8 +148,8 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
}
import MOpcode._
(opcode, addrMode) match {
case (_, InherentA) => reg == A
case (_, InherentB) => reg == B
case (_, InherentA) => overlaps(A)
case (_, InherentB) => overlaps(B)
case (PULU, set:RegisterSet) => reg == U || set.contains(reg)
case (PULS, set:RegisterSet) => reg == S || set.contains(reg)
case (PSHS, _) => reg == U

View File

@ -34,6 +34,26 @@ object M6809Buitins {
}
}
def perform16BitInPlace(ctx: CompilationContext, l: LhsExpression, r: Expression, opcode: MOpcode.Value, commutative: Boolean): List[MLine] = {
val lc = M6809ExpressionCompiler.compileToD(ctx, l)
val rc = M6809ExpressionCompiler.compileToD(ctx, r)
(lc, rc) match {
case (List(ldl@MLine0(LDD, Absolute(false), _)), _) if opcode != SUBD =>
rc ++ List(ldl.copy(opcode = opcode), ldl.copy(opcode = STD))
case (_, List(ldr@MLine0(LDD, Absolute(false), _))) if lc.last.opcode == LDD =>
lc ++ List(ldr.copy(opcode = opcode), lc.last.copy(opcode = STD))
case _ if lc.last.opcode == LDD && commutative =>
// TODO: preserve X?
lc ++ List(MLine.pp(PSHS, M6809Register.D)) ++ rc ++ List(MLine.accessAndPullSTwice(opcode), lc.last.copy(opcode = STD))
case _ if lc.last.opcode == LDD =>
// TODO: preserve X?
rc ++ List(MLine.pp(PSHS, M6809Register.D)) ++ lc ++ List(MLine.accessAndPullSTwice(opcode), lc.last.copy(opcode = STD))
case _ =>
println(lc)
???
}
}
def split(ctx: CompilationContext, expr: SumExpression): (Constant, List[(Boolean, Expression)]) = {
var constant = Constant.Zero
@ -92,7 +112,7 @@ object M6809Buitins {
for ((neg, load) <- addendReads) {
if (result.isEmpty && fromScratch) {
result ++= load
if (neg) result += MLine.inherent(NEG)
if (neg) result += MLine.inherentB(NEG)
} else {
load match {
case List(l@MLine0(LDB, _, _)) =>
@ -168,15 +188,112 @@ object M6809Buitins {
}
def compileWordSum(ctx: CompilationContext, expr: SumExpression, fromScratch: Boolean): List[MLine] = {
???
if (expr.decimal) ???
val (constant, variable) = split(ctx, expr)
val addendReads = variable
.map(addend => addend._1 -> M6809ExpressionCompiler.compileToD(ctx, addend._2))
.map(code => (if (code._1) 1 else 0, complexityD(code._2)) -> code).sortBy(_._1).map(_._2)
val result = ListBuffer[MLine]()
for ((neg, load) <- addendReads) {
if (result.isEmpty && fromScratch) {
result ++= load
if (neg) {
result += MLine.immediate(EORA, 0xff)
result += MLine.immediate(EORB, 0xff)
result += MLine.immediate(ADDD, 1)
}
} else {
load match {
case List(l@MLine0(LDD, _, _)) =>
if (neg) {
result += l.copy(opcode = SUBD)
} else {
result += l.copy(opcode = ADDD)
}
case _ =>
if (neg) {
result += MLine.pp(PSHS, M6809Register.D)
result ++= load
// TODO: optimize
result += MLine.immediate(EORA, 0xff)
result += MLine.immediate(EORB, 0xff)
result += MLine.immediate(ADDD, 1)
result += MLine.accessAndPullSTwice(ADDD)
} else {
result += MLine.pp(PSHS, M6809Register.D)
result ++= load
result += MLine.accessAndPullSTwice(ADDD)
}
}
}
}
if (!constant.isProvablyZero) {
if (result.isEmpty) {
result += MLine.immediate(LDD, constant)
} else {
result += MLine.immediate(ADDD, constant)
}
}
result.toList
}
def compileWordBitwise(ctx: CompilationContext,
params: List[Expression],
fromScratch: Boolean,
opcodeB: MOpcode.Value,
opcodeA: MOpcode.Value,
opcodeB: MOpcode.Value,
op: MathOperator.Value,
empty: Int): List[MLine] = {
???
val (constant, variable) = split(ctx, params, op, empty)
val addendReads = variable
.map(addend => M6809ExpressionCompiler.compileToD(ctx, addend))
.map(code => complexityD(code) -> code).sortBy(_._1).map(_._2)
val result = ListBuffer[MLine]()
for (load <- addendReads) {
if (result.isEmpty && fromScratch) {
result ++= load
} else {
load match {
case List(l@MLine0(LDD, Absolute(false), addr)) =>
result += l.copy(opcode = opcodeA)
result += l.copy(opcode = opcodeB, parameter = addr + 1)
case List(l@MLine0(LDD, Immediate, c)) =>
result += l.copy(opcode = opcodeA, parameter = c.hiByte)
result += l.copy(opcode = opcodeB, parameter = c.loByte)
case _ =>
result += MLine.pp(PSHS, M6809Register.D)
result ++= load
result += MLine.accessAndPullS(opcodeA)
result += MLine.accessAndPullS(opcodeB)
}
}
}
if (!constant.isProvably(empty)) {
if (result.isEmpty) {
result += MLine.immediate(LDD, constant)
} else {
result += MLine.immediate(opcodeA, constant.hiByte)
result += MLine.immediate(opcodeB, constant.loByte)
}
}
result.toList
}
def compileByteShiftForB(ctx: CompilationContext, rhs:Expression, left: Boolean): List[MLine] = {
val op = if (left) MOpcode.ASL else MOpcode.LSR
ctx.env.eval(rhs) match {
case Some(NumericConstant(0, _)) => Nil
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(MLine.inherentB(op))
case _ => ???
}
}
def compileWordShiftForD(ctx: CompilationContext, rhs:Expression, left: Boolean): List[MLine] = {
val op = if (left) List(MLine.inherentB(ASL), MLine.inherentA(ROL)) else List(MLine.inherentA(LSR), MLine.inherentB(ROR))
ctx.env.eval(rhs) match {
case Some(NumericConstant(0, _)) => Nil
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(op).flatten
case _ => ???
}
}
}

View File

@ -4,7 +4,7 @@ import millfork.assembly.m6809.{DAccumulatorIndexed, Indexed, MLine, MOpcode, Tw
import millfork.compiler.{AbstractExpressionCompiler, BranchIfFalse, BranchIfTrue, BranchSpec, ComparisonType, CompilationContext, NoBranching}
import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SumExpression, VariableExpression}
import millfork.assembly.m6809.MOpcode._
import millfork.env.{AssemblyParamSignature, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FunctionInMemory, M6809RegisterVariable, MacroFunction, MathOperator, MemoryVariable, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, Type, Variable, VariablePointy}
import millfork.env.{AssemblyParamSignature, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FunctionInMemory, FunctionPointerType, M6809RegisterVariable, MacroFunction, MathOperator, MemoryVariable, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, ThingInMemory, Type, Variable, VariableInMemory, VariablePointy}
import scala.collection.GenTraversableOnce
@ -116,8 +116,11 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case Some(ix) => List(MLine.absolute(LDX, v.addr)) -> (ix * v.elementType.size).quickSimplify
case _ =>
v.indexType.size match {
case 1 =>
(compileToD(ctx, index) :+ MLine(LEAX, DAccumulatorIndexed(M6809Register.X, indirect = false), Constant.Zero)) -> Constant.Zero
case 1 | 2 =>
(compileToD(ctx, index) ++ List(
MLine.absolute(LDX, v.addr),
MLine(LEAX, DAccumulatorIndexed(M6809Register.X, indirect = false), Constant.Zero)
)) -> Constant.Zero
}
}
prepareIndex ++ (targetSize match {
@ -133,35 +136,94 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case e@SumExpression(expressions, decimal) =>
getArithmeticParamMaxSize(ctx, expressions.map(_._2)) match {
case 1 => M6809Buitins.compileByteSum(ctx, e, fromScratch = true) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordSum(ctx, e, fromScratch = false) ++ targetifyD(ctx, target)
case 2 => M6809Buitins.compileWordSum(ctx, e, fromScratch = true) ++ targetifyD(ctx, target)
}
case fce@FunctionCallExpression(functionName, params) =>
functionName match {
case "not" => ???
case "nonet" => ???
case "nonet" =>
if (params.length != 1) {
ctx.log.error("Invalid number of parameters", fce.position)
Nil
} else {
ctx.env.eval(params.head) match {
case Some(c) =>
target match {
case MExpressionTarget.NOTHING => Nil
case _ => List(MLine.immediate(toLd(target), c))
}
case _ =>
compileToB(ctx, params.head) ++ List(MLine.immediate(LDA, 0), MLine.inherentA(ROL)) ++ targetifyD(ctx, target)
}
}
case "hi" =>
compileToD(ctx, params.head) ++ targetifyA(ctx, target, isSigned = false)
if (params.length != 1) {
ctx.log.error("Invalid number of parameters", fce.position)
Nil
} else {
compileToD(ctx, params.head) ++ targetifyA(ctx, target, isSigned = false)
}
case "lo" =>
compileToD(ctx, params.head) ++ targetifyB(ctx, target, isSigned = false)
case "call" => ???
if (params.length != 1) {
ctx.log.error("Invalid number of parameters", fce.position)
Nil
} else {
compileToD(ctx, params.head) ++ targetifyB(ctx, target, isSigned = false)
}
case "call" =>
params match {
case List(fp) =>
getExpressionType(ctx, fp) match {
case FunctionPointerType(_, _, _, _, Some(v)) if (v.name == "void") =>
compileToX(ctx, fp) :+ MLine.absolute(JSR, env.get[ThingInMemory]("call"))
case _ =>
ctx.log.error("Not a function pointer", fp.position)
compile(ctx, fp, MExpressionTarget.NOTHING)
}
case List(fp, param) =>
getExpressionType(ctx, fp) match {
case FunctionPointerType(_, _, _, Some(pt), Some(v)) =>
if (pt.size > 2 || pt.size < 1) {
ctx.log.error("Invalid parameter type", param.position)
compile(ctx, fp, MExpressionTarget.NOTHING) ++ compile(ctx, param, MExpressionTarget.NOTHING)
} else if (getExpressionType(ctx, param).isAssignableTo(pt)) {
// TODO: optimal compile order
pt.size match {
case 1 =>
compileToB(ctx, param) ++ stashBIfNeeded(ctx, compileToX(ctx, fp)) :+ MLine.absolute(JSR, env.get[ThingInMemory]("call"))
case 2 =>
compileToD(ctx, param) ++ stashDIfNeeded(ctx, compileToX(ctx, fp)) :+ MLine.absolute(JSR, env.get[ThingInMemory]("call"))
}
} else {
ctx.log.error("Invalid parameter type", param.position)
compile(ctx, fp, MExpressionTarget.NOTHING) ++ compile(ctx, param, MExpressionTarget.NOTHING)
}
case _ =>
ctx.log.error("Not a function pointer", fp.position)
compile(ctx, fp, MExpressionTarget.NOTHING) ++ compile(ctx, param, MExpressionTarget.NOTHING)
}
case _ =>
ctx.log.error("Invalid call syntax", fce.position)
Nil
}
case "*" => ???
case "*'" => ???
case "*'" => ctx.log.error("Decimal multiplication not implemented yet", fce.position); Nil
case "/" => ???
case "%%" => ???
case "&" =>
getArithmeticParamMaxSize(ctx, params) match {
case 1 => M6809Buitins.compileByteBitwise(ctx, params, fromScratch = true, ANDB, MathOperator.And, 0xff) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, ANDA, ANDB, MathOperator.And, 0xffff) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, ANDA, ANDB, MathOperator.And, 0xffff) ++ targetifyD(ctx, target)
}
case "|" =>
getArithmeticParamMaxSize(ctx, params) match {
case 1 => M6809Buitins.compileByteBitwise(ctx, params, fromScratch = true, ORB, MathOperator.Or, 0) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, ORA, ORB, MathOperator.Or, 0) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, ORA, ORB, MathOperator.Or, 0) ++ targetifyD(ctx, target)
}
case "^" =>
getArithmeticParamMaxSize(ctx, params) match {
case 1 => M6809Buitins.compileByteBitwise(ctx, params, fromScratch = true, EORB, MathOperator.Exor, 0) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, EORA, EORB, MathOperator.Exor, 0) ++ targetifyB(ctx, target, isSigned = false)
case 2 => M6809Buitins.compileWordBitwise(ctx, params, fromScratch = true, EORA, EORB, MathOperator.Exor, 0) ++ targetifyD(ctx, target)
}
case "&&" =>
assertBool(ctx, "&&", params)
@ -190,7 +252,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
compileTransitiveRelation(ctx, "==", params, target, branches) { (l, r) =>
size match {
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.Equal, l, r, branches)
case 2 => ???
case 2 => ctx.log.error("Word equality comparison not implemented yet", fce.position); Nil
case _ => ???
}
}
@ -199,7 +261,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
compileTransitiveRelation(ctx, "!=", params, target, branches) { (l, r) =>
size match {
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.NotEqual, l, r, branches)
case 2 => ???
case 2 => ctx.log.error("Word inequality comparison not implemented yet", fce.position); Nil
case _ => ???
}
}
@ -235,27 +297,44 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case _ => ???
}
}
case "<<" => ???
case "<<" =>
getArithmeticParamMaxSize(ctx, params) match {
case 1 => compileToB(ctx, params(0)) ++ M6809Buitins.compileByteShiftForB(ctx, params(1), left = true) ++ targetifyB(ctx, target, isSigned = false)
case 2 => compileToD(ctx, params(0)) ++ M6809Buitins.compileWordShiftForD(ctx, params(1), left = true) ++ targetifyD(ctx, target)
}
case ">>" => ???
case ">>>>" => ???
getArithmeticParamMaxSize(ctx, params) match {
case 1 => compileToB(ctx, params(0)) ++ M6809Buitins.compileByteShiftForB(ctx, params(1), left = false) ++ targetifyB(ctx, target, isSigned = false)
case 2 => compileToD(ctx, params(0)) ++ M6809Buitins.compileWordShiftForD(ctx, params(1), left = false) ++ targetifyD(ctx, target)
}
case ">>>>" =>
// TODO: this words, but is really suboptimal
getArithmeticParamMaxSize(ctx, params) match {
case 1 | 2 => compileToD(ctx, params(0)) ++
List(MLine.immediate(ANDA, 1)) ++
M6809Buitins.compileWordShiftForD(ctx, params(1), left = false) ++
targetifyB(ctx, target, isSigned = false)
}
case "<<'" => ???
case ">>'" => ???
case "+=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ADDB)
case _ => ???
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true)
case _ => ctx.log.error("Long addition not implemented yet", fce.position); Nil
}
case "+'=" => ???
case "-=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, SUBB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false)
case _ => ???
}
case "-'=" => ???
case "*=" => ???
case "*'=" => ???
case "*'=" => ctx.log.error("Decimal multiplication not implemented yet", fce.position); Nil
case "/=" => ???
case "%%=" => ???
case "&=" =>
@ -276,9 +355,33 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, EORB)
case _ => ???
}
case "<<=" => ???
case "<<=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
// TODO: optimize shifts directly in memory
size match {
case 1 => compileAddressToX(ctx, l) ++
List(MLine.indexedX(LDB, Constant.Zero)) ++
M6809Buitins.compileByteShiftForB(ctx, r, left = true) ++
List(MLine.indexedX(STB, Constant.Zero))
case 2 => compileAddressToX(ctx, l) ++
List(MLine.indexedX(LDD, Constant.Zero)) ++
M6809Buitins.compileWordShiftForD(ctx, r, left = true) ++
List(MLine.indexedX(STD, Constant.Zero))
}
case "<<'=" => ???
case ">>=" => ???
case ">>=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
// TODO: optimize shifts directly in memory
size match {
case 1 => compileAddressToX(ctx, l) ++
List(MLine.indexedX(LDB, Constant.Zero)) ++
M6809Buitins.compileByteShiftForB(ctx, r, left = false) ++
List(MLine.indexedX(STB, Constant.Zero))
case 2 => compileAddressToX(ctx, l) ++
List(MLine.indexedX(LDD, Constant.Zero)) ++
M6809Buitins.compileWordShiftForD(ctx, r, left = false) ++
List(MLine.indexedX(STD, Constant.Zero))
}
case ">>'=" => ???
case ">>>>=" => ???
case _ =>
@ -401,8 +504,13 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
}
def stashBIfNeeded(ctx: CompilationContext, lines: List[MLine]): List[MLine] = {
// TODO: only push if needed
MLine.pp(PSHS, M6809Register.B) :: (lines :+ MLine.pp(PULS, M6809Register.B))
if (lines.exists(_.changesRegister(M6809Register.B))) MLine.pp(PSHS, M6809Register.B) :: (lines :+ MLine.pp(PULS, M6809Register.B))
else lines
}
def stashDIfNeeded(ctx: CompilationContext, lines: List[MLine]): List[MLine] = {
if (lines.exists(_.changesRegister(M6809Register.D))) MLine.pp(PSHS, M6809Register.D) :: (lines :+ MLine.pp(PULS, M6809Register.D))
else lines
}
def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = {
@ -415,6 +523,9 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case IndexedExpression(name, index) =>
ctx.env.getPointy(name) match {
case p: ConstantPointy =>
if (p.readOnly) {
ctx.log.error("Writing to a constant array", target.position)
}
val (variableIndex, constOffset) = ctx.env.evalVariableAndConstantSubParts(index)
val effectiveBase = (p.value + constOffset).quickSimplify
variableIndex match {
@ -428,7 +539,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case Some(ix) => List(MLine.absolute(LDX, v.addr), MLine.indexedX(STB, ix * v.elementType.size))
case _ =>
v.indexType.size match {
case 1 =>
case 1 | 2 =>
stashBIfNeeded(ctx,
compileToD(ctx, index) :+ MLine(LEAX, DAccumulatorIndexed(M6809Register.X, indirect = false), Constant.Zero)) :+
MLine.indexedX(STB, Constant.Zero)
@ -448,7 +559,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
val variable = ctx.env.get[Variable](name)
List(MLine.variable(ctx, STD, variable))
case DerefExpression(inner, offset, _) =>
compileToX(ctx, inner) :+ MLine(STD, Indexed(M6809Register.X, indirect = false), NumericConstant(offset, 2))
stashDIfNeeded(ctx, compileToX(ctx, inner)) :+ MLine(STD, Indexed(M6809Register.X, indirect = false), NumericConstant(offset, 2))
}
}
@ -475,6 +586,28 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case MExpressionTarget.U => List(MLine.tfr(M6809Register.D, M6809Register.U))
}
def compileAddressToX(ctx: CompilationContext, expr: LhsExpression): List[MLine] = {
expr match {
case VariableExpression(name) =>
val variable = ctx.env.get[VariableInMemory](name)
List(MLine.immediate(MOpcode.LDX, variable.toAddress))
case DerefExpression(inner, offset, _) =>
compileToX(ctx, inner) :+ MLine.indexedX(MOpcode.LEAX, Constant(offset))
case IndexedExpression(aname, index) =>
ctx.env.getPointy(aname) match {
case p: VariablePointy => compileToD(ctx, index #*# p.elementType.size) ++ List(MLine.absolute(ADDD, p.addr), MLine.tfr(M6809Register.D, M6809Register.X))
case p: ConstantPointy =>
if (p.sizeInBytes.exists(_ < 255)) {
compileToB(ctx, index #*# p.elementType.size) ++ List(MLine.immediate(LDX, p.value), MLine.inherent(ABX))
} else {
compileToX(ctx, index #*# p.elementType.size) :+ MLine.indexedX(LEAX, p.value)
}
case p:StackVariablePointy => compileToD(ctx, index #*# p.elementType.size) ++ List(MLine.variablestack(ctx, ADDD, p.offset), MLine.tfr(M6809Register.D, M6809Register.X))
}
case _ => ???
}
}
private def compileTransitiveRelation(ctx: CompilationContext,
operator: String,

View File

@ -20,6 +20,7 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
case ReturnStatement(Some(e)) =>
// TODO: clean stack
// TODO: RTI
AbstractExpressionCompiler.checkAssignmentType(ctx, e, ctx.function.returnType)
val rts = List(MLine.inherent(RTS))
val eval = ctx.function.returnType match {
case FatBooleanType =>
@ -42,7 +43,9 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
???
}
case Assignment(destination, source) =>
AbstractExpressionCompiler.getExpressionType(ctx, destination).size match {
val destinationType = AbstractExpressionCompiler.getExpressionType(ctx, destination)
AbstractExpressionCompiler.checkAssignmentType(ctx, source, destinationType)
destinationType.size match {
case 1 => (M6809ExpressionCompiler.compileToB(ctx, source) ++ M6809ExpressionCompiler.storeB(ctx, destination)) -> Nil
case 2 => (M6809ExpressionCompiler.compileToD(ctx, source) ++ M6809ExpressionCompiler.storeD(ctx, destination)) -> Nil
}
@ -68,7 +71,8 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
}
case _ =>
println(statement)
???
ctx.log.error("Not implemented yet", statement.position)
Nil -> Nil
}
code._1.map(_.positionIfEmpty(statement.position)) -> code._2.map(_.positionIfEmpty(statement.position))
}

View File

@ -44,6 +44,8 @@ sealed trait Expression extends Node {
case SumExpression(params, false) => SumExpression((false -> this) :: params, decimal = false)
case _ => SumExpression(List(false -> this, false -> that), decimal = false)
}
def #*#(smallInt: Int): Expression =
if (smallInt == 1) this else FunctionCallExpression("*", List(this, LiteralExpression(smallInt, 1).pos(this.position))).pos(this.position)
def #-#(smallInt: Int): Expression = (this #-# LiteralExpression(smallInt, 1).pos(this.position)).pos(this.position)
def #-#(that: Expression): Expression = SumExpression(List(false -> this, true -> that), decimal = false)

View File

@ -211,7 +211,7 @@ class M6809Assembler(program: Program,
index + 4
case _ =>
// TODO
throw new IllegalArgumentException("Not supported: " + instr)
throw new IllegalArgumentException("Not supported: " + instr + " " + instr.productIterator.mkString("/"))
}
}

View File

@ -468,7 +468,11 @@ class ArraySuite extends FunSuite with Matchers with AppendedClues {
"""
| array(word) a[7] @$c000
| void main () {
| // the 6809 backend is apparently too smart right now and this actually works!:
| a[0] += 2
| #if ARCH_6809
| a[0]*'a[1]
| #endif
| }
""".stripMargin)
}

View File

@ -1,7 +1,7 @@
package millfork.test
import millfork.Cpu
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun, EmuUnoptimizedRun}
import millfork.test.emu.{EmuCrossPlatformBenchmarkRun, EmuUnoptimizedCrossPlatformRun, EmuUnoptimizedRun, ShouldNotCompile}
import org.scalatest.{FunSuite, Matchers}
/**
@ -366,6 +366,29 @@ class ByteDecimalMathSuite extends FunSuite with Matchers {
}
}
test("Decimal multiplication by non-constant") {
ShouldNotCompile(
"""
| volatile byte x
| void main() {
| byte tmp
| tmp = 3
| tmp *'= x
| }
|""".stripMargin)
}
test("Decimal multiplication of two variables") {
ShouldNotCompile(
"""
| volatile byte x
| void main() {
| byte tmp
| tmp = x *' x
| }
|""".stripMargin)
}
test("Decimal comparison") {
// CMP#0 shouldn't be elided after a decimal operation.
// Currently no emulator used for testing can catch that.

View File

@ -10,7 +10,7 @@ import org.scalatest.{AppendedClues, FunSuite, Matchers}
class FunctionPointerSuite extends FunSuite with Matchers with AppendedClues{
test("Function pointers 1") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Motorola6809)(
"""
|
| byte output @$c000
@ -100,7 +100,7 @@ class FunctionPointerSuite extends FunSuite with Matchers with AppendedClues{
}
test("Function pointers 3") {
EmuUnoptimizedCrossPlatformRun (Cpu.Mos, Cpu.Z80)(
EmuUnoptimizedCrossPlatformRun (Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
"""
| const byte COUNT = 128
| array(word) output0[COUNT] @$c000
@ -117,7 +117,7 @@ class FunctionPointerSuite extends FunSuite with Matchers with AppendedClues{
|
""".stripMargin) { m =>
for (i <- 0 until 0x80) {
m.readByte(0xc000 + i * 2) should equal(i) withClue ("id " + i)
m.readWord(0xc000 + i * 2) should equal(i) withClue ("id " + i)
}
}
}

View File

@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
class NonetSuite extends FunSuite with Matchers {
test("Nonet operations") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
"""
| array output [5] @$c000
| void main () {
@ -45,7 +45,7 @@ class NonetSuite extends FunSuite with Matchers {
}
test("Nonet left shift") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
"""
| word output0 @$c000
| word output1 @$c002
@ -119,7 +119,7 @@ class NonetSuite extends FunSuite with Matchers {
}
test("Nonet shift right") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086)(
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086, Cpu.Motorola6809)(
"""
| byte output0 @$c000
| byte output1 @$c002
@ -141,7 +141,7 @@ class NonetSuite extends FunSuite with Matchers {
}
test("Nonet shift right 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086)(
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086, Cpu.Motorola6809)(
"""
| byte output0 @$c000
| byte output1 @$c002

View File

@ -9,7 +9,7 @@ import org.scalatest.{FunSuite, Matchers}
class ShiftSuite extends FunSuite with Matchers {
test("In-place shifting") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| array output [3] @$c000
| void main () {
| output[0] = 1
@ -20,7 +20,7 @@ class ShiftSuite extends FunSuite with Matchers {
}
test("Byte shifting") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| byte output @$c000
| void main () {
| byte a
@ -31,7 +31,7 @@ class ShiftSuite extends FunSuite with Matchers {
}
test("Word shifting") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| byte a
@ -70,7 +70,7 @@ class ShiftSuite extends FunSuite with Matchers {
}
test("Word shifting via pseudoregister") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = identity(three() << 7)
@ -81,7 +81,7 @@ class ShiftSuite extends FunSuite with Matchers {
}
test("Word shifting via pseudoregister 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos/*, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086*/)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| word w

View File

@ -9,7 +9,7 @@ import org.scalatest.{AppendedClues, FunSuite, Matchers}
class WordMathSuite extends FunSuite with Matchers with AppendedClues {
test("Word addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word a
| void main () {
@ -21,7 +21,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Cast word addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| byte output @$c000
| word a
| void main () {
@ -34,7 +34,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word subtraction") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word a
| void main () {
@ -46,7 +46,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word subtraction 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word a
| void main () {
@ -58,7 +58,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word subtraction 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Cmos, Cpu.Z80, Cpu.Intel8080, Cpu.Intel8085, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word a
| void main () {
@ -73,7 +73,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Byte-to-word addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word pair
| void main () {
@ -86,7 +86,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Literal addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = 640
@ -96,7 +96,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Array element addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| word pair
| array b[2]
@ -113,7 +113,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("nesdev.com example") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| byte output @$c000
| byte tile @$C3A6
| array map [256] @$c300
@ -135,7 +135,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("nesdev.com example 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| byte output @$c000
| byte tile @$C3A6
| array map [256] @$c300
@ -153,7 +153,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("hi()/lo()") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| array output [7] @$c000
| void main () {
| output[0] = lo(33)
@ -185,7 +185,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word addition 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| word v
@ -201,7 +201,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word addition 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| byte c
@ -217,7 +217,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word addition 4") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| word v
@ -254,7 +254,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word bit ops 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| word v
@ -270,7 +270,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word shift") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| word v
@ -288,7 +288,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word shift 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = five()
@ -303,7 +303,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word shift 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = five()
@ -318,7 +318,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word shift 4") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = five()
@ -333,7 +333,7 @@ class WordMathSuite extends FunSuite with Matchers with AppendedClues {
}
test("Word shift 5") {
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Sixteen, Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| word output @$c000
| void main () {
| output = five()

View File

@ -100,7 +100,7 @@ class EmuM6809Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizat
log.verbosity = 999
var effectiveSource = source
if (!source.contains("_panic")) effectiveSource += "\n void _panic(){while(true){}}"
// if (source.contains("call(")) effectiveSource += "\nnoinline asm word call(word d) {\n\n}\n"
if (source.contains("call(")) effectiveSource += "\nnoinline asm word call(word d) {\nJMP ,X\n}\n"
log.setSource(Some(effectiveSource.linesIterator.toIndexedSeq))
val PreprocessingResult(preprocessedSource, features, _) = Preprocessor.preprocessForTest(options, effectiveSource)
val parserF = M6809Parser("", preprocessedSource, "", options, features)

View File

@ -8,7 +8,7 @@ import millfork.compiler.{CompilationContext, LabelGenerator}
import millfork.compiler.mos.MosCompiler
import millfork.env.{Environment, InitializedArray, InitializedMemoryVariable, NormalFunction}
import millfork.node.StandardCallGraph
import millfork.parser.{MosParser, PreprocessingResult, Preprocessor, Z80Parser}
import millfork.parser.{M6809Parser, MosParser, PreprocessingResult, Preprocessor, Z80Parser}
import millfork._
import millfork.compiler.m6809.M6809Compiler
import millfork.compiler.z80.Z80Compiler
@ -23,6 +23,7 @@ object ShouldNotCompile extends Matchers {
def apply(source: String): Unit = {
checkCase(Cpu.Mos, source)
checkCase(Cpu.Z80, source)
checkCase(Cpu.Motorola6809, source)
}
private def checkCase(cpu: Cpu.Value, source: String) {
@ -40,6 +41,8 @@ object ShouldNotCompile extends Matchers {
platform.cpuFamily match {
case CpuFamily.M6502 =>
effectiveSource += "\nnoinline asm word call(word ax) {\nJMP ((__reg.b2b3))\n}\n"
case CpuFamily.M6809 =>
effectiveSource += "\nnoinline asm word call(word d) {\nJMP ,x\n}\n"
case CpuFamily.I80 =>
if (options.flag(CompilationFlag.UseIntelSyntaxForInput))
effectiveSource += "\nnoinline asm word call(word de) {\npush d\nret\n}\n"
@ -54,6 +57,8 @@ object ShouldNotCompile extends Matchers {
platform.cpuFamily match {
case CpuFamily.M6502 =>
MosParser("", preprocessedSource, "", options, features)
case CpuFamily.M6809 =>
M6809Parser("", preprocessedSource, "", options, features)
case CpuFamily.I80 =>
Z80Parser("", preprocessedSource, "", options, features, options.flag(CompilationFlag.UseIntelSyntaxForInput))
}