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

6809: Improved support for large types

This commit is contained in:
Karol Stasiak 2020-06-18 20:29:31 +02:00
parent 88b2bbd434
commit b387ece71d
10 changed files with 401 additions and 64 deletions

View File

@ -38,6 +38,8 @@ object MLine {
def tfr(source: M6809Register.Value, target: M6809Register.Value): MLine = MLine(TFR, TwoRegisters(source, target), Constant.Zero) def tfr(source: M6809Register.Value, target: M6809Register.Value): MLine = MLine(TFR, TwoRegisters(source, target), Constant.Zero)
def exg(source: M6809Register.Value, target: M6809Register.Value): MLine = MLine(EXG, TwoRegisters(source, target), Constant.Zero)
def pp(opcode: MOpcode.Value, registers: M6809Register.Value*): MLine = MLine(opcode, RegisterSet(registers.toSet), Constant.Zero) def pp(opcode: MOpcode.Value, registers: M6809Register.Value*): MLine = MLine(opcode, RegisterSet(registers.toSet), Constant.Zero)
def indexedS(opcode: MOpcode.Value, offset: Int = 0): MLine = def indexedS(opcode: MOpcode.Value, offset: Int = 0): MLine =
@ -79,12 +81,12 @@ object MLine {
def variable(ctx: CompilationContext, opcode : MOpcode.Value, variable: Variable, offset: Int = 0): MLine = { def variable(ctx: CompilationContext, opcode : MOpcode.Value, variable: Variable, offset: Int = 0): MLine = {
variable match { variable match {
case v: VariableInMemory => MLine.absolute(opcode, v.toAddress) case v: VariableInMemory => MLine.absolute(opcode, v.toAddress + offset)
case v: StackVariable => case v: StackVariable =>
val size = variable.typ.size val size = variable.typ.size
if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset, size)) if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset + offset, size))
else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset, size)) else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset + offset, size))
else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset, size)) else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset + offset, size))
case _ => ??? case _ => ???
} }
} }
@ -177,9 +179,9 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
case (EXG, TwoRegisters(r1, r2)) => overlaps(r1) || overlaps(r2) case (EXG, TwoRegisters(r1, r2)) => overlaps(r1) || overlaps(r2)
case (op, _) if MOpcode.ChangesAAlways(op) => overlaps(A) || addrMode.changesRegister(reg) case (op, _) if MOpcode.ChangesAAlways(op) => overlaps(A) || addrMode.changesRegister(reg)
case (op, _) if MOpcode.ChangesBAlways(op) => overlaps(B) || addrMode.changesRegister(reg) case (op, _) if MOpcode.ChangesBAlways(op) => overlaps(B) || addrMode.changesRegister(reg)
case (LDA, _) => overlaps(A) || addrMode.changesRegister(reg) case (LDA | ANDA | ADDA | ADCA | SUBA | SBCA | EORA | ORA | BITA, _) => overlaps(A) || addrMode.changesRegister(reg)
case (LDB, _) => overlaps(B) || addrMode.changesRegister(reg) case (LDB | ANDB | ADDB | ADCB | SUBB | SBCB | EORB | ORB | BITB, _) => overlaps(B) || addrMode.changesRegister(reg)
case (LDD, _) => overlaps(D) || addrMode.changesRegister(reg) case (LDD | ADDD | SUBD, _) => overlaps(D) || addrMode.changesRegister(reg)
case (LDU | LEAU, _) => reg == U || addrMode.changesRegister(reg) case (LDU | LEAU, _) => reg == U || addrMode.changesRegister(reg)
case (LDS | LEAS, _) => reg == S || addrMode.changesRegister(reg) case (LDS | LEAS, _) => reg == S || addrMode.changesRegister(reg)
case (LDX | LEAX, _) => reg == X || addrMode.changesRegister(reg) case (LDX | LEAX, _) => reg == X || addrMode.changesRegister(reg)
@ -187,10 +189,17 @@ case class MLine(opcode: MOpcode.Value, addrMode: MAddrMode, parameter: Constant
case (MUL, _) => overlaps(D) case (MUL, _) => overlaps(D)
case (ABX, _) => reg == X case (ABX, _) => reg == X
case (NOP | SWI | SWI2 | SWI3 | SYNC, _) => false case (NOP | SWI | SWI2 | SWI3 | SYNC, _) => false
case _ => true // TODO case (STA | STB | STD | STS | STU | STX | STY, _) => false
case (SEX | DAA, _) => overlaps(A)
case (JSR | SWI | SWI2 | SWI3, _) => true
case _ => addrMode.changesRegister(reg)
} }
} }
def changesCarryFlag: Boolean = !MOpcode.PreservesC(opcode)
def readsRegister(reg: M6809Register.Value): Boolean = { def readsRegister(reg: M6809Register.Value): Boolean = {
import M6809Register._ import M6809Register._
def overlaps(other: M6809Register.Value): Boolean = { def overlaps(other: M6809Register.Value): Boolean = {

View File

@ -46,7 +46,6 @@ object MOpcode extends Enumeration {
val ChangesAAlways: Set[MOpcode.Value] = Set(ADDA, ADCA, SUBA, SBCA, ANDA, ORA, EORA, SEX, DAA) val ChangesAAlways: Set[MOpcode.Value] = Set(ADDA, ADCA, SUBA, SBCA, ANDA, ORA, EORA, SEX, DAA)
val ChangesBAlways: Set[MOpcode.Value] = Set(ADDB, ADCB, SUBB, SBCB, ANDB, ORB, EORB) val ChangesBAlways: Set[MOpcode.Value] = Set(ADDB, ADCB, SUBB, SBCB, ANDB, ORB, EORB)
val ChangesDAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB) val ChangesDAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
val ChangesCFAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
val ReadsAAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB) val ReadsAAlways: Set[MOpcode.Value] = Set(ADDD, SUBD, ANDB, ORB, EORB)
val AccessesWordInMemory: Set[MOpcode.Value] = Set(ADDD, SUBD, LDD, STD, LDX, LDY, LDU, LDS, STX, STY, STU, STS, CMPD, CMPX, CMPY, CMPU, CMPS) val AccessesWordInMemory: Set[MOpcode.Value] = Set(ADDD, SUBD, LDD, STD, LDX, LDY, LDU, LDS, STX, STY, STU, STS, CMPD, CMPX, CMPY, CMPU, CMPS)
val AllLinear: Set[MOpcode.Value] = Set( val AllLinear: Set[MOpcode.Value] = Set(
@ -78,6 +77,15 @@ object MOpcode extends Enumeration {
CMPA, CMPB, CMPD, CMPX, CMPY, CMPU, CMPS, CMPA, CMPB, CMPD, CMPX, CMPY, CMPU, CMPS,
MUL, MUL,
) )
val PreservesC: Set[MOpcode.Value] = Set(
ANDA, ANDB, BITA, BITB, DEC, EXG, INC,
LDA, LDB, LDD, LDX, LDY, LDU, LDS,
LEAS, LEAX, LEAY, LEAU,
NOP, ORA, ORB,
PSHS, PSHU, PULS, PULU,
STA, STB, STD, STX, STY, STS, STU,
TFR, TST
)
// The following are incomplete: // The following are incomplete:
val ChangesN: Set[MOpcode.Value] = Set( val ChangesN: Set[MOpcode.Value] = Set(
CWAI, ORCC, ANDCC, CWAI, ORCC, ANDCC,

View File

@ -1,11 +1,13 @@
package millfork.compiler.m6809 package millfork.compiler.m6809
import java.util.concurrent.AbstractExecutorService
import millfork.CompilationFlag import millfork.CompilationFlag
import millfork.assembly.m6809.{DAccumulatorIndexed, Immediate, Indexed, InherentB, MLine, MLine0, MOpcode, RegisterSet, TwoRegisters} import millfork.assembly.m6809.{DAccumulatorIndexed, Immediate, Indexed, InherentB, MLine, MLine0, MOpcode, RegisterSet, TwoRegisters}
import millfork.compiler.{AbstractExpressionCompiler, BranchIfFalse, BranchIfTrue, BranchSpec, ComparisonType, CompilationContext, NoBranching} import millfork.compiler.{AbstractExpressionCompiler, BranchIfFalse, BranchIfTrue, BranchSpec, ComparisonType, CompilationContext, NoBranching}
import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SeparateBytesExpression, SumExpression, VariableExpression} import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SeparateBytesExpression, SumExpression, VariableExpression}
import millfork.assembly.m6809.MOpcode._ import millfork.assembly.m6809.MOpcode._
import millfork.env.{AssemblyOrMacroParamSignature, BuiltInBooleanType, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FlagBooleanType, FunctionInMemory, FunctionPointerType, Label, M6809RegisterVariable, MacroFunction, MathOperator, MemoryAddressConstant, MemoryVariable, NonFatalCompilationException, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, ThingInMemory, Type, Variable, VariableInMemory, VariablePointy} import millfork.env.{AssemblyOrMacroParamSignature, BuiltInBooleanType, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, FlagBooleanType, FunctionInMemory, FunctionPointerType, Label, M6809RegisterVariable, MacroFunction, MathOperator, MemoryAddressConstant, MemoryVariable, NonFatalCompilationException, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, StructureConstant, ThingInMemory, Type, Variable, VariableInMemory, VariablePointy}
import scala.collection.GenTraversableOnce import scala.collection.GenTraversableOnce
@ -357,7 +359,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
size match { size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ADDB) case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ADDB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true) case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ADDD, commutative = true)
case _ => ctx.log.error("Long addition not implemented yet", fce.position); Nil case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ADDB)
} }
case "+'=" => case "+'=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@ -372,15 +374,14 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case (true, false) => lc ++ rc ++ add case (true, false) => lc ++ rc ++ add
case (true, true) => rc ++ stashAIfNeeded(ctx, lc) ++ add case (true, true) => rc ++ stashAIfNeeded(ctx, lc) ++ add
} }
case 2 => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ADDA)
case _ => ???
} }
case "-=" => case "-=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
size match { size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, SUBB) case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, SUBB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false) case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, SUBD, commutative = false)
case _ => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, SUBB)
} }
case "-'=" => case "-'=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@ -390,8 +391,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
val rc = compileToB(ctx, r) val rc = compileToB(ctx, r)
lc ++ List(MLine.pp(PSHS, M6809Register.B)) ++ lc ++ List(MLine.pp(PSHS, M6809Register.B)) ++
rc ++ List(MLine.pp(PSHS, M6809Register.B), MLine.immediate(LDA, 0x9a), MLine.accessAndPullS(SUBA), MLine.accessAndPullS(ADDA), MLine.inherent(DAA), MLine.indexedX(STA, 0)) rc ++ List(MLine.pp(PSHS, M6809Register.B), MLine.immediate(LDA, 0x9a), MLine.accessAndPullS(SUBA), MLine.accessAndPullS(ADDA), MLine.inherent(DAA), MLine.indexedX(STA, 0))
case 2 => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, SUBA)
case _ => ???
} }
case "*=" => case "*=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@ -417,21 +417,21 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
size match { size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ANDB) case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ANDB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ANDA, ANDB, commutative = true) case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ANDA, ANDB, commutative = true)
case _ => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ANDB)
} }
case "|=" => case "|=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
size match { size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ORB) case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ORB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ORA, ORB, commutative = true) case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ORA, ORB, commutative = true)
case _ => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, ORB)
} }
case "^=" => case "^=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
size match { size match {
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, EORB) case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, EORB)
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, EORA, EORB, commutative = true) case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, EORA, EORB, commutative = true)
case _ => ??? case _ => M6809LargeBuiltins.modifyInPlaceViaX(ctx, l, r, EORB)
} }
case "<<=" => case "<<=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@ -441,6 +441,8 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = true)) handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = true))
case 2 => case 2 =>
handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true)) handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true))
case _ =>
M6809LargeBuiltins.compileShiftInPlace(ctx, size, l, r, left = true)
} }
case "<<'=" => case "<<'=" =>
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params) val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
@ -455,6 +457,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
size match { size match {
case 1 => handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = false)) case 1 => handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = false))
case 2 => handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = false)) case 2 => handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = false))
case _ => M6809LargeBuiltins.compileShiftInPlace(ctx, size, l, r, left = false)
} }
case ">>'=" => ??? case ">>'=" => ???
case ">>>>=" => ??? case ">>>>=" => ???
@ -499,7 +502,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
case 2 => case 2 =>
compileToD(ctx, paramExpr) ++ storeD(callCtx, VariableExpression(paramVar.name + "`aa")) compileToD(ctx, paramExpr) ++ storeD(callCtx, VariableExpression(paramVar.name + "`aa"))
case _ => case _ =>
??? M6809LargeBuiltins.storeLarge(callCtx, VariableExpression(paramVar.name + "`aa"), paramExpr)
} }
} }
case AssemblyOrMacroParamSignature(signature) => case AssemblyOrMacroParamSignature(signature) =>
@ -647,6 +650,11 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
else lines else lines
} }
def stashCarryIfNeeded(ctx: CompilationContext, lines: List[MLine]): List[MLine] = {
if (lines.exists(_.changesCarryFlag)) MLine.pp(PSHS, M6809Register.CC) :: (lines :+ MLine.pp(PULS, M6809Register.CC))
else lines
}
def storeA(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashAIfNeeded, STA) def storeA(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashAIfNeeded, STA)
def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashBIfNeeded, STB) def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = store8(ctx, target, stashBIfNeeded, STB)
@ -839,4 +847,74 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
} }
false false
} }
def compileToByteReads(ctx: CompilationContext, source: Expression, targetSize: Int): List[List[MLine]] = {
val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, source)
ctx.env.eval(source) match {
case Some(const) =>
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyteBe(targetSize - 1 - i, targetSize))))
case None =>
sourceType.size match {
case 0 => ???
case 1 =>
List.tabulate(targetSize)(i =>
if (sourceType.isSigned) {
if (i == 0) compileToB(ctx, source) :+ MLine.tfr(M6809Register.B, M6809Register.A)
else if (i == 1) List(
MLine.tfr(M6809Register.A, M6809Register.B),
MLine.inherent(SEX),
MLine.tfr(M6809Register.B, M6809Register.A)
)
else List(MLine.tfr(M6809Register.A, M6809Register.B))
} else {
if (i == 0) compileToB(ctx, source)
else List(MLine.immediate(LDB, 0))
}
)
case 2 =>
List.tabulate(targetSize)(i =>
if (sourceType.isSigned) {
if (i == 0) compileToD(ctx, source)
else if (i == 1) List(MLine.tfr(M6809Register.A, M6809Register.B))
else if (i == 2) {
if (targetSize > 3) List(
MLine.tfr(M6809Register.A, M6809Register.B),
MLine.inherent(SEX),
MLine.tfr(M6809Register.B, M6809Register.A)
) else List(
MLine.tfr(M6809Register.A, M6809Register.B),
MLine.inherent(SEX)
)
} else List(MLine.tfr(M6809Register.A, M6809Register.B))
} else {
if (i == 0) compileToD(ctx, source)
else if (i == 1) List(MLine.tfr(M6809Register.A, M6809Register.B))
else List(MLine.immediate(LDB, 0))
}
)
case _ =>
source match {
case LiteralExpression(value, size) =>
val const = NumericConstant(value, size)
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyte(i))))
case GeneratedConstantExpression(const, _) =>
List.tabulate(targetSize)(i => List(MLine.immediate(LDB, const.subbyteBe(targetSize - 1 - i, targetSize))))
case VariableExpression(name) =>
val v = ctx.env.get[Variable](name)
List.tabulate(targetSize)(i => List(if (i < v.typ.size) MLine.variable(ctx, LDB, v, v.typ.size - 1 - i) else MLine.immediate(LDB, 0)))
case e:FunctionCallExpression =>
ctx.env.maybeGet[NormalFunction](e.functionName) match {
case Some(function) =>
val load = M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING)
val v = ctx.env.get[VariableInMemory](function.name + ".return")
List.tabulate(targetSize) { i =>
if (i == 0) load :+ MLine.variable(ctx, LDB, v, v.typ.size - 1 - i)
else List(if (i < v.typ.size) MLine.variable(ctx, LDB, v, v.typ.size - 1 - i) else MLine.immediate(LDB, 0))
}
case _ => ???
}
}
}
}
}
} }

