mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-24 15:29:23 +00:00
6502: Improve memset
This commit is contained in:
parent
46ce602a3e
commit
b01c440cf0
@ -1,8 +1,9 @@
|
|||||||
package millfork.compiler.mos
|
package millfork.compiler.mos
|
||||||
|
|
||||||
|
import millfork.CompilationFlag
|
||||||
import millfork.assembly.mos.AssemblyLine
|
import millfork.assembly.mos.AssemblyLine
|
||||||
import millfork.compiler.{BranchSpec, CompilationContext}
|
import millfork.compiler.{BranchSpec, CompilationContext}
|
||||||
import millfork.env.{Label, NumericConstant, Type, VariableInMemory}
|
import millfork.env.{NumericConstant, Type, VariableInMemory}
|
||||||
import millfork.node._
|
import millfork.node._
|
||||||
import millfork.assembly.mos.Opcode._
|
import millfork.assembly.mos.Opcode._
|
||||||
|
|
||||||
@ -32,43 +33,93 @@ object MosBulkMemoryOperations {
|
|||||||
case Some(c) => c.quickSimplify
|
case Some(c) => c.quickSimplify
|
||||||
case _ => return MosStatementCompiler.compileForStatement(ctx, f)
|
case _ => return MosStatementCompiler.compileForStatement(ctx, f)
|
||||||
}
|
}
|
||||||
val loadReg = MosExpressionCompiler.compile(ctx, SumExpression(List(false -> f.start, false -> target.index), decimal = false), Some(w -> reg), BranchSpec.None)
|
val useTwoRegs = ctx.options.flag(CompilationFlag.OptimizeForSpeed) && ctx.options.zpRegisterSize >= 4
|
||||||
|
val loadReg = MosExpressionCompiler.compile(ctx, SumExpression(List(false -> f.start, false -> target.index), decimal = false), Some(w -> reg), BranchSpec.None) ++ (
|
||||||
|
if (useTwoRegs) List(AssemblyLine.zeropage(LDA, reg), AssemblyLine.zeropage(STA, reg,2), AssemblyLine.zeropage(LDA, reg,1), AssemblyLine.zeropage(STA, reg,3))
|
||||||
|
else Nil
|
||||||
|
)
|
||||||
val loadSource = MosExpressionCompiler.compileToA(ctx, source)
|
val loadSource = MosExpressionCompiler.compileToA(ctx, source)
|
||||||
val loadAll = if (MosExpressionCompiler.changesZpreg(loadSource, 0) || MosExpressionCompiler.changesZpreg(loadSource, 1)) {
|
val loadAll = if (MosExpressionCompiler.changesZpreg(loadSource, 0) || MosExpressionCompiler.changesZpreg(loadSource, 1)) {
|
||||||
loadSource ++ MosExpressionCompiler.preserveRegisterIfNeeded(ctx, MosRegister.A, loadReg)
|
loadSource ++ MosExpressionCompiler.preserveRegisterIfNeeded(ctx, MosRegister.A, loadReg)
|
||||||
} else {
|
} else {
|
||||||
loadReg ++ loadSource
|
loadReg ++ loadSource
|
||||||
}
|
}
|
||||||
val wholePageCount = size.hiByte
|
val wholePageCount = size.hiByte.quickSimplify
|
||||||
val setWholePages = wholePageCount match {
|
|
||||||
case NumericConstant(0, _) => Nil
|
def fillOnePage: List[AssemblyLine] = {
|
||||||
case NumericConstant(1, _) =>
|
val label = ctx.nextLabel("ms")
|
||||||
val label = ctx.nextLabel("ms")
|
if (useTwoRegs) {
|
||||||
List(
|
if (ctx.options.flag(CompilationFlag.OptimizeForSonicSpeed)) {
|
||||||
|
List(
|
||||||
|
AssemblyLine.immediate(LDY, 0x80),
|
||||||
|
AssemblyLine.label(label),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.indexedY(STA, reg, 2),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.indexedY(STA, reg, 2),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.relative(BNE, label))
|
||||||
|
} else if (ctx.options.flag(CompilationFlag.OptimizeForSpeed)) {
|
||||||
|
List(
|
||||||
|
AssemblyLine.immediate(LDY, 0x80),
|
||||||
|
AssemblyLine.label(label),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.indexedY(STA, reg, 2),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.relative(BNE, label))
|
||||||
|
} else ???
|
||||||
|
} else {
|
||||||
|
if (ctx.options.flag(CompilationFlag.OptimizeForSonicSpeed)) {
|
||||||
|
List(
|
||||||
|
AssemblyLine.immediate(LDY, 0),
|
||||||
|
AssemblyLine.label(label),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.relative(BNE, label))
|
||||||
|
} else if (ctx.options.flag(CompilationFlag.OptimizeForSpeed)) {
|
||||||
|
List(
|
||||||
|
AssemblyLine.immediate(LDY, 0),
|
||||||
|
AssemblyLine.label(label),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.indexedY(STA, reg),
|
||||||
|
AssemblyLine.implied(INY),
|
||||||
|
AssemblyLine.relative(BNE, label))
|
||||||
|
} else {
|
||||||
|
List(
|
||||||
AssemblyLine.immediate(LDY, 0),
|
AssemblyLine.immediate(LDY, 0),
|
||||||
AssemblyLine.label(label),
|
AssemblyLine.label(label),
|
||||||
AssemblyLine.indexedY(STA, reg),
|
AssemblyLine.indexedY(STA, reg),
|
||||||
AssemblyLine.implied(INY),
|
AssemblyLine.implied(INY),
|
||||||
AssemblyLine.relative(BNE, label))
|
AssemblyLine.relative(BNE, label))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val setWholePages = wholePageCount match {
|
||||||
|
case NumericConstant(0, _) => Nil
|
||||||
|
case NumericConstant(1, _) =>
|
||||||
|
fillOnePage
|
||||||
case _ =>
|
case _ =>
|
||||||
val labelX = ctx.nextLabel("ms")
|
val labelX = ctx.nextLabel("ms")
|
||||||
val labelXSkip = ctx.nextLabel("ms")
|
val labelXSkip = ctx.nextLabel("ms")
|
||||||
val labelY = ctx.nextLabel("ms")
|
|
||||||
List(
|
List(
|
||||||
AssemblyLine.immediate(LDX, wholePageCount),
|
AssemblyLine.immediate(LDX, wholePageCount),
|
||||||
AssemblyLine.relative(BEQ, labelXSkip),
|
AssemblyLine.relative(BEQ, labelXSkip),
|
||||||
AssemblyLine.label(labelX),
|
AssemblyLine.label(labelX)) ++ fillOnePage ++ List(
|
||||||
AssemblyLine.immediate(LDY, 0),
|
|
||||||
AssemblyLine.label(labelY),
|
|
||||||
AssemblyLine.indexedY(STA, reg),
|
|
||||||
AssemblyLine.implied(INY),
|
|
||||||
AssemblyLine.relative(BNE, labelY),
|
|
||||||
AssemblyLine.zeropage(INC, reg, 1),
|
AssemblyLine.zeropage(INC, reg, 1),
|
||||||
AssemblyLine.implied(DEX),
|
AssemblyLine.implied(DEX),
|
||||||
AssemblyLine.relative(BNE, labelX),
|
AssemblyLine.relative(BNE, labelX),
|
||||||
AssemblyLine.label(labelXSkip))
|
AssemblyLine.label(labelXSkip))
|
||||||
}
|
}
|
||||||
val restSize = size.loByte
|
val restSize = size.loByte.quickSimplify
|
||||||
val setRest = restSize match {
|
val setRest = restSize match {
|
||||||
case NumericConstant(0, _) => Nil
|
case NumericConstant(0, _) => Nil
|
||||||
case NumericConstant(1, _) =>
|
case NumericConstant(1, _) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user