mirror of
https://github.com/KarolS/millfork.git
synced 2025-02-06 01:30:13 +00:00
Z80: Better inlining of variables into register pairs
This commit is contained in:
parent
019547aae8
commit
0cb91c0f68
@ -1,7 +1,7 @@
|
||||
package millfork.assembly.z80.opt
|
||||
|
||||
import millfork.assembly.AssemblyOptimization
|
||||
import millfork.assembly.z80.{opt, _}
|
||||
import millfork.assembly.z80._
|
||||
import millfork.assembly.z80.ZOpcode._
|
||||
import millfork.env.{CompoundConstant, Constant, MathOperator, NumericConstant}
|
||||
import millfork.node.ZRegister
|
||||
@ -786,6 +786,25 @@ object AlwaysGoodI80Optimizations {
|
||||
(Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (code, ctx) =>
|
||||
List(ZLine.ldImm16(ZRegister.BC, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
||||
},
|
||||
|
||||
// TODO: this is a bit controversial
|
||||
// 41 cycles 6 bytes → 24 cycles 8 bytes
|
||||
MultipleAssemblyRules(Seq(BC, DE).map{ reg =>
|
||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(reg)) ~
|
||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(reg, IMM_16)) & MatchParameter(0)) ~
|
||||
(Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, reg))) ~
|
||||
(Elidable & HasOpcode(POP) & HasRegisterParam(reg) & DoesntMatterWhatItDoesWithFlagsExceptCarry & DoesntMatterWhatItDoesWith(A)) ~~> { (code, ctx) =>
|
||||
val offset = ctx.get[Constant](0)
|
||||
List(
|
||||
ZLine.ld8(A, L),
|
||||
ZLine.imm8(ADD, offset.loByte),
|
||||
ZLine.ld8(L, A),
|
||||
ZLine.ld8(A, H),
|
||||
ZLine.imm8(ADC, offset.hiByte),
|
||||
ZLine.ld8(H, A)
|
||||
)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
val UnusedCodeRemoval = new RuleBasedAssemblyOptimization("Unreachable code removal",
|
||||
|
@ -124,7 +124,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
case (v, range, _) =>
|
||||
log.debug(s"Inlining $v to register pair HL")
|
||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||
val newCode = inlineVars(v, "", "", oldCode.map(_._2))
|
||||
val newCode = inlineVars(v, "", "", oldCode)
|
||||
reportOptimizedBlock(oldCode, newCode)
|
||||
output ++= newCode
|
||||
i = range.end
|
||||
@ -138,7 +138,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
case (v, range, _) =>
|
||||
log.debug(s"Inlining $v to register pair BC")
|
||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||
val newCode = inlineVars("", v, "", oldCode.map(_._2))
|
||||
val newCode = inlineVars("", v, "", oldCode)
|
||||
reportOptimizedBlock(oldCode, newCode)
|
||||
output ++= newCode
|
||||
i = range.end
|
||||
@ -153,7 +153,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
case (v, range, _) =>
|
||||
log.debug(s"Inlining $v to register pair DE")
|
||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||
val newCode = inlineVars("", "", v, oldCode.map(_._2))
|
||||
val newCode = inlineVars("", "", v, oldCode)
|
||||
reportOptimizedBlock(oldCode, newCode)
|
||||
output ++= newCode
|
||||
i = range.end
|
||||
@ -192,15 +192,16 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
None
|
||||
}
|
||||
code match {
|
||||
|
||||
case (_, ZLine(LD_16, TwoRegisters(BC, IMM_16), _, true))::
|
||||
(i, ZLine(ADD_16, TwoRegisters(HL, BC), _, true)) :: xs if target == BC =>
|
||||
if (i.importanceAfter.getRegister(BC) == Important || i.importanceAfter.getRegister(DE) == Important) fail(22)
|
||||
if (i.importanceAfter.getRegister(BC) == Important) fail(22)
|
||||
else if(i.importanceAfter.getRegister(DE) == Important) canBeInlined(vname, synced, target, xs).map(add(CyclesAndBytes(-21, -2)))
|
||||
else canBeInlined(vname, synced = true, target, xs)
|
||||
|
||||
case (_, ZLine(LD_16, TwoRegisters(DE, IMM_16), _, true))::
|
||||
(i, ZLine(ADD_16, TwoRegisters(HL, DE), _, true)) :: xs if target == DE =>
|
||||
if (i.importanceAfter.getRegister(BC) == Important || i.importanceAfter.getRegister(DE) == Important) fail(23)
|
||||
if (i.importanceAfter.getRegister(DE) == Important) fail(23)
|
||||
else if (i.importanceAfter.getRegister(BC) == Important) canBeInlined(vname, synced, target, xs).map(add(CyclesAndBytes(-21, -2)))
|
||||
else canBeInlined(vname, synced = true, target, xs)
|
||||
|
||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th1), true)) ::
|
||||
@ -292,28 +293,36 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
}
|
||||
}
|
||||
|
||||
def inlineVars(hl: String, bc: String, de: String, code: List[ZLine]): List[ZLine] = {
|
||||
// if (code.nonEmpty) println(code.head)
|
||||
def inlineVars(hl: String, bc: String, de: String, code: List[(FlowInfo, ZLine)]): List[ZLine] = {
|
||||
// if (code.nonEmpty) println(code.head)
|
||||
code match {
|
||||
|
||||
case (load@ZLine(LD_16, TwoRegisters(BC, IMM_16), _, _)) ::
|
||||
ZLine(ADD_16, TwoRegisters(HL, BC), _, _) ::
|
||||
case (_, load@ZLine(LD_16, TwoRegisters(BC, IMM_16), _, _)) ::
|
||||
(f, add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) ::
|
||||
xs if bc != "" =>
|
||||
load.copy(registers = TwoRegisters(DE, IMM_16)) ::
|
||||
ZLine.registers(ADD_16, HL, DE) ::
|
||||
inlineVars(hl, bc, de, xs)
|
||||
if (f.importanceAfter.getRegister(DE) == Important) {
|
||||
ZLine.register(PUSH, BC) :: load :: add :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
||||
} else {
|
||||
load.copy(registers = TwoRegisters(DE, IMM_16)) ::
|
||||
ZLine.registers(ADD_16, HL, DE) ::
|
||||
inlineVars(hl, bc, de, xs)
|
||||
}
|
||||
|
||||
case (load@ZLine(LD_16, TwoRegisters(DE, IMM_16), _, _)) ::
|
||||
ZLine(ADD_16, TwoRegisters(HL, DE), _, _) ::
|
||||
case (_, load@ZLine(LD_16, TwoRegisters(DE, IMM_16), _, _)) ::
|
||||
(f, add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) ::
|
||||
xs if de != "" =>
|
||||
load.copy(registers = TwoRegisters(BC, IMM_16)) ::
|
||||
ZLine.registers(ADD_16, HL, BC) ::
|
||||
inlineVars(hl, bc, de, xs)
|
||||
if (f.importanceAfter.getRegister(BC) == Important) {
|
||||
ZLine.register(PUSH, DE) :: load :: add :: ZLine.register(POP, DE) :: inlineVars(hl, bc, de, xs)
|
||||
} else {
|
||||
load.copy(registers = TwoRegisters(BC, IMM_16)) ::
|
||||
ZLine.registers(ADD_16, HL, BC) ::
|
||||
inlineVars(hl, bc, de, xs)
|
||||
}
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), a1@MemoryAddressConstant(th1), _) ::
|
||||
ZLine(ADD_16, TwoRegisters(HL, reg@(DE | BC)), _, _) ::
|
||||
ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), a2@MemoryAddressConstant(th2), _) ::
|
||||
xs if hl != "" && th1.name != hl && th2.name != hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), a1@MemoryAddressConstant(th1), _)) ::
|
||||
(_, ZLine(ADD_16, TwoRegisters(HL, reg@(DE | BC)), _, _)) ::
|
||||
(_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), a2@MemoryAddressConstant(th2), _)) ::
|
||||
xs if hl != "" && th1.name != hl && th2.name != hl=>
|
||||
// bytes before: 3 + 1 + 3 = 7
|
||||
// cycles before: 16 + 11 + 16 = 43
|
||||
// bytes after: 3 + 1 + 3 + 3 + 1 + 3 = 14
|
||||
@ -330,99 +339,105 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
ZLine.ldAbs8(a2 + 1, A) ::
|
||||
inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ::
|
||||
(loadConst@ZLine(LD_16, TwoRegisters(BC, constSource), _, _)) ::
|
||||
(add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) ::
|
||||
(_, loadConst@ZLine(LD_16, TwoRegisters(BC, constSource), _, _)) ::
|
||||
(_, add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) :: xs if th.name == bc =>
|
||||
ZLine.ld8(B, H) :: ZLine.ld8(C, L) ::
|
||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ::
|
||||
(loadConst@ZLine(LD_16, TwoRegisters(DE, constSource), _, _)) ::
|
||||
(add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) ::
|
||||
(_, loadConst@ZLine(LD_16, TwoRegisters(DE, constSource), _, _)) ::
|
||||
(_, add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) :: xs if th.name == de =>
|
||||
ZLine.ld8(D, H) :: ZLine.ld8(E, L) ::
|
||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||
add.copy(registers = TwoRegisters(HL, DE)) :: inlineVars(hl, bc, de, xs)
|
||||
// TODO: above with regs swapped
|
||||
|
||||
case (loadConst@ZLine(LD_16, TwoRegisters(t, constSource), _, _)) ::
|
||||
ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ::
|
||||
(add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == bc && t == t2 && t != HL =>
|
||||
case (_, loadConst@ZLine(LD_16, TwoRegisters(t, constSource), _, _)) ::
|
||||
(_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _)) ::
|
||||
(_, add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == bc && t == t2 && t != HL =>
|
||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case (loadConst@ZLine(LD_16, TwoRegisters(t, constSource),_,_)) ::
|
||||
ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ::
|
||||
(add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == de && t == t2 && t != HL =>
|
||||
case (_, loadConst@ZLine(LD_16, TwoRegisters(t, constSource),_,_)) ::
|
||||
(_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _)) ::
|
||||
(_, add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == de && t == t2 && t != HL =>
|
||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||
add.copy(registers = TwoRegisters(HL, DE)) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(H, B) :: ZLine.ld8(L, C) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(B, H) :: ZLine.ld8(C, L) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(H, D) :: ZLine.ld8(L, E) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(D, H) :: ZLine.ld8(E, L) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(D, B) :: ZLine.ld8(E, C) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(B, D) :: ZLine.ld8(C, E) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(DE, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(D, H) :: ZLine.ld8(E, L) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(H, D) :: ZLine.ld8(L, E) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(B, H) :: ZLine.ld8(C, L) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(H, B) :: ZLine.ld8(L, C) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(BC, MEM_ABS_16), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(B, D) :: ZLine.ld8(C, E) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(D, B) :: ZLine.ld8(E, C) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(A, L) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(L, A) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(A, C) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(C, A) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(A, E) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), MemoryAddressConstant(th), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(E, A) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(A, H) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == hl =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == hl =>
|
||||
ZLine.ld8(H, A) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(A, B) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == bc =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == bc =>
|
||||
ZLine.ld8(B, A) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD, TwoRegisters(A, MEM_ABS_8), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(A, D) :: inlineVars(hl, bc, de, xs)
|
||||
case ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) :: xs if th.name == de =>
|
||||
case (_, ZLine(LD, TwoRegisters(MEM_ABS_8, A), CompoundConstant(MathOperator.Plus, MemoryAddressConstant(th), NumericConstant(1, _)), _) ) :: xs if th.name == de =>
|
||||
ZLine.ld8(D, A) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case (x@ZLine(CALL, _, _, _)) :: xs =>
|
||||
case (_, l1@ZLine(LD_16, TwoRegisters(BC, IMM_16), _, _)) :: (_, l2@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) :: xs if bc != "" =>
|
||||
ZLine.register(PUSH, BC) :: l1 :: l2 :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case (_, l1@ZLine(LD_16, TwoRegisters(DE, IMM_16), _, _)) :: (_, l2@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) :: xs if de != "" =>
|
||||
ZLine.register(PUSH, DE) :: l1 :: l2 :: ZLine.register(POP, DE) :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case (_, x@ZLine(CALL, _, _, _)) :: xs =>
|
||||
if (bc != "") {
|
||||
ZLine.register(PUSH, BC) :: x :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
||||
} else if (de != "") {
|
||||
@ -432,18 +447,18 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
||||
}
|
||||
|
||||
|
||||
case x :: ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) :: xs if x.changesRegister(HL) && th.name == hl =>
|
||||
x :: inlineVars(hl, bc, de, xs)
|
||||
case x :: ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _) :: xs if x.changesRegister(BC) && th.name == bc =>
|
||||
x :: inlineVars(hl, bc, de, xs)
|
||||
case x :: ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _) :: xs if x.changesRegister(DE) && th.name == de =>
|
||||
x :: inlineVars(hl, bc, de, xs)
|
||||
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(HL) && th.name == hl =>
|
||||
x._2 :: inlineVars(hl, bc, de, xs)
|
||||
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(BC) && th.name == bc =>
|
||||
x._2 :: inlineVars(hl, bc, de, xs)
|
||||
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(DE) && th.name == de =>
|
||||
x._2 :: inlineVars(hl, bc, de, xs)
|
||||
|
||||
case x :: _ if bc != "" && x.changesRegister(BC) => throw new IllegalStateException()
|
||||
case x :: _ if de != "" && x.changesRegister(DE) => throw new IllegalStateException()
|
||||
case x :: _ if hl != "" && x.changesRegister(HL) => throw new IllegalStateException()
|
||||
case x :: _ if bc != "" && x._2.changesRegister(BC) => throw new IllegalStateException()
|
||||
case x :: _ if de != "" && x._2.changesRegister(DE) => throw new IllegalStateException()
|
||||
case x :: _ if hl != "" && x._2.changesRegister(HL) => throw new IllegalStateException()
|
||||
|
||||
case x :: xs => x :: inlineVars(hl, bc, de, xs)
|
||||
case x :: xs => x._2 :: inlineVars(hl, bc, de, xs)
|
||||
case Nil => Nil
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user