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

Removal of the <<<< operator; nonet operation improvements

Use `nonet(a << b)` instead of `a <<<< b`
This commit is contained in:
Karol Stasiak 2018-03-16 00:34:24 +01:00
parent 9680423691
commit 516d7eae26
8 changed files with 40 additions and 30 deletions

View File

@ -227,17 +227,6 @@ object BuiltIns {
}
}
@deprecated
def compileNonetLeftShift(ctx: CompilationContext, lhs: Expression, rhs: Expression): List[AssemblyLine] = {
val label = MfCompiler.nextLabel("sh")
compileShiftOps(ASL, ctx, lhs, rhs) ++ List(
AssemblyLine.immediate(LDX, 0),
AssemblyLine.relative(BCC, label),
AssemblyLine.implied(INX),
AssemblyLine.label(label)
)
}
def compileInPlaceByteShiftOps(opcode: Opcode.Value, ctx: CompilationContext, lhs: LhsExpression, rhs: Expression): List[AssemblyLine] = {
val env = ctx.env
val b = env.get[Type]("byte")

View File

@ -62,7 +62,6 @@ object ExpressionCompiler {
case FunctionCallExpression("<<'", params) => b
case FunctionCallExpression(">>'", params) => b
case FunctionCallExpression(">>>>", params) => b
case FunctionCallExpression("<<<<", params) => w
case FunctionCallExpression("&&", params) => bool
case FunctionCallExpression("||", params) => bool
case FunctionCallExpression("^^", params) => bool
@ -832,7 +831,7 @@ object ExpressionCompiler {
if (addends.size > 2) {
ErrorReporting.warn("Nonet addition works correctly only for two operands", ctx.options, expr.position)
}
case FunctionCallExpression("+" | "+'" | "<<" | "<<<<" | "<<'" | "nonet", _) => // ok
case FunctionCallExpression("+" | "+'" | "<<" | "<<'" | "nonet", _) => // ok
case _ =>
ErrorReporting.warn("Unspecified nonet operation, results might be unpredictable", ctx.options, expr.position)
}
@ -895,11 +894,6 @@ object ExpressionCompiler {
case v: LhsExpression =>
BuiltIns.compileNonetOps(ctx, v, r)
}
case "<<<<" =>
ErrorReporting.warn("`x <<<< y` is obsolete, use `nonet(x << y)`", ctx.options, expr.position)
assertAllBytes("Long shift ops not supported", ctx, params)
val (l, r, 1) = assertBinary(ctx, params)
BuiltIns.compileNonetLeftShift(ctx, l, r)
case "<<" =>
val (l, r, size) = assertBinary(ctx, params)
size match {

View File

@ -150,8 +150,8 @@ case class SubbyteConstant(base: Constant, index: Int) extends Constant {
}
object MathOperator extends Enumeration {
val Plus, Minus, Times, Shl, Shr, Shl9, Shr9,
DecimalPlus, DecimalMinus, DecimalTimes, DecimalShl, DecimalShr,
val Plus, Minus, Times, Shl, Shr, Shl9, Shr9, Plus9, DecimalPlus9,
DecimalPlus, DecimalMinus, DecimalTimes, DecimalShl, DecimalShl9, DecimalShr,
And, Or, Exor = Value
}
@ -170,6 +170,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
case MathOperator.Shl => lv << rv
case MathOperator.Shr => lv >> rv
case MathOperator.Shl9 => (lv << rv) & 0x1ff
case MathOperator.Plus9 => (lv + rv) & 0x1ff
case MathOperator.Shr9 => (lv & 0x1ff) >> rv
case MathOperator.Exor => lv ^ rv
case MathOperator.Or => lv | rv
@ -177,6 +178,8 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
case _ => return this
}
operator match {
case MathOperator.Plus9 | MathOperator.DecimalPlus9 =>
size = 2
case MathOperator.Times | MathOperator.Shl =>
val mask = (1 << (size * 8)) - 1
if (value != (value & mask)){
@ -188,6 +191,9 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
case (NumericConstant(0, 1), c) =>
operator match {
case MathOperator.Plus => c
case MathOperator.Plus9 => c
case MathOperator.DecimalPlus => c
case MathOperator.DecimalPlus9 => c
case MathOperator.Minus => CompoundConstant(operator, l, r)
case MathOperator.Times => Constant.Zero
case MathOperator.Shl => Constant.Zero
@ -202,6 +208,9 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
case (c, NumericConstant(0, 1)) =>
operator match {
case MathOperator.Plus => c
case MathOperator.Plus9 => c
case MathOperator.DecimalPlus => c
case MathOperator.DecimalPlus9 => c
case MathOperator.Minus => c
case MathOperator.Times => Constant.Zero
case MathOperator.Shl => c
@ -259,16 +268,19 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
override def toString: String = {
operator match {
case Plus => f"$plhs + $prhs"
case Plus9 => f"nonet($plhs + $prhs)"
case Minus => f"$plhs - $prhs"
case Times => f"$plhs * $prhs"
case Shl => f"$plhs << $prhs"
case Shr => f"$plhs >> $prhs"
case Shl9 => f"$plhs <<<< $prhs"
case Shl9 => f"nonet($plhs << $prhs)"
case Shr9 => f"$plhs >>>> $prhs"
case DecimalPlus => f"$plhs +' $prhs"
case DecimalPlus9 => f"nonet($plhs +' $prhs)"
case DecimalMinus => f"$plhs -' $prhs"
case DecimalTimes => f"$plhs *' $prhs"
case DecimalShl => f"$plhs <<' $prhs"
case DecimalShl9 => f"nonet($plhs <<' $prhs)"
case DecimalShr => f"$plhs >>' $prhs"
case And => f"$plhs & $prhs"
case Or => f"$plhs | $prhs"

View File

@ -278,7 +278,7 @@ class Environment(val parent: Option[Environment], val prefix: String) {
"<<" | ">>" |
"<<'" | ">>'" |
"&" | "|" | "^" |
">>>>" | "<<<<" |
">>>>" |
"*" | "*'", _)) => variable -> constant
case Some(FunctionCallExpression(fname, _)) =>
maybeGet[Thing](fname) match {
@ -332,6 +332,19 @@ class Environment(val parent: Option[Environment], val prefix: String) {
} yield hc.asl(8) + lc
case FunctionCallExpression(name, params) =>
name match {
case "nonet" =>
params match {
case List(FunctionCallExpression("<<", ps@List(_, _))) =>
constantOperation(MathOperator.Shl9, ps)
case List(FunctionCallExpression("<<'", ps@List(_, _))) =>
constantOperation(MathOperator.DecimalShl9, ps)
case List(SumExpression(ps@List((true,_),(true,_)), false)) =>
constantOperation(MathOperator.Plus9, ps.map(_._2))
case List(SumExpression(ps@List((true,_),(true,_)), true)) =>
constantOperation(MathOperator.DecimalPlus9, ps.map(_._2))
case _ =>
None
}
case ">>'" =>
constantOperation(MathOperator.DecimalShr, params)
case "<<'" =>
@ -340,8 +353,6 @@ class Environment(val parent: Option[Environment], val prefix: String) {
constantOperation(MathOperator.Shr, params)
case "<<" =>
constantOperation(MathOperator.Shl, params)
case "<<<<" =>
constantOperation(MathOperator.Shl9, params)
case ">>>>" =>
constantOperation(MathOperator.Shr9, params)
case "*'" =>

View File

@ -99,14 +99,18 @@ class Assembler(private val program: Program, private val rootEnv: Environment,
val r = deepConstResolve(rc)
operator match {
case MathOperator.Plus => l + r
case MathOperator.Plus9 => (l + r) & 0x1ff
case MathOperator.Minus => l - r
case MathOperator.Times => l * r
case MathOperator.Shl => l << r
case MathOperator.Shl9 => (l << r) & 0x1ff
case MathOperator.Shr => l >>> r
case MathOperator.DecimalPlus => asDecimal(l, r, _ + _)
case MathOperator.DecimalPlus9 => asDecimal(l, r, _ + _) & 0x1ff
case MathOperator.DecimalMinus => asDecimal(l, r, _ - _)
case MathOperator.DecimalTimes => asDecimal(l, r, _ * _)
case MathOperator.DecimalShl => asDecimal(l, 1 << r, _ * _)
case MathOperator.DecimalShl9 => asDecimal(l, 1 << r, _ * _) & 0x1ff
case MathOperator.DecimalShr => asDecimal(l, 1 << r, _ / _)
case MathOperator.And => l & r
case MathOperator.Exor => l ^ r

View File

@ -130,7 +130,7 @@ case class MfParser(filename: String, input: String, currentDirectory: String, o
List("&&"),
List("==", "<=", ">=", "!=", "<", ">"),
List(":"),
List("+'", "-'", "<<'", ">>'", "<<<<", ">>>>", "+", "-", "&", "|", "^", "<<", ">>"),
List("+'", "-'", "<<'", ">>'", ">>>>", "+", "-", "&", "|", "^", "<<", ">>"),
List("*'", "*"))
val nonStatementLevel = 1 // everything but not `=`

View File

@ -310,7 +310,7 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
| byte source @$C002
| void main () {
| init()
| output += source <<<< 1
| output += nonet(source << 1)
| }
| void init() {
| output = 0

View File

@ -37,10 +37,10 @@ class NonetSuite extends FunSuite with Matchers {
| void main () {
| byte a
| a = 3
| output0 = a <<<< 1
| output1 = a <<<< 2
| output2 = a <<<< 6
| output3 = a <<<< 7
| output0 = nonet(a << 1)
| output1 = nonet(a << 2)
| output2 = nonet(a << 6)
| output3 = nonet(a << 7)
| }
""".stripMargin) { m =>
m.readWord(0xc000) should equal(0x06)