1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-25 19:29:49 +00:00

Improvements to constant evaluation

This commit is contained in:
Karol Stasiak 2020-03-25 23:50:06 +01:00
parent 2a566af3da
commit 475496c137
5 changed files with 39 additions and 11 deletions

View File

@ -32,6 +32,8 @@
* Minor improvements to inline assembly.
* Improvements to constant evaluation.
* Optimization improvements.
## 0.3.14

View File

@ -14,7 +14,8 @@ import millfork.output.NoAlignment
*/
object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
def compileConstant(ctx: CompilationContext, expr: Constant, exprType: Type, target: Variable): List[AssemblyLine] = {
def compileConstant(ctx: CompilationContext, expr0: Constant, exprType: Type, target: Variable): List[AssemblyLine] = {
val expr = expr0.fitInto(exprType, target.typ)
target match {
case RegisterVariable(MosRegister.A, _) => List(AssemblyLine(LDA, Immediate, expr))
case RegisterVariable(MosRegister.AW, _) =>

View File

@ -1,7 +1,7 @@
package millfork.env
import millfork.DecimalUtils._
import millfork.node.ResolvedFieldDesc
import millfork.node.{ResolvedFieldDesc, SumExpression}
import millfork.output.DivisibleAlignment
object Constant {
@ -79,17 +79,19 @@ sealed trait Constant {
def subword(index: Int): Constant = {
if (requiredSize <= index) Constant.Zero
else if (requiredSize == 2 && !this.isInstanceOf[StructureConstant]) this
else {
// TODO: check if ok
CompoundConstant(MathOperator.Or, CompoundConstant(MathOperator.Shl, subbyte(index + 1), NumericConstant(8, 1)), subbyte(index)).quickSimplify
CompoundConstant(MathOperator.Or, CompoundConstant(MathOperator.Shl, subbyte(index + 1), NumericConstant(8, 2)), subbyte(index)).quickSimplify
}
}
def subwordReversed(index: Int): Constant = {
if (requiredSize <= index) Constant.Zero
else if (requiredSize == 2 && !this.isInstanceOf[StructureConstant]) this
else {
// TODO: check if ok
CompoundConstant(MathOperator.Or, CompoundConstant(MathOperator.Shl, subbyte(index), NumericConstant(8, 1)), subbyte(index + 1)).quickSimplify
CompoundConstant(MathOperator.Or, CompoundConstant(MathOperator.Shl, subbyte(index), NumericConstant(8, 2)), subbyte(index + 1)).quickSimplify
}
}
@ -126,6 +128,10 @@ sealed trait Constant {
case NumericConstant(value, 1) =>
if (typ.isSigned) NumericConstant(value.toByte, 1)
else NumericConstant(value & 0xff, 1)
case CompoundConstant(MathOperator.Minus, NumericConstant(l, _), NumericConstant(r, _)) =>
val value = l - r
if (typ.isSigned) NumericConstant(value.toByte, 1)
else NumericConstant(value & 0xff, 1)
case b => b
}
case 2 =>
@ -133,12 +139,26 @@ sealed trait Constant {
case NumericConstant(value, _) =>
if (typ.isSigned) NumericConstant(value.toShort, 2)
else NumericConstant(value & 0xffff, 2)
case CompoundConstant(MathOperator.Minus, NumericConstant(l, _), NumericConstant(r, _)) =>
val value = l - r
if (typ.isSigned) NumericConstant(value.toShort, 2)
else NumericConstant(value & 0xffff, 2)
case w => w
}
case _ => this
}
}
def fitInto(sourceType: Type, targetType: Type): Constant = {
val fit0 = fitInto(sourceType)
if (sourceType.size >= targetType.size) fit0 else {
fit0 match {
case NumericConstant(n, _) => NumericConstant(n, targetType.size)
case _ => fit0
}
}
}
final def succ: Constant = (this + 1).quickSimplify
def rootThingName: String

View File

@ -140,11 +140,16 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
else ???
case SubbyteConstant(cc, i) => deepConstResolve(cc).>>>(i * 8).&(0xff)
case s: StructureConstant =>
s.typ.size match {
case 0 => 0
case 1 => deepConstResolve(s.subbyte(0))
case 2 => if (platform.isBigEndian) deepConstResolve(s.subwordReversed(0)) else deepConstResolve(s.subword(0)) // TODO: endianness?
case _ => ???
try {
s.typ.size match {
case 0 => 0
case 1 => deepConstResolve(s.subbyte(0))
case 2 => if (platform.isBigEndian) deepConstResolve(s.subwordReversed(0)) else deepConstResolve(s.subword(0)) // TODO: endianness?
case _ => ???
}
} catch {
case _: StackOverflowError =>
log.fatal("Stack overflow " + c)
}
case CompoundConstant(operator, lc, rc) =>
val l = deepConstResolve(lc)

View File

@ -92,7 +92,7 @@ class StructSuite extends FunSuite with Matchers {
}
test("Optimize struct modifications") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086, Cpu.Motorola6809)("""
| struct point { byte x, byte y }
| enum direction { none, right }
| direction last_direction @$c400
@ -116,7 +116,7 @@ class StructSuite extends FunSuite with Matchers {
}
test("Struct literals") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086)("""
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8086, Cpu.Motorola6809)("""
| struct point { byte x, byte y }
| const point origin = point(1,2)
| noinline point move_right(point p) {