mirror of
https://github.com/KarolS/millfork.git
synced 2025-02-06 17:30:05 +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
|
package millfork.assembly.z80.opt
|
||||||
|
|
||||||
import millfork.assembly.AssemblyOptimization
|
import millfork.assembly.AssemblyOptimization
|
||||||
import millfork.assembly.z80.{opt, _}
|
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
|
||||||
@ -786,6 +786,25 @@ object AlwaysGoodI80Optimizations {
|
|||||||
(Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (code, ctx) =>
|
(Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (code, ctx) =>
|
||||||
List(ZLine.ldImm16(ZRegister.BC, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
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",
|
val UnusedCodeRemoval = new RuleBasedAssemblyOptimization("Unreachable code removal",
|
||||||
|
@ -124,7 +124,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
log.debug(s"Inlining $v to register pair HL")
|
log.debug(s"Inlining $v to register pair HL")
|
||||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||||
val newCode = inlineVars(v, "", "", oldCode.map(_._2))
|
val newCode = inlineVars(v, "", "", oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -138,7 +138,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
log.debug(s"Inlining $v to register pair BC")
|
log.debug(s"Inlining $v to register pair BC")
|
||||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||||
val newCode = inlineVars("", v, "", oldCode.map(_._2))
|
val newCode = inlineVars("", v, "", oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -153,7 +153,7 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
|||||||
case (v, range, _) =>
|
case (v, range, _) =>
|
||||||
log.debug(s"Inlining $v to register pair DE")
|
log.debug(s"Inlining $v to register pair DE")
|
||||||
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
val oldCode = vs.codeWithFlow.slice(range.start, range.end)
|
||||||
val newCode = inlineVars("", "", v, oldCode.map(_._2))
|
val newCode = inlineVars("", "", v, oldCode)
|
||||||
reportOptimizedBlock(oldCode, newCode)
|
reportOptimizedBlock(oldCode, newCode)
|
||||||
output ++= newCode
|
output ++= newCode
|
||||||
i = range.end
|
i = range.end
|
||||||
@ -192,15 +192,16 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
code match {
|
code match {
|
||||||
|
|
||||||
case (_, ZLine(LD_16, TwoRegisters(BC, IMM_16), _, true))::
|
case (_, ZLine(LD_16, TwoRegisters(BC, IMM_16), _, true))::
|
||||||
(i, ZLine(ADD_16, TwoRegisters(HL, BC), _, true)) :: xs if target == BC =>
|
(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)
|
else canBeInlined(vname, synced = true, target, xs)
|
||||||
|
|
||||||
case (_, ZLine(LD_16, TwoRegisters(DE, IMM_16), _, true))::
|
case (_, ZLine(LD_16, TwoRegisters(DE, IMM_16), _, true))::
|
||||||
(i, ZLine(ADD_16, TwoRegisters(HL, DE), _, true)) :: xs if target == DE =>
|
(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)
|
else canBeInlined(vname, synced = true, target, xs)
|
||||||
|
|
||||||
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th1), true)) ::
|
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] = {
|
def inlineVars(hl: String, bc: String, de: String, code: List[(FlowInfo, ZLine)]): List[ZLine] = {
|
||||||
// if (code.nonEmpty) println(code.head)
|
// if (code.nonEmpty) println(code.head)
|
||||||
code match {
|
code match {
|
||||||
|
|
||||||
case (load@ZLine(LD_16, TwoRegisters(BC, IMM_16), _, _)) ::
|
case (_, load@ZLine(LD_16, TwoRegisters(BC, IMM_16), _, _)) ::
|
||||||
ZLine(ADD_16, TwoRegisters(HL, BC), _, _) ::
|
(f, add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) ::
|
||||||
xs if bc != "" =>
|
xs if bc != "" =>
|
||||||
load.copy(registers = TwoRegisters(DE, IMM_16)) ::
|
if (f.importanceAfter.getRegister(DE) == Important) {
|
||||||
ZLine.registers(ADD_16, HL, DE) ::
|
ZLine.register(PUSH, BC) :: load :: add :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
||||||
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), _, _)) ::
|
case (_, load@ZLine(LD_16, TwoRegisters(DE, IMM_16), _, _)) ::
|
||||||
ZLine(ADD_16, TwoRegisters(HL, DE), _, _) ::
|
(f, add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) ::
|
||||||
xs if de != "" =>
|
xs if de != "" =>
|
||||||
load.copy(registers = TwoRegisters(BC, IMM_16)) ::
|
if (f.importanceAfter.getRegister(BC) == Important) {
|
||||||
ZLine.registers(ADD_16, HL, BC) ::
|
ZLine.register(PUSH, DE) :: load :: add :: ZLine.register(POP, DE) :: inlineVars(hl, bc, de, xs)
|
||||||
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), _) ::
|
case (_, ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), a1@MemoryAddressConstant(th1), _)) ::
|
||||||
ZLine(ADD_16, TwoRegisters(HL, reg@(DE | BC)), _, _) ::
|
(_, ZLine(ADD_16, TwoRegisters(HL, reg@(DE | BC)), _, _)) ::
|
||||||
ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), a2@MemoryAddressConstant(th2), _) ::
|
(_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), a2@MemoryAddressConstant(th2), _)) ::
|
||||||
xs if hl != "" && th1.name != hl && th2.name != hl =>
|
xs if hl != "" && th1.name != hl && th2.name != hl=>
|
||||||
// bytes before: 3 + 1 + 3 = 7
|
// bytes before: 3 + 1 + 3 = 7
|
||||||
// cycles before: 16 + 11 + 16 = 43
|
// cycles before: 16 + 11 + 16 = 43
|
||||||
// bytes after: 3 + 1 + 3 + 3 + 1 + 3 = 14
|
// bytes after: 3 + 1 + 3 + 3 + 1 + 3 = 14
|
||||||
@ -330,99 +339,105 @@ object WordVariableToRegisterOptimization extends AssemblyOptimization[ZLine] {
|
|||||||
ZLine.ldAbs8(a2 + 1, A) ::
|
ZLine.ldAbs8(a2 + 1, A) ::
|
||||||
inlineVars(hl, bc, de, xs)
|
inlineVars(hl, bc, de, xs)
|
||||||
|
|
||||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ::
|
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) ::
|
||||||
(loadConst@ZLine(LD_16, TwoRegisters(BC, constSource), _, _)) ::
|
(_, loadConst@ZLine(LD_16, TwoRegisters(BC, constSource), _, _)) ::
|
||||||
(add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) :: xs if th.name == bc =>
|
(_, add@ZLine(ADD_16, TwoRegisters(HL, BC), _, _)) :: xs if th.name == bc =>
|
||||||
ZLine.ld8(B, H) :: ZLine.ld8(C, L) ::
|
ZLine.ld8(B, H) :: ZLine.ld8(C, L) ::
|
||||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||||
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
||||||
|
|
||||||
case ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _) ::
|
case (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) ::
|
||||||
(loadConst@ZLine(LD_16, TwoRegisters(DE, constSource), _, _)) ::
|
(_, loadConst@ZLine(LD_16, TwoRegisters(DE, constSource), _, _)) ::
|
||||||
(add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) :: xs if th.name == de =>
|
(_, add@ZLine(ADD_16, TwoRegisters(HL, DE), _, _)) :: xs if th.name == de =>
|
||||||
ZLine.ld8(D, H) :: ZLine.ld8(E, L) ::
|
ZLine.ld8(D, H) :: ZLine.ld8(E, L) ::
|
||||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||||
add.copy(registers = TwoRegisters(HL, DE)) :: inlineVars(hl, bc, de, xs)
|
add.copy(registers = TwoRegisters(HL, DE)) :: inlineVars(hl, bc, de, xs)
|
||||||
// TODO: above with regs swapped
|
// TODO: above with regs swapped
|
||||||
|
|
||||||
case (loadConst@ZLine(LD_16, TwoRegisters(t, constSource), _, _)) ::
|
case (_, loadConst@ZLine(LD_16, TwoRegisters(t, constSource), _, _)) ::
|
||||||
ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ::
|
(_, 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 =>
|
(_, add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == bc && t == t2 && t != HL =>
|
||||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||||
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
add.copy(registers = TwoRegisters(HL, BC)) :: inlineVars(hl, bc, de, xs)
|
||||||
|
|
||||||
case (loadConst@ZLine(LD_16, TwoRegisters(t, constSource),_,_)) ::
|
case (_, loadConst@ZLine(LD_16, TwoRegisters(t, constSource),_,_)) ::
|
||||||
ZLine(LD_16, TwoRegisters(HL, MEM_ABS_16), MemoryAddressConstant(th), _) ::
|
(_, 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 =>
|
(_, add@ZLine(ADD_16, TwoRegisters(HL, t2), _, _)) :: xs if th.name == de && t == t2 && t != HL =>
|
||||||
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
loadConst.copy(registers = TwoRegisters(HL, constSource)) ::
|
||||||
add.copy(registers = TwoRegisters(HL, DE)) :: inlineVars(hl, bc, de, xs)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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 != "") {
|
if (bc != "") {
|
||||||
ZLine.register(PUSH, BC) :: x :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
ZLine.register(PUSH, BC) :: x :: ZLine.register(POP, BC) :: inlineVars(hl, bc, de, xs)
|
||||||
} else if (de != "") {
|
} 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 =>
|
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, HL), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(HL) && th.name == hl =>
|
||||||
x :: inlineVars(hl, bc, de, xs)
|
x._2 :: 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 =>
|
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, BC), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(BC) && th.name == bc =>
|
||||||
x :: inlineVars(hl, bc, de, xs)
|
x._2 :: 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 =>
|
case x :: (_, ZLine(LD_16, TwoRegisters(MEM_ABS_16, DE), MemoryAddressConstant(th), _)) :: xs if x._2.changesRegister(DE) && th.name == de =>
|
||||||
x :: inlineVars(hl, bc, de, xs)
|
x._2 :: inlineVars(hl, bc, de, xs)
|
||||||
|
|
||||||
case x :: _ if bc != "" && x.changesRegister(BC) => throw new IllegalStateException()
|
case x :: _ if bc != "" && x._2.changesRegister(BC) => throw new IllegalStateException()
|
||||||
case x :: _ if de != "" && x.changesRegister(DE) => throw new IllegalStateException()
|
case x :: _ if de != "" && x._2.changesRegister(DE) => throw new IllegalStateException()
|
||||||
case x :: _ if hl != "" && x.changesRegister(HL) => 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
|
case Nil => Nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user