View File

@ -0,0 +1,238 @@
package millfork.compiler.m6809
import millfork.assembly.m6809.{Immediate, MLine, MLine0, MOpcode, TwoRegisters}
import millfork.compiler.{AbstractExpressionCompiler, CompilationContext}
import millfork.node.{Expression, LhsExpression, M6809Register}
import millfork.assembly.m6809.MOpcode._
import millfork.env.{Constant, NumericConstant}
import scala.collection.GenTraversableOnce
import scala.collection.mutable.ListBuffer
/**
* @author Karol Stasiak
*/
object M6809LargeBuiltins {
def compileShiftInPlace(ctx: CompilationContext, size: Int, target: LhsExpression, shiftValue: Expression, left: Boolean): List[MLine] = {
val (targetAddr, targetInit): (Option[Constant], List[MLine]) = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr) -> Nil
case xs => None -> xs
}
val oneShift = if (left) {
targetAddr match {
case Some(addr) =>
List.tabulate(size)(i => MLine.absolute(if (i == 0) ASL else ROL, addr + (size - 1 - i)))
case None =>
List.tabulate(size)(i => MLine.indexedX(if (i == 0) ASL else ROL, size - 1 - i))
}
} else {
targetAddr match {
case Some(addr) =>
List.tabulate(size)(i => MLine.absolute(if (i == 0) LSR else ROR, addr + i))
case None =>
List.tabulate(size)(i => MLine.indexedX(if (i == 0) LSR else ROR, i))
}
}
targetInit ++ (M6809ExpressionCompiler.compileToB(ctx, shiftValue) match {
case List(MLine0(LDB, Immediate, NumericConstant(n, _))) if n >= 0 && (n - 1) * size < 4 =>
List.fill(n.toInt)(oneShift).flatten
case xs@List(MLine0(LDB, Immediate, c)) if c.isProvablyGreaterOrEqualThan(1) =>
val label = ctx.nextLabel("sr")
xs ++ List(MLine.label(label)) ++ oneShift ++ List(MLine.inherentB(DEC), MLine.shortBranch(BNE, label))
case xs =>
val loop = ctx.nextLabel("sr")
val skip = ctx.nextLabel("ss")
M6809ExpressionCompiler.stashXIfNeeded(ctx, xs) ++ List(
MLine.label(loop),
MLine.inherentB(DEC),
MLine.immediate(CMPB, -1),
MLine.shortBranch(BEQ, skip)) ++ oneShift ++ List(
MLine.shortBranch(BRA, loop),
MLine.label(skip)
)
})
}
def storeLarge(ctx: CompilationContext, target: LhsExpression, source: Expression): List[MLine] = {
val byteCount = AbstractExpressionCompiler.getExpressionType(ctx, target).size
val byteLoads = M6809ExpressionCompiler.compileToByteReads(ctx, source, byteCount)
val (targetAddr, targetInit): (Option[Constant], List[MLine]) = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr) -> Nil
case xs => None -> xs
}
// TODO: use loop for very large structures
// TODO: use D to speed up certain loads
targetInit ++ byteLoads.zipWithIndex.flatMap{ case (loadByte, ix) =>
M6809ExpressionCompiler.stashXIfNeeded(ctx, loadByte) :+ ( targetAddr match {
case Some(addr) => MLine.absolute(STB, addr + (byteCount - 1 - ix))
case None => MLine.indexedX(STB, byteCount - 1 - ix)
} )
}
}
def convertToLda(ldb: List[MLine]): List[MLine] = {
ldb match {
case List(l@MLine0(LDB, _, _)) => List(l.copy(opcode = LDA))
case List(l@MLine0(TFR, TwoRegisters(M6809Register.A, M6809Register.B), _)) => List(l.copy(addrMode = TwoRegisters(M6809Register.B, M6809Register.A)))
case _ => MLine.exg(M6809Register.A, M6809Register.B) :: (ldb :+ MLine.exg(M6809Register.A, M6809Register.B))
}
}
def compileInc(ctx: CompilationContext, target: LhsExpression): List[MLine] = {
val sizeInBytes = AbstractExpressionCompiler.getExpressionType(ctx, target).size
val result = new ListBuffer[MLine]()
val targetAddr: Option[Constant] = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr)
case xs =>
result ++= xs
None
}
val skipLabel = ctx.nextLabel("in")
for (i <- 0 until sizeInBytes) {
targetAddr match {
case Some(addr) =>
result += MLine.absolute(INC, addr + (sizeInBytes - 1 - i))
case None =>
result += MLine.indexedX(INC, sizeInBytes - 1 - i)
}
if (i != sizeInBytes - 1) {
result += MLine.shortBranch(BNE, skipLabel)
}
}
result += MLine.label(skipLabel)
result.toList
}
def modifyInPlaceViaX(ctx: CompilationContext, target: LhsExpression, argument: Expression, opcode: MOpcode.Value): List[MLine] = {
if (opcode == ADDB) ctx.env.eval(argument) match {
case Some(NumericConstant(1, _)) =>
return compileInc(ctx, target)
case _ =>
}
val sizeInBytes = AbstractExpressionCompiler.getExpressionType(ctx, target).size
val byteLoads = M6809ExpressionCompiler.compileToByteReads(ctx, argument, sizeInBytes)
val result = new ListBuffer[MLine]()
val targetAddr: Option[Constant] = M6809ExpressionCompiler.compileAddressToX(ctx, target) match {
case List(MLine(LDX, Immediate, addr, _, _)) => Some(addr)
case xs =>
result ++= xs
ctx.log.error("Invalid left-hand-side expression", target.position)
None
}
var firstNonzeroByte = 0
for (i <- 0 until sizeInBytes) {
val ldb = byteLoads(i)
val magicConstant =
ldb match {
case List(MLine0(LDB, Immediate, NumericConstant(x, _))) => Some(x.toInt & 0xff)
case _ => None
}
(opcode, magicConstant) match {
case (ORB | EORB, Some(0)) =>
// nothing
case (ANDB, Some(0xff)) =>
// nothing
case (EORB, Some(0xff)) =>
targetAddr match {
case Some(addr) =>
result += MLine.absolute(COM, addr + (sizeInBytes - 1 - i))
case None =>
result += MLine.indexedX(COM, sizeInBytes - 1 - i)
}
case (ADDB | SUBB | ADDA | SUBA, Some(0)) if i == firstNonzeroByte =>
firstNonzeroByte = i + 1
case (SUBA, _) => ???
case (ADDA, _) if i == firstNonzeroByte =>
val lda = convertToLda(ldb)
targetAddr match {
case Some(addr) =>
result ++= lda
result += MLine.absolute(ADCA, addr + (sizeInBytes - 1 - i))
result += MLine.inherent(DAA)
result += MLine.absolute(STA, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, lda)
result += MLine.indexedX(ADCA, sizeInBytes - 1 - i)
result += MLine.inherent(DAA)
result += MLine.indexedX(STA, sizeInBytes - 1 - i)
}
case (ADDA, _) if i != firstNonzeroByte =>
val lda = convertToLda(ldb)
targetAddr match {
case Some(addr) =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, lda)
result += MLine.absolute(ADCA, addr + (sizeInBytes - 1 - i))
result += MLine.inherent(DAA)
result += MLine.absolute(STA, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, lda))
result += MLine.indexedX(ADCA, sizeInBytes - 1 - i)
result += MLine.inherent(DAA)
result += MLine.indexedX(STA, sizeInBytes - 1 - i)
}
case (SUBB, _) if i == firstNonzeroByte =>
targetAddr match {
case Some(addr) =>
result ++= ldb
result += MLine.pp(PSHS, M6809Register.B)
result += MLine.absolute(LDB, addr + (sizeInBytes - 1 - i))
result += MLine.accessAndPullS(SUBB)
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb)
result += MLine.pp(PSHS, M6809Register.B)
result += MLine.indexedX(LDB, sizeInBytes - 1 - i)
result += MLine.accessAndPullS(SUBB)
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
}
case (SUBB, _) if i != firstNonzeroByte =>
targetAddr match {
case Some(addr) =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, ldb)
result += MLine.pp(PSHS, M6809Register.B)
result += MLine.absolute(LDB, addr + (sizeInBytes - 1 - i))
result += MLine.accessAndPullS(SBCB)
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb))
result += MLine.pp(PSHS, M6809Register.B)
result += MLine.indexedX(LDB, sizeInBytes - 1 - i)
result += MLine.accessAndPullS(SBCB)
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
}
case (ADDB, _) if i != firstNonzeroByte =>
targetAddr match {
case Some(addr) =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, ldb)
result += MLine.absolute(ADCB, addr + (sizeInBytes - 1 - i))
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashCarryIfNeeded(ctx, M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb))
result += MLine.indexedX(ADCB, sizeInBytes - 1 - i)
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
}
case _ =>
targetAddr match {
case Some(addr) =>
result ++= ldb
result += MLine.absolute(opcode, addr + (sizeInBytes - 1 - i))
result += MLine.absolute(STB, addr + (sizeInBytes - 1 - i))
case None =>
result ++= M6809ExpressionCompiler.stashXIfNeeded(ctx, ldb)
result += MLine.indexedX(opcode, sizeInBytes - 1 - i)
result += MLine.indexedX(STB, sizeInBytes - 1 - i)
}
}
}
result.toList
}
}

