mirror of
https://github.com/KarolS/millfork.git
synced 2024-09-10 11:54:30 +00:00
Z80: Faster array indexing
This commit is contained in:
parent
8b09941cef
commit
019547aae8
@ -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, _) =>
|
||||
|
@ -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 {
|
||||
|
14
src/main/scala/millfork/env/Environment.scala
vendored
14
src/main/scala/millfork/env/Environment.scala
vendored
@ -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
|
||||
}
|
||||
|
||||
|
4
src/main/scala/millfork/env/Pointy.scala
vendored
4
src/main/scala/millfork/env/Pointy.scala
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user