mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-25 06:29:17 +00:00
Optimization fixes and improvements for Z80
This commit is contained in:
parent
ed067d3a67
commit
619bf8116a
@ -1,7 +1,7 @@
|
||||
package millfork.assembly.z80.opt
|
||||
|
||||
import millfork.assembly.AssemblyOptimization
|
||||
import millfork.assembly.z80.{TwoRegisters, ZLine, ZOpcode}
|
||||
import millfork.assembly.z80.{OneRegister, TwoRegisters, ZLine, ZOpcode}
|
||||
import millfork.assembly.z80.ZOpcode._
|
||||
import millfork.env.{Constant, NumericConstant}
|
||||
import millfork.node.ZRegister
|
||||
@ -69,6 +69,18 @@ object AlwaysGoodZ80Optimizations {
|
||||
(Linear & Not(Changes(register))).* ~
|
||||
(Elidable & Is16BitLoad(register, ZRegister.IMM_16) & MatchImmediate(0)) ~~> (_.init)
|
||||
),
|
||||
|
||||
(Elidable & Is8BitLoadTo(ZRegister.MEM_HL)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(Changes(ZRegister.HL))).* ~
|
||||
Is8BitLoadTo(ZRegister.MEM_HL) ~~> (_.tail),
|
||||
|
||||
(Elidable & Is8BitLoadTo(ZRegister.MEM_DE)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(Changes(ZRegister.DE))).* ~
|
||||
Is8BitLoadTo(ZRegister.MEM_DE) ~~> (_.tail),
|
||||
|
||||
(Elidable & Is8BitLoadTo(ZRegister.MEM_BC)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(Changes(ZRegister.BC))).* ~
|
||||
Is8BitLoadTo(ZRegister.MEM_BC) ~~> (_.tail),
|
||||
)
|
||||
|
||||
private def simplifiable16BitAddWithSplitTarget(targetH: ZRegister.Value, targetL: ZRegister.Value, target: ZRegister.Value, source: ZRegister.Value) = MultipleAssemblyRules(List(
|
||||
@ -147,6 +159,23 @@ object AlwaysGoodZ80Optimizations {
|
||||
code.head.copy(opcode = LD, registers = TwoRegisters(ZRegister.A, ZRegister.MEM_ABS_8)),
|
||||
code(1).copy(registers = TwoRegisters(code(1).registers.asInstanceOf[TwoRegisters].target, ZRegister.A)),
|
||||
)),
|
||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
||||
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
||||
List(
|
||||
code.head.copy(registers = TwoRegisters(ZRegister.DE, ZRegister.IMM_16))
|
||||
)),
|
||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
||||
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
||||
List(
|
||||
code.head.copy(registers = TwoRegisters(ZRegister.BC, ZRegister.IMM_16))
|
||||
)),
|
||||
)
|
||||
|
||||
val UnusedLabelRemoval = new RuleBasedAssemblyOptimization("Unused label removal",
|
||||
needsFlowInfo = FlowInfoRequirement.JustLabels,
|
||||
(Elidable & HasOpcode(LABEL) & HasCallerCount(0)) ~~> (_ => Nil)
|
||||
)
|
||||
|
||||
val All: List[AssemblyOptimization[ZLine]] = List[AssemblyOptimization[ZLine]](
|
||||
@ -155,6 +184,7 @@ object AlwaysGoodZ80Optimizations {
|
||||
PointlessLoad,
|
||||
ReloadingKnownValueFromMemory,
|
||||
SimplifiableMaths,
|
||||
UnusedLabelRemoval,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package millfork.assembly.z80.opt
|
||||
|
||||
import millfork.assembly.mos.{AssemblyLine, OpcodeClasses}
|
||||
import millfork.assembly.opt.{AnyStatus, SingleStatus}
|
||||
import millfork.assembly.z80.{OneRegister, TwoRegisters, ZLine, ZOpcodeClasses}
|
||||
import millfork.env.{Label, MemoryAddressConstant, NormalFunction, NumericConstant}
|
||||
@ -35,6 +34,7 @@ object CoarseFlowAnalyzer {
|
||||
case ZLine(LABEL, _, MemoryAddressConstant(Label(l)), _) =>
|
||||
val L = l
|
||||
currentStatus = codeArray.indices.flatMap(j => codeArray(j) match {
|
||||
case ZLine(DJNZ, _, MemoryAddressConstant(Label(L)), _) => Some(flagArray(j).copy(b = AnyStatus))
|
||||
case ZLine(_, _, MemoryAddressConstant(Label(L)), _) => Some(flagArray(j))
|
||||
case _ => None
|
||||
}).fold(currentStatus)(_ ~ _)
|
||||
|
@ -1,8 +1,7 @@
|
||||
package millfork.assembly.z80.opt
|
||||
|
||||
import millfork.CompilationOptions
|
||||
import millfork.assembly.mos.{AssemblyLine, Opcode, State}
|
||||
import millfork.assembly.z80.ZLine
|
||||
import millfork.assembly.z80.{ZLine, ZOpcode}
|
||||
import millfork.env.{Label, MemoryAddressConstant, NormalFunction}
|
||||
|
||||
/**
|
||||
@ -44,7 +43,7 @@ object FlowAnalyzer {
|
||||
val labelMap: (() => Option[Map[String, Int]]) = () => req match {
|
||||
case FlowInfoRequirement.NoRequirement => None
|
||||
case _ => Some(code.flatMap {
|
||||
case ZLine(op, _, MemoryAddressConstant(Label(l)), _) if op != Opcode.LABEL => Some(l)
|
||||
case ZLine(op, _, MemoryAddressConstant(Label(l)), _) if op != ZOpcode.LABEL => Some(l)
|
||||
case _ => None
|
||||
}.groupBy(identity).mapValues(_.size))
|
||||
}
|
||||
|
@ -456,6 +456,11 @@ case class MatchParameter(i: Int) extends AssemblyLinePattern {
|
||||
}
|
||||
}
|
||||
|
||||
case class MatchOpcode(i: Int) extends AssemblyLinePattern {
|
||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
||||
ctx.addObject(i, line.opcode)
|
||||
}
|
||||
|
||||
case class HasRegister(register: ZRegister.Value, value: Int) extends AssemblyLinePattern {
|
||||
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
|
||||
FlowInfoRequirement.assertForward(needsFlowInfo)
|
||||
@ -615,7 +620,7 @@ case class Is16BitLoad(target:ZRegister.Value, source: ZRegister.Value) extends
|
||||
case class IsRegular8BitLoadFrom(source: ZRegister.Value) extends TrivialAssemblyLinePattern {
|
||||
override def apply(line: ZLine): Boolean =
|
||||
line.opcode == ZOpcode.LD && line.registers.asInstanceOf[TwoRegisters].source == source && (line.registers.asInstanceOf[TwoRegisters].target match {
|
||||
case ZRegister.I | ZRegister.MEM_ABS_8 | ZRegister.R => false
|
||||
case ZRegister.I | ZRegister.MEM_ABS_8 | ZRegister.R | ZRegister.MEM_DE | ZRegister.MEM_BC => false
|
||||
case _ => true
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user