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

Z80: Faster array indexing

This commit is contained in:
Karol Stasiak 2018-08-08 17:50:27 +02:00
parent 8b09941cef
commit 019547aae8
4 changed files with 26 additions and 16 deletions

View File

@ -9,6 +9,7 @@ import millfork.compiler._
import millfork.env._
import millfork.error.ConsoleLogger
import millfork.node.{MosRegister, _}
import millfork.output.NoAlignment
/**
* @author Karol Stasiak
*/
@ -180,7 +181,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
val reg = ctx.env.get[VariableInMemory]("__reg")
val compileIndex = compile(ctx, indexExpression, Some(MosExpressionCompiler.getExpressionType(ctx, indexExpression) -> RegisterVariable(MosRegister.YA, w)), BranchSpec.None)
val prepareRegister = pointy match {
case ConstantPointy(addr, _, _, _, _) =>
case ConstantPointy(addr, _, _, _, _, _) =>
List(
AssemblyLine.implied(CLC),
AssemblyLine.immediate(ADC, addr.hiByte),
@ -295,7 +296,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
wrapWordIndexingStorage(prepareWordIndexing(ctx, p, indexExpr))
case (p: ConstantPointy, Some(v), 2, _) =>
val w = env.get[VariableType]("word")
wrapWordIndexingStorage(prepareWordIndexing(ctx, ConstantPointy(p.value + constIndex, None, if (constIndex.isProvablyZero) p.size else None, w, p.elementType), v))
wrapWordIndexingStorage(prepareWordIndexing(ctx, ConstantPointy(p.value + constIndex, None, if (constIndex.isProvablyZero) p.size else None, w, p.elementType, NoAlignment), v))
case (p: ConstantPointy, Some(v), 1, _) =>
storeToArrayAtUnknownIndex(v, p.value)
//TODO: should there be a type check or a zeropage check?
@ -614,7 +615,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
None,
if (constantIndex.isProvablyZero) a.size else None,
env.get[VariableType]("word"),
a.elementType), v) ++ loadFromReg()
a.elementType, NoAlignment), v) ++ loadFromReg()
case (a: VariablePointy, _, 2, _) =>
prepareWordIndexing(ctx, a, indexExpr) ++ loadFromReg()
case (p:VariablePointy, None, 0 | 1, _) =>

View File

@ -7,6 +7,7 @@ import millfork.env._
import millfork.node.{ZRegister, _}
import millfork.assembly.z80.ZOpcode._
import millfork.error.ConsoleLogger
import millfork.output.{NoAlignment, WithinPageAlignment}
/**
* @author Karol Stasiak
@ -940,13 +941,21 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
val pointy = env.getPointy(i.name)
AbstractExpressionCompiler.checkIndexType(ctx, pointy, i.index)
pointy match {
case ConstantPointy(baseAddr, _, _, _, _) =>
case ConstantPointy(baseAddr, _, size, _, _, alignment) =>
env.evalVariableAndConstantSubParts(i.index) match {
case (None, offset) => List(ZLine.ldImm16(ZRegister.HL, (baseAddr + offset).quickSimplify))
case (Some(index), offset) =>
List(ZLine.ldImm16(ZRegister.BC, (baseAddr + offset).quickSimplify)) ++
stashBCIfChanged(ctx, compileToHL(ctx, index)) ++
List(ZLine.registers(ADD_16, ZRegister.HL, ZRegister.BC))
val constantPart = (baseAddr + offset).quickSimplify
if (getExpressionType(ctx, i.index).size == 1 && size.exists(_ < 256) && alignment == WithinPageAlignment) {
compileToA(ctx, i.index) ++ List(
ZLine.imm8(ADD, constantPart.loByte),
ZLine.ld8(ZRegister.L, ZRegister.A),
ZLine.ldImm8(ZRegister.H, constantPart.hiByte))
} else {
List(ZLine.ldImm16(ZRegister.BC, constantPart)) ++
stashBCIfChanged(ctx, compileToHL(ctx, index)) ++
List(ZLine.registers(ADD_16, ZRegister.HL, ZRegister.BC))
}
}
case VariablePointy(varAddr, _, _) =>
env.eval(i.index) match {

View File

@ -294,13 +294,13 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
InitializedMemoryVariable
UninitializedMemoryVariable
getArrayOrPointer(name) match {
case th@InitializedArray(_, _, cs, _, i, e, _) => ConstantPointy(th.toAddress, Some(name), Some(cs.length), i, e)
case th@UninitializedArray(_, size, _, i, e, _) => ConstantPointy(th.toAddress, Some(name), Some(size), i, e)
case th@RelativeArray(_, _, size, _, i, e) => ConstantPointy(th.toAddress, Some(name), Some(size), i, e)
case th@InitializedArray(_, _, cs, _, i, e, _) => ConstantPointy(th.toAddress, Some(name), Some(cs.length), i, e, th.alignment)
case th@UninitializedArray(_, size, _, i, e, _) => ConstantPointy(th.toAddress, Some(name), Some(size), i, e, th.alignment)
case th@RelativeArray(_, _, size, _, i, e) => ConstantPointy(th.toAddress, Some(name), Some(size), i, e, NoAlignment)
case ConstantThing(_, value, typ) if typ.size <= 2 && typ.isPointy =>
val b = get[VariableType]("byte")
val w = get[VariableType]("word")
ConstantPointy(value, None, None, w, b)
ConstantPointy(value, None, None, w, b, NoAlignment)
case th:VariableInMemory if th.typ.isPointy=>
val b = get[VariableType]("byte")
val w = get[VariableType]("word")
@ -309,7 +309,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
log.error(s"$name is not a valid pointer or array")
val b = get[VariableType]("byte")
val w = get[VariableType]("word")
ConstantPointy(Constant.Zero, None, None, w, b)
ConstantPointy(Constant.Zero, None, None, w, b, NoAlignment)
}
}
@ -872,9 +872,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
}
private def defaultArrayAlignment(options: CompilationOptions, size: Long): MemoryAlignment = {
if (options.platform.cpuFamily == CpuFamily.M6502 &&
options.flag(CompilationFlag.OptimizeForSpeed) &&
size <= 256) WithinPageAlignment
if (options.flag(CompilationFlag.OptimizeForSpeed) && size <= 256 && size != 0) WithinPageAlignment
else NoAlignment
}

View File

@ -1,5 +1,7 @@
package millfork.env
import millfork.output.MemoryAlignment
trait Pointy {
def name: Option[String]
def indexType: VariableType
@ -10,4 +12,4 @@ case class VariablePointy(addr: Constant, indexType: VariableType, elementType:
override def name: Option[String] = None
}
case class ConstantPointy(value: Constant, name: Option[String], size: Option[Int], indexType: VariableType, elementType: VariableType) extends Pointy
case class ConstantPointy(value: Constant, name: Option[String], size: Option[Int], indexType: VariableType, elementType: VariableType, alignment: MemoryAlignment) extends Pointy