mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-10 05:29:49 +00:00
Improvements to constant evaluation
This commit is contained in:
parent
2a566af3da
commit
475496c137
@ -32,6 +32,8 @@
|
||||
|
||||
* Minor improvements to inline assembly.
|
||||
|
||||
* Improvements to constant evaluation.
|
||||
|
||||
* Optimization improvements.
|
||||
|
||||
## 0.3.14
|
||||
|
@ -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, _) =>
|
||||
|
26
src/main/scala/millfork/env/Constant.scala
vendored
26
src/main/scala/millfork/env/Constant.scala
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user