mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-10 01:36:59 +00:00
8080: Optimization improvements
This commit is contained in:
parent
7427231c3d
commit
57776f7f93
@ -234,6 +234,19 @@ object Status {
|
||||
case _ => AnyStatus -> AnyStatus
|
||||
}
|
||||
|
||||
def sbb(value: Status[Int], carry: Status[Boolean]): (Status[Int], Status[Boolean]) = (inner, value) match {
|
||||
case (SingleStatus(x), SingleStatus(v)) => carry match {
|
||||
case SingleStatus(false) => SingleStatus((x - v) & 0xff) -> SingleStatus((x.&(0xff) - v.&(0xff)) < 0)
|
||||
case SingleStatus(true) => SingleStatus((x - v - 1) & 0xff) -> SingleStatus((x.&(0xff) - v.&(0xff) - 1) < 0)
|
||||
case _ => AnyStatus -> (if (v == 0) SingleFalse else AnyStatus)
|
||||
}
|
||||
case (_, SingleStatus(0)) => carry match {
|
||||
case SingleStatus(false) => inner -> SingleFalse
|
||||
case _ => AnyStatus -> AnyStatus
|
||||
}
|
||||
case _ => AnyStatus -> AnyStatus
|
||||
}
|
||||
|
||||
def adc_w(value: Int, carry: Status[Boolean], decimal: Status[Boolean]): Status[Int] = inner match {
|
||||
case SingleStatus(x) => decimal match {
|
||||
case SingleStatus(false) => carry match {
|
||||
|
@ -334,6 +334,22 @@ object AlwaysGoodI80Optimizations {
|
||||
(HasOpcode(CP) & MatchSoleRegisterAndOffset(1) & Not(Match8BitImmediate(2))) ~
|
||||
(HasOpcodeIn(Set(JP, JR, RET)) & HasRegisters(IfFlagClear(ZFlag.Z))) ~
|
||||
(Elidable & HasOpcode(LD) & HasTargetRegister(A) & MatchSourceRegisterAndOffset(1)) ~~> (_.init),
|
||||
|
||||
// 69
|
||||
(Elidable & HasOpcode(LD) & HasTargetRegister(MEM_ABS_8) & MatchParameter(0)) ~
|
||||
(Linear & Not(ConcernsMemory)).* ~
|
||||
(HasOpcode(LD) & HasTargetRegister(MEM_ABS_8) & MatchParameter(0)) ~~> (_.tail),
|
||||
|
||||
// 70
|
||||
(Elidable & HasOpcode(LD) & HasTargetRegister(MEM_HL)) ~
|
||||
(Linear & Not(ConcernsMemory) & Not(Changes(ZRegister.HL))).* ~
|
||||
(HasOpcode(LD) & HasTargetRegister(MEM_HL)) ~~> (_.tail),
|
||||
|
||||
// 71
|
||||
(Elidable & HasOpcode(LD_16) & HasTargetRegister(MEM_ABS_16) & MatchParameter(0)) ~
|
||||
(Linear & Not(ConcernsMemory)).* ~
|
||||
(HasOpcode(LD_16) & HasTargetRegister(MEM_ABS_16) & MatchParameter(0)) ~~> (_.tail),
|
||||
|
||||
)
|
||||
|
||||
val PointlessStackStashing = new RuleBasedAssemblyOptimization("Pointless stack stashing",
|
||||
@ -1706,8 +1722,30 @@ object AlwaysGoodI80Optimizations {
|
||||
),
|
||||
)
|
||||
|
||||
val ActuallyUnconditionalJump = new RuleBasedAssemblyOptimization("Actually unconditional jump",
|
||||
needsFlowInfo = FlowInfoRequirement.ForwardFlow,
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.C)) & HasSet(ZFlag.C)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.C)) & HasClear(ZFlag.C)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.Z)) & HasSet(ZFlag.Z)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.Z)) & HasClear(ZFlag.Z)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.S)) & HasSet(ZFlag.S)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.S)) & HasClear(ZFlag.S)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.P)) & HasSet(ZFlag.P)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.P)) & HasClear(ZFlag.P)) ~~> (code => code.map(_.copy(opcode = JP, registers = NoRegisters))),
|
||||
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.C)) & HasSet(ZFlag.C)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.C)) & HasClear(ZFlag.C)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.Z)) & HasSet(ZFlag.Z)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.Z)) & HasClear(ZFlag.Z)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.S)) & HasSet(ZFlag.S)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.S)) & HasClear(ZFlag.S)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagClear(ZFlag.P)) & HasSet(ZFlag.P)) ~~> (code => Nil),
|
||||
(Elidable & HasOpcodeIn(Set(JP, JR)) & HasRegisters(IfFlagSet(ZFlag.P)) & HasClear(ZFlag.P)) ~~> (code => Nil),
|
||||
)
|
||||
|
||||
|
||||
val All: List[AssemblyOptimization[ZLine]] = List[AssemblyOptimization[ZLine]](
|
||||
ActuallyUnconditionalJump,
|
||||
BranchInPlaceRemoval,
|
||||
ConstantDivision,
|
||||
ConstantMultiplication,
|
||||
|
@ -155,9 +155,22 @@ object CoarseFlowAnalyzer {
|
||||
currentStatus = currentStatus.copy(a = newA,
|
||||
nf = Status.SingleFalse, cf = newC, zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
|
||||
case ZLine0(SUB, OneRegister(ZRegister.IMM_8), NumericConstant(n, _)) =>
|
||||
val (newA, newC) = currentStatus.a.sbb(SingleStatus(n.toInt & 0xff), Status.SingleFalse)
|
||||
currentStatus = currentStatus.copy(a = newA,
|
||||
nf = Status.SingleTrue, cf = newC, zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
case ZLine0(SBC,OneRegister(ZRegister.IMM_8), NumericConstant(n, _))=>
|
||||
val (newA, newC) = currentStatus.a.sbb(SingleStatus(n.toInt & 0xff), currentStatus.cf)
|
||||
currentStatus = currentStatus.copy(a = newA,
|
||||
nf = Status.SingleTrue, cf = newC,zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
case ZLine0(SUB, OneRegister(s), _) =>
|
||||
currentStatus = currentStatus.copy(a = (currentStatus.a <*> currentStatus.getRegister(s)) ((m, n) => (m - n) & 0xff),
|
||||
nf = Status.SingleTrue, cf = AnyStatus, zf = AnyStatus, sf = AnyStatus, pf = AnyStatus, hf = AnyStatus)
|
||||
val (newA, newC) = currentStatus.a.sbb(currentStatus.getRegister(s), Status.SingleFalse)
|
||||
currentStatus = currentStatus.copy(a = newA,
|
||||
nf = Status.SingleTrue, cf = newC, zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
case ZLine0(SBC, OneRegister(s), _) =>
|
||||
val (newA, newC) = currentStatus.a.sbb(currentStatus.getRegister(s), currentStatus.cf)
|
||||
currentStatus = currentStatus.copy(a = newA,
|
||||
nf = Status.SingleTrue, cf = newC,zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
|
||||
case ZLine0(AND, OneRegister(s), _) =>
|
||||
currentStatus = currentStatus.copy(a = (currentStatus.a <*> currentStatus.getRegister(s)) ((m, n) => (m & n) & 0xff),
|
||||
@ -173,6 +186,13 @@ object CoarseFlowAnalyzer {
|
||||
currentStatus = currentStatus.copy(a = (currentStatus.a <*> currentStatus.getRegister(s)) ((m, n) => (m ^ n) & 0xff),
|
||||
nf = Status.SingleFalse, cf = Status.SingleFalse, zf = AnyStatus, sf = AnyStatus, pf = AnyStatus, hf = AnyStatus)
|
||||
|
||||
case ZLine0(CP, OneRegister(ZRegister.IMM_8), NumericConstant(n, _)) =>
|
||||
val (newA, newC) = currentStatus.a.sbb(SingleStatus(n.toInt & 0xff), Status.SingleFalse)
|
||||
currentStatus = currentStatus.copy(nf = AnyStatus, cf = newC, zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
case ZLine0(CP, OneRegister(s), _) =>
|
||||
val (newA, newC) = currentStatus.a.sbb(currentStatus.getRegister(s), Status.SingleFalse)
|
||||
currentStatus = currentStatus.copy(nf = AnyStatus, cf = newC, zf = newA.z(), sf = newA.n(), pf = AnyStatus, hf = AnyStatus)
|
||||
|
||||
case ZLine0(INC, OneRegister(r), _) =>
|
||||
val newV = currentStatus.getRegister(r).map(i => i.+(1).&(0xff))
|
||||
currentStatus = currentStatus.
|
||||
|
Loading…
x
Reference in New Issue
Block a user