mirror of
https://github.com/KarolS/millfork.git
synced 2024-07-07 21:28:59 +00:00
6809: Implement more things
This commit is contained in:
parent
6cd639a23a
commit
f39fd67a89
@ -32,6 +32,10 @@ object MLine {
|
|||||||
|
|
||||||
def longBranch(opcode: MOpcode.Value, label: String): MLine = longBranch(opcode, Label(label))
|
def longBranch(opcode: MOpcode.Value, label: String): MLine = longBranch(opcode, Label(label))
|
||||||
|
|
||||||
|
def shortBranch(opcode: MOpcode.Value, label: Label): MLine = MLine(opcode, Relative, label.toAddress)
|
||||||
|
|
||||||
|
def shortBranch(opcode: MOpcode.Value, label: String): MLine = shortBranch(opcode, Label(label))
|
||||||
|
|
||||||
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 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)
|
||||||
@ -42,6 +46,9 @@ object MLine {
|
|||||||
def indexedX(opcode: MOpcode.Value, offset: Constant): MLine =
|
def indexedX(opcode: MOpcode.Value, offset: Constant): MLine =
|
||||||
MLine(opcode, Indexed(M6809Register.X, indirect = false), offset)
|
MLine(opcode, Indexed(M6809Register.X, indirect = false), offset)
|
||||||
|
|
||||||
|
def indexedX(opcode: MOpcode.Value, offset: Int): MLine =
|
||||||
|
MLine(opcode, Indexed(M6809Register.X, indirect = false), Constant(offset))
|
||||||
|
|
||||||
def accessAndPullS(opcode: MOpcode.Value): MLine =
|
def accessAndPullS(opcode: MOpcode.Value): MLine =
|
||||||
MLine(opcode, PostIncremented(M6809Register.S, 1, indirect = false), Constant.Zero)
|
MLine(opcode, PostIncremented(M6809Register.S, 1, indirect = false), Constant.Zero)
|
||||||
|
|
||||||
@ -74,9 +81,10 @@ object MLine {
|
|||||||
variable match {
|
variable match {
|
||||||
case v: VariableInMemory => MLine.absolute(opcode, v.toAddress)
|
case v: VariableInMemory => MLine.absolute(opcode, v.toAddress)
|
||||||
case v: StackVariable =>
|
case v: StackVariable =>
|
||||||
if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset, 1))
|
val size = variable.typ.size
|
||||||
else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset, 1))
|
if (ctx.options.flag(CompilationFlag.UseUForStack)) MLine(opcode, Indexed(M6809Register.U, indirect = false), NumericConstant(v.baseOffset, size))
|
||||||
else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset, 1))
|
else if (ctx.options.flag(CompilationFlag.UseYForStack)) MLine(opcode, Indexed(M6809Register.Y, indirect = false), NumericConstant(v.baseOffset, size))
|
||||||
|
else MLine(opcode, Indexed(M6809Register.S, indirect = false), NumericConstant(v.baseOffset + ctx.extraStackOffset, size))
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,28 @@ object M6809Buitins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def perform16BitInPlace(ctx: CompilationContext, l: LhsExpression, r: Expression, opcodeA: MOpcode.Value, opcodeB: 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), _)), _) =>
|
||||||
|
rc ++ List(ldl.copy(opcode = opcodeA), ldl.copy(opcode = opcodeB, parameter = ldl.parameter + 1), ldl.copy(opcode = STD))
|
||||||
|
case (_, List(ldr@MLine0(LDD, Absolute(false), _))) if lc.last.opcode == LDD =>
|
||||||
|
lc ++ List(ldr.copy(opcode = opcodeA), ldr.copy(opcode = opcodeB, parameter = ldr.parameter + 1), lc.last.copy(opcode = STD))
|
||||||
|
case (_, List(ldr@MLine0(LDD, Immediate, _))) if lc.last.opcode == LDD =>
|
||||||
|
lc ++ List(ldr.copy(opcode = opcodeA, parameter = ldr.parameter.hiByte), ldr.copy(opcode = opcodeB, parameter = ldr.parameter.loByte), 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.accessAndPullS(opcodeA), MLine.accessAndPullS(opcodeB), lc.last.copy(opcode = STD))
|
||||||
|
case _ if lc.last.opcode == LDD =>
|
||||||
|
// TODO: preserve X?
|
||||||
|
rc ++ List(MLine.pp(PSHS, M6809Register.D)) ++ lc ++ List(MLine.accessAndPullS(opcodeA), MLine.accessAndPullS(opcodeB), lc.last.copy(opcode = STD))
|
||||||
|
case _ =>
|
||||||
|
println(lc)
|
||||||
|
???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def split(ctx: CompilationContext, expr: SumExpression): (Constant, List[(Boolean, Expression)]) = {
|
def split(ctx: CompilationContext, expr: SumExpression): (Constant, List[(Boolean, Expression)]) = {
|
||||||
var constant = Constant.Zero
|
var constant = Constant.Zero
|
||||||
@ -283,7 +305,18 @@ object M6809Buitins {
|
|||||||
ctx.env.eval(rhs) match {
|
ctx.env.eval(rhs) match {
|
||||||
case Some(NumericConstant(0, _)) => Nil
|
case Some(NumericConstant(0, _)) => Nil
|
||||||
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(MLine.inherentB(op))
|
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(MLine.inherentB(op))
|
||||||
case _ => ???
|
case _ =>
|
||||||
|
val loop = ctx.nextLabel("sr")
|
||||||
|
val skip = ctx.nextLabel("ss")
|
||||||
|
M6809ExpressionCompiler.stashBIfNeeded(ctx, M6809ExpressionCompiler.compileToX(ctx, rhs)) ++ List(
|
||||||
|
MLine.label(loop),
|
||||||
|
MLine.indexedX(LEAX, -1),
|
||||||
|
MLine.immediate(CMPX, -1),
|
||||||
|
MLine.shortBranch(BEQ, skip),
|
||||||
|
MLine.inherentB(op),
|
||||||
|
MLine.shortBranch(BRA, loop),
|
||||||
|
MLine.label(skip)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,8 +324,21 @@ object M6809Buitins {
|
|||||||
val op = if (left) List(MLine.inherentB(ASL), MLine.inherentA(ROL)) else List(MLine.inherentA(LSR), MLine.inherentB(ROR))
|
val op = if (left) List(MLine.inherentB(ASL), MLine.inherentA(ROL)) else List(MLine.inherentA(LSR), MLine.inherentB(ROR))
|
||||||
ctx.env.eval(rhs) match {
|
ctx.env.eval(rhs) match {
|
||||||
case Some(NumericConstant(0, _)) => Nil
|
case Some(NumericConstant(0, _)) => Nil
|
||||||
|
case Some(NumericConstant(8, _)) =>
|
||||||
|
if (left) List(MLine.tfr(M6809Register.B, M6809Register.A), MLine.immediate(LDB, 0))
|
||||||
|
else List(MLine.tfr(M6809Register.A, M6809Register.B), MLine.immediate(LDA, 0))
|
||||||
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(op).flatten
|
case Some(NumericConstant(n, _)) => List.fill(n.toInt)(op).flatten
|
||||||
case _ => ???
|
case _ =>
|
||||||
|
val loop = ctx.nextLabel("sr")
|
||||||
|
val skip = ctx.nextLabel("ss")
|
||||||
|
M6809ExpressionCompiler.stashDIfNeeded(ctx, M6809ExpressionCompiler.compileToX(ctx, rhs)) ++ List(
|
||||||
|
MLine.label(loop),
|
||||||
|
MLine.indexedX(LEAX, -1),
|
||||||
|
MLine.immediate(CMPX, -1),
|
||||||
|
MLine.shortBranch(BEQ, skip))++op++List(
|
||||||
|
MLine.shortBranch(BRA, loop),
|
||||||
|
MLine.label(skip)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import millfork.assembly.m6809.MOpcode._
|
|||||||
object M6809Comparisons {
|
object M6809Comparisons {
|
||||||
|
|
||||||
def isTrivial(lc: List[MLine]): Boolean = lc match {
|
def isTrivial(lc: List[MLine]): Boolean = lc match {
|
||||||
case List(MLine0(LDB, _, _)) => true
|
case List(MLine0(LDB | LDD, _, _)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ object M6809Comparisons {
|
|||||||
case ComparisonType.GreaterOrEqualUnsigned => BCC
|
case ComparisonType.GreaterOrEqualUnsigned => BCC
|
||||||
case ComparisonType.LessUnsigned => BCS
|
case ComparisonType.LessUnsigned => BCS
|
||||||
case ComparisonType.GreaterUnsigned => BHI
|
case ComparisonType.GreaterUnsigned => BHI
|
||||||
case ComparisonType.LessOrEqualSigned => BLS
|
case ComparisonType.LessOrEqualUnsigned => BLS
|
||||||
case ComparisonType.GreaterSigned => BGT
|
case ComparisonType.GreaterSigned => BGT
|
||||||
case ComparisonType.GreaterOrEqualSigned => BGE
|
case ComparisonType.GreaterOrEqualSigned => BGE
|
||||||
case ComparisonType.LessSigned => BLT
|
case ComparisonType.LessSigned => BLT
|
||||||
@ -45,4 +45,34 @@ object M6809Comparisons {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def compile16BitComparison(ctx: CompilationContext, comparisonType: ComparisonType.Value, l: Expression, r: Expression, branches: BranchSpec): scala.List[MLine] = {
|
||||||
|
val jump = branches match {
|
||||||
|
case BranchIfFalse(label) => return compile16BitComparison(ctx, ComparisonType.negate(comparisonType), l, r, branches.flip)
|
||||||
|
case BranchIfTrue(label) => List(MLine.longBranch(
|
||||||
|
comparisonType match {
|
||||||
|
case ComparisonType.Equal => BEQ
|
||||||
|
case ComparisonType.NotEqual => BNE
|
||||||
|
case ComparisonType.GreaterOrEqualUnsigned => BCC
|
||||||
|
case ComparisonType.LessUnsigned => BCS
|
||||||
|
case ComparisonType.GreaterUnsigned => BHI
|
||||||
|
case ComparisonType.LessOrEqualUnsigned => BLS
|
||||||
|
case ComparisonType.GreaterSigned => BGT
|
||||||
|
case ComparisonType.GreaterOrEqualSigned => BGE
|
||||||
|
case ComparisonType.LessSigned => BLT
|
||||||
|
case ComparisonType.LessOrEqualSigned => BLE
|
||||||
|
},
|
||||||
|
label
|
||||||
|
))
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
val lc = M6809ExpressionCompiler.compileToD(ctx, l)
|
||||||
|
val rc = M6809ExpressionCompiler.compileToD(ctx, r)
|
||||||
|
if (isTrivial(lc) && !isTrivial(rc)) return compile16BitComparison(ctx, ComparisonType.flip(comparisonType), r, l, branches)
|
||||||
|
if (isTrivial(rc)) {
|
||||||
|
lc ++ rc.map(_.copy(opcode = CMPD)) ++ jump
|
||||||
|
} else {
|
||||||
|
rc ++ List(MLine.pp(PSHS, M6809Register.D)) ++ lc ++ List(MLine.accessAndPullSTwice(CMPD)) ++ jump
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package millfork.compiler.m6809
|
package millfork.compiler.m6809
|
||||||
|
|
||||||
import millfork.assembly.m6809.{DAccumulatorIndexed, Indexed, MLine, MOpcode, TwoRegisters}
|
import millfork.assembly.m6809.{DAccumulatorIndexed, Immediate, Indexed, MLine, MLine0, MOpcode, 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, SumExpression, VariableExpression}
|
import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SumExpression, VariableExpression}
|
||||||
import millfork.assembly.m6809.MOpcode._
|
import millfork.assembly.m6809.MOpcode._
|
||||||
@ -252,7 +252,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, "==", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, "==", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.Equal, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.Equal, l, r, branches)
|
||||||
case 2 => ctx.log.error("Word equality comparison not implemented yet", fce.position); Nil
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, ComparisonType.Equal, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, "!=", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, "!=", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.NotEqual, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, ComparisonType.NotEqual, l, r, branches)
|
||||||
case 2 => ctx.log.error("Word inequality comparison not implemented yet", fce.position); Nil
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, ComparisonType.NotEqual, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -270,6 +270,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, "<", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, "<", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.LessSigned else ComparisonType.LessUnsigned, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.LessSigned else ComparisonType.LessUnsigned, l, r, branches)
|
||||||
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, if (signed) ComparisonType.LessSigned else ComparisonType.LessUnsigned, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,6 +279,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, ">", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, ">", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.GreaterSigned else ComparisonType.GreaterUnsigned, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.GreaterSigned else ComparisonType.GreaterUnsigned, l, r, branches)
|
||||||
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, if (signed) ComparisonType.GreaterSigned else ComparisonType.GreaterUnsigned, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,6 +288,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, "<=", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, "<=", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.LessOrEqualSigned else ComparisonType.LessOrEqualUnsigned, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.LessOrEqualSigned else ComparisonType.LessOrEqualUnsigned, l, r, branches)
|
||||||
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, if (signed) ComparisonType.LessOrEqualSigned else ComparisonType.LessOrEqualUnsigned, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,6 +297,7 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
compileTransitiveRelation(ctx, ">=", params, target, branches) { (l, r) =>
|
compileTransitiveRelation(ctx, ">=", params, target, branches) { (l, r) =>
|
||||||
size match {
|
size match {
|
||||||
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.GreaterOrEqualSigned else ComparisonType.GreaterOrEqualUnsigned, l, r, branches)
|
case 1 => M6809Comparisons.compile8BitComparison(ctx, if (signed) ComparisonType.GreaterOrEqualSigned else ComparisonType.GreaterOrEqualUnsigned, l, r, branches)
|
||||||
|
case 2 => M6809Comparisons.compile16BitComparison(ctx, if (signed) ComparisonType.GreaterOrEqualSigned else ComparisonType.GreaterOrEqualUnsigned, l, r, branches)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,13 +306,13 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
case 1 => compileToB(ctx, params(0)) ++ M6809Buitins.compileByteShiftForB(ctx, params(1), left = true) ++ targetifyB(ctx, target, isSigned = false)
|
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 2 => compileToD(ctx, params(0)) ++ M6809Buitins.compileWordShiftForD(ctx, params(1), left = true) ++ targetifyD(ctx, target)
|
||||||
}
|
}
|
||||||
case ">>" => ???
|
case ">>" =>
|
||||||
getArithmeticParamMaxSize(ctx, params) match {
|
getArithmeticParamMaxSize(ctx, params) match {
|
||||||
case 1 => compileToB(ctx, params(0)) ++ M6809Buitins.compileByteShiftForB(ctx, params(1), left = false) ++ targetifyB(ctx, target, isSigned = false)
|
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 2 => compileToD(ctx, params(0)) ++ M6809Buitins.compileWordShiftForD(ctx, params(1), left = false) ++ targetifyD(ctx, target)
|
||||||
}
|
}
|
||||||
case ">>>>" =>
|
case ">>>>" =>
|
||||||
// TODO: this words, but is really suboptimal
|
// TODO: this works, but is really suboptimal
|
||||||
getArithmeticParamMaxSize(ctx, params) match {
|
getArithmeticParamMaxSize(ctx, params) match {
|
||||||
case 1 | 2 => compileToD(ctx, params(0)) ++
|
case 1 | 2 => compileToD(ctx, params(0)) ++
|
||||||
List(MLine.immediate(ANDA, 1)) ++
|
List(MLine.immediate(ANDA, 1)) ++
|
||||||
@ -341,46 +345,39 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
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, ANDB)
|
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ANDB)
|
||||||
|
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ANDB, commutative = true)
|
||||||
case _ => ???
|
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, ORB)
|
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, ORB)
|
||||||
|
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, ORB, commutative = true)
|
||||||
case _ => ???
|
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, EORB)
|
case 1 => M6809Buitins.perform8BitInPlace(ctx, l, r, EORB)
|
||||||
|
case 2 => M6809Buitins.perform16BitInPlace(ctx, l, r, EORB, commutative = true)
|
||||||
case _ => ???
|
case _ => ???
|
||||||
}
|
}
|
||||||
case "<<=" =>
|
case "<<=" =>
|
||||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||||
// TODO: optimize shifts directly in memory
|
// TODO: optimize shifts directly in memory
|
||||||
size match {
|
size match {
|
||||||
case 1 => compileAddressToX(ctx, l) ++
|
case 1 =>
|
||||||
List(MLine.indexedX(LDB, Constant.Zero)) ++
|
handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = true))
|
||||||
M6809Buitins.compileByteShiftForB(ctx, r, left = true) ++
|
case 2 =>
|
||||||
List(MLine.indexedX(STB, Constant.Zero))
|
handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = true))
|
||||||
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 ">>=" =>
|
case ">>=" =>
|
||||||
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
val (l, r, size) = assertArithmeticAssignmentLike(ctx, params)
|
||||||
// TODO: optimize shifts directly in memory
|
// TODO: optimize shifts directly in memory
|
||||||
size match {
|
size match {
|
||||||
case 1 => compileAddressToX(ctx, l) ++
|
case 1 => handleInPlaceModification(ctx, l, 1, M6809Buitins.compileByteShiftForB(ctx, r, left = false))
|
||||||
List(MLine.indexedX(LDB, Constant.Zero)) ++
|
case 2 => handleInPlaceModification(ctx, l, 2, M6809Buitins.compileWordShiftForD(ctx, r, left = false))
|
||||||
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 ">>>>=" => ???
|
case ">>>>=" => ???
|
||||||
@ -547,6 +544,11 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
else lines
|
else lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def stashXIfNeeded(ctx: CompilationContext, lines: List[MLine]): List[MLine] = {
|
||||||
|
if (lines.exists(_.changesRegister(M6809Register.X))) MLine.pp(PSHS, M6809Register.X) :: (lines :+ MLine.pp(PULS, M6809Register.X))
|
||||||
|
else lines
|
||||||
|
}
|
||||||
|
|
||||||
def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = {
|
def storeB(ctx: CompilationContext, target: LhsExpression): List[MLine] = {
|
||||||
target match {
|
target match {
|
||||||
case VariableExpression(name) =>
|
case VariableExpression(name) =>
|
||||||
@ -642,6 +644,29 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handleInPlaceModification(ctx: CompilationContext, l: LhsExpression, size: Int, r: List[MLine]): List[MLine] = {
|
||||||
|
compileAddressToX(ctx, l) match {
|
||||||
|
case List(MLine0(LDX, Immediate, addr)) =>
|
||||||
|
size match {
|
||||||
|
case 1 => List(MLine.absolute(LDB, addr)) ++ r ++ List(MLine.absolute(STB, addr))
|
||||||
|
case 2 => List(MLine.absolute(LDD, addr)) ++ r ++ List(MLine.absolute(STD, addr))
|
||||||
|
}
|
||||||
|
case lc =>
|
||||||
|
size match {
|
||||||
|
case 1 =>
|
||||||
|
lc ++
|
||||||
|
List(MLine.indexedX(LDB, Constant.Zero)) ++
|
||||||
|
stashXIfNeeded(ctx, r) ++
|
||||||
|
List(MLine.indexedX(STB, Constant.Zero))
|
||||||
|
case 2 =>
|
||||||
|
lc ++
|
||||||
|
List(MLine.indexedX(LDD, Constant.Zero)) ++
|
||||||
|
stashXIfNeeded(ctx, r) ++
|
||||||
|
List(MLine.indexedX(LDD, Constant.Zero))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private def compileTransitiveRelation(ctx: CompilationContext,
|
private def compileTransitiveRelation(ctx: CompilationContext,
|
||||||
operator: String,
|
operator: String,
|
||||||
|
Loading…
Reference in New Issue
Block a user