View File

@ -33,6 +33,12 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING) M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING)
case 1 => M6809ExpressionCompiler.compileToB(ctx, e) case 1 => M6809ExpressionCompiler.compileToB(ctx, e)
case 2 => M6809ExpressionCompiler.compileToD(ctx, e) case 2 => M6809ExpressionCompiler.compileToD(ctx, e)
case _ =>
if (ctx.function.hasElidedReturnVariable) {
Nil
} else {
M6809LargeBuiltins.storeLarge(ctx, VariableExpression(ctx.function.name + ".return"), e)
}
} }
} }
(eval ++ rts) -> Nil (eval ++ rts) -> Nil
@ -65,6 +71,7 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] {
case _ => M6809ExpressionCompiler.compileToB(ctx, source) ++ M6809ExpressionCompiler.storeB(ctx, destination) case _ => M6809ExpressionCompiler.compileToB(ctx, source) ++ M6809ExpressionCompiler.storeB(ctx, destination)
} }
case 2 => M6809ExpressionCompiler.compileToD(ctx, source) ++ M6809ExpressionCompiler.storeD(ctx, destination) case 2 => M6809ExpressionCompiler.compileToD(ctx, source) ++ M6809ExpressionCompiler.storeD(ctx, destination)
case _ => M6809LargeBuiltins.storeLarge(ctx, destination, source)
}) -> Nil }) -> Nil
case ExpressionStatement(expression) => case ExpressionStatement(expression) =>
M6809ExpressionCompiler.compile(ctx, expression, MExpressionTarget.NOTHING) -> Nil M6809ExpressionCompiler.compile(ctx, expression, MExpressionTarget.NOTHING) -> Nil

