mirror of
https://github.com/KarolS/millfork.git
synced 2024-10-13 01:23:40 +00:00
Z80: More optimizations
This commit is contained in:
parent
ec9dba9d27
commit
bebb8c45a5
@ -14,6 +14,7 @@ object ZFlag extends Enumeration {
|
|||||||
val Z, P, C, S, H, N = Value
|
val Z, P, C, S, H, N = Value
|
||||||
|
|
||||||
val AllButSZ: Seq[Value] = Seq(P, C, H, N)
|
val AllButSZ: Seq[Value] = Seq(P, C, H, N)
|
||||||
|
val AllButZ: Seq[Value] = Seq(P, C, H, N, S)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait ZRegisters
|
sealed trait ZRegisters
|
||||||
|
@ -5,6 +5,7 @@ import millfork.assembly.z80._
|
|||||||
import millfork.assembly.z80.ZOpcode._
|
import millfork.assembly.z80.ZOpcode._
|
||||||
import millfork.env.{CompoundConstant, Constant, MathOperator, NumericConstant}
|
import millfork.env.{CompoundConstant, Constant, MathOperator, NumericConstant}
|
||||||
import millfork.node.ZRegister
|
import millfork.node.ZRegister
|
||||||
|
import ZRegister._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimizations valid for Intel8080, Z80, EZ80 and Sharp
|
* Optimizations valid for Intel8080, Z80, EZ80 and Sharp
|
||||||
@ -742,8 +743,61 @@ object AlwaysGoodI80Optimizations {
|
|||||||
ZLine.implied(RLCA),
|
ZLine.implied(RLCA),
|
||||||
ZLine.imm8(AND, 7))
|
ZLine.imm8(AND, 7))
|
||||||
},
|
},
|
||||||
|
(Elidable & HasOpcode(RR) & HasRegisterParam(ZRegister.A) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {_ =>
|
||||||
|
List(ZLine.implied(RRA))
|
||||||
|
},
|
||||||
|
(Elidable & HasOpcode(RRC) & HasRegisterParam(ZRegister.A) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {_ =>
|
||||||
|
List(ZLine.implied(RRCA))
|
||||||
|
},
|
||||||
|
(Elidable & HasOpcode(RL) & HasRegisterParam(ZRegister.A) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {_ =>
|
||||||
|
List(ZLine.implied(RLA))
|
||||||
|
},
|
||||||
|
(Elidable & HasOpcode(RLC) & HasRegisterParam(ZRegister.A) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {_ =>
|
||||||
|
List(ZLine.implied(RLCA))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val PointlessExdehl = new RuleBasedAssemblyOptimization("Pointless EX DE,HL",
|
||||||
|
needsFlowInfo = FlowInfoRequirement.NoRequirement,
|
||||||
|
|
||||||
|
(Elidable & HasOpcode(EX_DE_HL)) ~
|
||||||
|
(Elidable & (
|
||||||
|
HasOpcode(LD_16) & (HasRegisters(TwoRegisters(DE, IMM_16)) | HasRegisters(TwoRegisters(HL, IMM_16)) | HasRegisters(TwoRegisters(BC, IMM_16))) |
|
||||||
|
Is8BitLoad(A, H) |
|
||||||
|
Is8BitLoad(A, L) |
|
||||||
|
Is8BitLoad(A, D) |
|
||||||
|
Is8BitLoad(A, E) |
|
||||||
|
Is8BitLoad(H, A) |
|
||||||
|
Is8BitLoad(L, A) |
|
||||||
|
Is8BitLoad(D, A) |
|
||||||
|
Is8BitLoad(E, A) |
|
||||||
|
HasOpcodeIn(Set(POP, PUSH, INC_16, DEC_16)) |
|
||||||
|
HasOpcodeIn(Set(INC, DEC, ADD, ADC, SUB, SBC, RLA, RLA, RRCA, RRCA, RL, RR, RRC, RLC, AND, XOR, OR, CP))
|
||||||
|
)).* ~
|
||||||
|
(Elidable & HasOpcode(EX_DE_HL)) ~~> { code =>
|
||||||
|
code.tail.init.map { line =>
|
||||||
|
line.registers match {
|
||||||
|
case OneRegister(HL) => line.copy(registers = OneRegister(DE))
|
||||||
|
case OneRegister(DE) => line.copy(registers = OneRegister(HL))
|
||||||
|
case TwoRegisters(HL, source) => line.copy(registers = TwoRegisters(DE, source))
|
||||||
|
case TwoRegisters(DE, source) => line.copy(registers = TwoRegisters(HL, source))
|
||||||
|
case TwoRegisters(H, r) => line.copy(registers = TwoRegisters(D, r))
|
||||||
|
case TwoRegisters(L, r) => line.copy(registers = TwoRegisters(E, r))
|
||||||
|
case TwoRegisters(D, r) => line.copy(registers = TwoRegisters(H, r))
|
||||||
|
case TwoRegisters(E, r) => line.copy(registers = TwoRegisters(L, r))
|
||||||
|
case TwoRegisters(r, H) => line.copy(registers = TwoRegisters(r, D))
|
||||||
|
case TwoRegisters(r, L) => line.copy(registers = TwoRegisters(r, E))
|
||||||
|
case TwoRegisters(r, D) => line.copy(registers = TwoRegisters(r, H))
|
||||||
|
case TwoRegisters(r, E) => line.copy(registers = TwoRegisters(r, L))
|
||||||
|
case _ => line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
val All: List[AssemblyOptimization[ZLine]] = List[AssemblyOptimization[ZLine]](
|
val All: List[AssemblyOptimization[ZLine]] = List[AssemblyOptimization[ZLine]](
|
||||||
BranchInPlaceRemoval,
|
BranchInPlaceRemoval,
|
||||||
FreeHL,
|
FreeHL,
|
||||||
|
@ -3,8 +3,9 @@ package millfork.assembly.z80.opt
|
|||||||
import millfork.assembly.AssemblyOptimization
|
import millfork.assembly.AssemblyOptimization
|
||||||
import millfork.assembly.z80._
|
import millfork.assembly.z80._
|
||||||
import millfork.assembly.z80.ZOpcode._
|
import millfork.assembly.z80.ZOpcode._
|
||||||
import millfork.env.{CompoundConstant, Constant, MathOperator, NumericConstant}
|
import millfork.env.Constant
|
||||||
import millfork.node.ZRegister
|
import millfork.node.ZRegister
|
||||||
|
import ZRegister._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimizations valid for Z80 and EZ80
|
* Optimizations valid for Z80 and EZ80
|
||||||
@ -81,6 +82,17 @@ object AlwaysGoodZ80Optimizations {
|
|||||||
(Elidable & HasOpcode(NEG)) ~
|
(Elidable & HasOpcode(NEG)) ~
|
||||||
(Elidable & HasOpcode(ADD) & Has8BitImmediate(0xff) & DoesntMatterWhatItDoesWithFlags) ~~> (_ => List(ZLine.implied(CPL))),
|
(Elidable & HasOpcode(ADD) & Has8BitImmediate(0xff) & DoesntMatterWhatItDoesWithFlags) ~~> (_ => List(ZLine.implied(CPL))),
|
||||||
|
|
||||||
|
(Elidable & HasOpcode(OR) & HasRegisters(OneRegister(A)) & HasRegister(BC, 0)) ~
|
||||||
|
(Elidable & HasOpcode(SBC_16) & HasRegisters(TwoRegisters(HL, BC)) & DoesntMatterWhatItDoesWithFlagsExceptZero) ~~> { code =>
|
||||||
|
List(ZLine.ld8(A, H), ZLine.register(OR, L))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Elidable & HasOpcode(OR) & HasRegisters(OneRegister(A)) & HasRegister(DE, 0)) ~
|
||||||
|
(Elidable & HasOpcode(SBC_16) & HasRegisters(TwoRegisters(HL, DE)) & DoesntMatterWhatItDoesWithFlagsExceptZero) ~~> { code =>
|
||||||
|
List(ZLine.ld8(A, H), ZLine.register(OR, L))
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val FreeHL = new RuleBasedAssemblyOptimization("Free HL (Z80)",
|
val FreeHL = new RuleBasedAssemblyOptimization("Free HL (Z80)",
|
||||||
|
@ -621,11 +621,21 @@ case object DoesntMatterWhatItDoesWithFlagsOtherThanSZ extends AssemblyLinePatte
|
|||||||
override def toString: String = "[¯\\_(ツ)_/¯:NPVH]"
|
override def toString: String = "[¯\\_(ツ)_/¯:NPVH]"
|
||||||
}
|
}
|
||||||
|
|
||||||
case object DoesntMatterWhatItDoesWithFlagsExceptCarry extends AssemblyLinePattern {
|
case object DoesntMatterWhatItDoesWithFlagsExceptZero extends AssemblyLinePattern {
|
||||||
|
|
||||||
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
|
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
|
||||||
FlowInfoRequirement.assertBackward(needsFlowInfo)
|
FlowInfoRequirement.assertBackward(needsFlowInfo)
|
||||||
|
|
||||||
|
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
||||||
|
ZFlag.AllButZ.forall(r => flowInfo.importanceAfter.getFlag(r) != Important)
|
||||||
|
|
||||||
|
override def toString: String = "[¯\\_(ツ)_/¯:NPVHS]"
|
||||||
|
}
|
||||||
|
|
||||||
|
case object DoesntMatterWhatItDoesWithFlagsExceptCarry extends AssemblyLinePattern {
|
||||||
|
override def validate(needsFlowInfo: FlowInfoRequirement.Value): Unit =
|
||||||
|
FlowInfoRequirement.assertBackward(needsFlowInfo)
|
||||||
|
|
||||||
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
|
||||||
ZFlag.values.forall(r => r == ZFlag.C || flowInfo.importanceAfter.getFlag(r) != Important)
|
ZFlag.values.forall(r => r == ZFlag.C || flowInfo.importanceAfter.getFlag(r) != Important)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user