View File

@ -34,6 +34,10 @@ class MemoryBank(val index: Int, val isBigEndian: Boolean) {
if (isBigEndian) readByte(addr + 3) + (readByte(addr + 2) << 8) + (readByte(addr + 1) << 16) + (readByte(addr) << 24) if (isBigEndian) readByte(addr + 3) + (readByte(addr + 2) << 8) + (readByte(addr + 1) << 16) + (readByte(addr) << 24)
else readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + (readByte(addr + 3) << 24) else readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + (readByte(addr + 3) << 24)
def readLongLong(addr: Int): Long =
if (isBigEndian) readLong(addr).toLong.<<(32) + readLong(addr + 4).&(1L.<<(32).-(1))
else readLong(addr + 4).toLong.<<(32) + readLong(addr).&(1L.<<(32).-(1))
def readWord(addrHi: Int, addrLo: Int): Int = readByte(addrLo) + (readByte(addrHi) << 8) def readWord(addrHi: Int, addrLo: Int): Int = readByte(addrLo) + (readByte(addrHi) << 8)
val output: Array[Byte] = Array.fill[Byte](1 << 16)(0) val output: Array[Byte] = Array.fill[Byte](1 << 16)(0)

View File

@ -10,7 +10,7 @@ import org.scalatest.{FunSuite, Matchers}
class FarwordTest extends FunSuite with Matchers { class FarwordTest extends FunSuite with Matchers {
test("Int24 assignment") { test("Int24 assignment") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output3 @$c000 | int24 output3 @$c000
| int24 output2 @$c004 | int24 output2 @$c004
@ -29,7 +29,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 assignment 2") { test("Int24 assignment 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)(
""" """
| int24 output3 @$c000 | int24 output3 @$c000
| int24 output2 @$c004 | int24 output2 @$c004
@ -48,12 +48,12 @@ class FarwordTest extends FunSuite with Matchers {
""".stripMargin) { m => """.stripMargin) { m =>
m.readMedium(0xc000) should equal(0x23344) m.readMedium(0xc000) should equal(0x23344)
m.readMedium(0xc004) should equal(0x7788) m.readMedium(0xc004) should equal(0x7788)
m.readMedium(0xc008) should equal(0x55) m.readWord(0xc008) should equal(0x55)
} }
} }
test("Int24 assignment 3") { test("Int24 assignment 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output0 @$c000 | int24 output0 @$c000
| int24 output1 @$c003 | int24 output1 @$c003
@ -70,7 +70,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 addition") { test("Int24 addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -90,7 +90,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 addition 2") { test("Int24 addition 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)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -104,7 +104,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 subtraction") { test("Int24 subtraction") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -124,7 +124,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 subtraction 2") { test("Int24 subtraction 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)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -138,7 +138,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
} }
test("Int24 subtraction 3") { test("Int24 subtraction 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -158,7 +158,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
test("Int24 AND") { test("Int24 AND") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output @$c000 | int24 output @$c000
| void main () { | void main () {
@ -178,7 +178,7 @@ class FarwordTest extends FunSuite with Matchers {
} }
test("Int24 INC/DEC") { test("Int24 INC/DEC") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int24 output0 @$c000 | int24 output0 @$c000
| int24 output1 @$c004 | int24 output1 @$c004

View File

@ -28,7 +28,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Long assignment") { test("Long assignment") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output4 @$c000 | long output4 @$c000
| long output2 @$c004 | long output2 @$c004
@ -47,7 +47,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long assignment 2") { test("Long assignment 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)(
""" """
| long output4 @$c000 | long output4 @$c000
| long output2 @$c004 | long output2 @$c004
@ -66,11 +66,11 @@ class LongTest extends FunSuite with Matchers {
""".stripMargin) { m => """.stripMargin) { m =>
m.readLong(0xc000) should equal(0x11223344) m.readLong(0xc000) should equal(0x11223344)
m.readLong(0xc004) should equal(0x7788) m.readLong(0xc004) should equal(0x7788)
m.readLong(0xc008) should equal(0x55) m.readWord(0xc008) should equal(0x55)
} }
} }
test("Long addition") { test("Long addition") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -90,7 +90,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long addition 2") { test("Long addition 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)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -104,7 +104,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long addition 3") { test("Long addition 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -138,7 +138,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long subtraction") { test("Long subtraction") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -158,7 +158,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long subtraction 2") { test("Long subtraction 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)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -172,7 +172,7 @@ class LongTest extends FunSuite with Matchers {
} }
} }
test("Long subtraction 3") { test("Long subtraction 3") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -192,7 +192,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Long AND") { test("Long AND") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -212,7 +212,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Long INC/DEC") { test("Long INC/DEC") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output0 @$c000 | long output0 @$c000
| long output1 @$c004 | long output1 @$c004
@ -252,7 +252,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Returning long") { test("Returning long") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output @$c000 | long output @$c000
| void main () { | void main () {
@ -267,7 +267,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Various combinations involving promotions") { test("Various combinations involving promotions") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| long output0 @$c000 | long output0 @$c000
| long output1 @$c004 | long output1 @$c004
@ -329,7 +329,7 @@ class LongTest extends FunSuite with Matchers {
} }
test("Larger than long") { test("Larger than long") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)( EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)(
""" """
| int64 output0 @$c000 | int64 output0 @$c000
| int64 output1 @$c008 | int64 output1 @$c008
@ -364,18 +364,11 @@ class LongTest extends FunSuite with Matchers {
| return param | return param
| } | }
""".stripMargin) { m => """.stripMargin) { m =>
m.readLong(0xc000) should equal(0x91929394) m.readLongLong(0xc000) should equal(0x91929394L)
m.readLong(0xc008) should equal(0x929394) m.readLongLong(0xc008) should equal(0x929394L)
m.readLong(0xc010) should equal(0x9394) m.readLongLong(0xc010) should equal(0x9394L)
m.readLong(0xc018) should equal(0x94) m.readLongLong(0xc018) should equal(0x94L)
m.readLongLong(0xc020) should equal(0x0101010191929394L)
m.readLong(0xc004) should equal(0)
m.readLong(0xc00c) should equal(0)
m.readLong(0xc014) should equal(0)
m.readLong(0xc01c) should equal(0)
m.readLong(0xc020) should equal(0x91929394)
m.readLong(0xc024) should equal(0x01010101)
} }
} }
} }

View File

@ -33,7 +33,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
""".stripMargin){m => m.readWord(0xc000) should equal(0xfffe)} """.stripMargin){m => m.readWord(0xc000) should equal(0xfffe)}
} }
test("Sbyte to Long") { test("Sbyte to Long") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(""" EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| long output @$c000 | long output @$c000
| void main () { | void main () {
| output = 421 | output = 421
@ -46,7 +46,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
} }
test("Optimize pointless sign extension") { test("Optimize pointless sign extension") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086)(""" EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp, Cpu.Intel8086, Cpu.Motorola6809)("""
| array output [10] @$c000 | array output [10] @$c000
| word w | word w
| void main () { | void main () {
@ -66,7 +66,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
| return 5 | return 5
| } | }
""".stripMargin){m => """.stripMargin){m =>
m.readWord(0xc000) should equal(440) m.readWord(0xc001, 0xc000) should equal(440)
} }
} }
@ -111,7 +111,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
} }
test("Check multilayered conversions of signed and unsigned types") { test("Check multilayered conversions of signed and unsigned types") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)( EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
""" """
|long output @$c000 |long output @$c000
|noinline sbyte f() = $FE |noinline sbyte f() = $FE
@ -140,7 +140,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
} }
test("Signed16 to int32 extension") { test("Signed16 to int32 extension") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)( EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
""" """
|int32 output @$c000 |int32 output @$c000
| |
@ -156,7 +156,7 @@ class SignExtensionSuite extends FunSuite with Matchers {
} }
test("Signed16 to int32 extension 2") { test("Signed16 to int32 extension 2") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80)( EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(
""" """
|int32 output @$c000 |int32 output @$c000
| |

View File

@ -50,7 +50,7 @@ object Settings {
/** /**
* Should the Motorola 6809 tests be enabled? * Should the Motorola 6809 tests be enabled?
* Motorola 6809 emulation is not yet implemented, so keep this false for the time being. * Motorola 6809 emulation is currently under development and more and more tests are ran against it.
*/ */
val enableMotorola6809Tests: Boolean = true val enableMotorola6809Tests: Boolean = true