mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-12 19:29:51 +00:00
8080: Fix optimizations near ifs
This commit is contained in:
parent
34254314a6
commit
dfda9f9283
@ -48,6 +48,8 @@ This matches both the CC65 behaviour and the return values from `readkey()`.
|
|||||||
|
|
||||||
* 8080/Z80: compiler crash when compiling conditions;
|
* 8080/Z80: compiler crash when compiling conditions;
|
||||||
|
|
||||||
|
* 8080/Z80: miscompilation of code after `if` statements;
|
||||||
|
|
||||||
* 8080/Z80: miscompilation near multiplication;
|
* 8080/Z80: miscompilation near multiplication;
|
||||||
|
|
||||||
* Z80: miscompilation when using stack variables.
|
* Z80: miscompilation when using stack variables.
|
||||||
|
@ -795,17 +795,20 @@ object AlwaysGoodI80Optimizations {
|
|||||||
|
|
||||||
val FreeHL = new RuleBasedAssemblyOptimization("Free HL",
|
val FreeHL = new RuleBasedAssemblyOptimization("Free HL",
|
||||||
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
needsFlowInfo = FlowInfoRequirement.BackwardFlow,
|
||||||
|
// 0
|
||||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL, ZRegister.A)) ~~> (code =>
|
(Elidable & Is8BitLoadTo(ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL, ZRegister.A)) ~~> (code =>
|
||||||
List(
|
List(
|
||||||
code(1).copy(registers = TwoRegisters(ZRegister.A, code(1).registers.asInstanceOf[TwoRegisters].source)),
|
code(1).copy(registers = TwoRegisters(ZRegister.A, code(1).registers.asInstanceOf[TwoRegisters].source)),
|
||||||
code.head.copy(opcode = LD, registers = TwoRegisters(ZRegister.MEM_ABS_8, ZRegister.A)),
|
code.head.copy(opcode = LD, registers = TwoRegisters(ZRegister.MEM_ABS_8, ZRegister.A)),
|
||||||
)),
|
)),
|
||||||
|
// 1
|
||||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
||||||
List(
|
List(
|
||||||
code.head.copy(opcode = LD, registers = TwoRegisters(ZRegister.A, ZRegister.MEM_ABS_8)),
|
code.head.copy(opcode = LD, registers = TwoRegisters(ZRegister.A, ZRegister.MEM_ABS_8)),
|
||||||
)),
|
)),
|
||||||
|
// 2
|
||||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||||
(Elidable & IsRegular8BitLoadFrom(ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.A)) ~~> (code =>
|
(Elidable & IsRegular8BitLoadFrom(ZRegister.MEM_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.A)) ~~> (code =>
|
||||||
List(
|
List(
|
||||||
@ -813,12 +816,14 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(1).copy(registers = TwoRegisters(code(1).registers.asInstanceOf[TwoRegisters].target, ZRegister.A)),
|
code(1).copy(registers = TwoRegisters(code(1).registers.asInstanceOf[TwoRegisters].target, ZRegister.A)),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 3
|
||||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
||||||
List(
|
List(
|
||||||
code.head.copy(registers = TwoRegisters(ZRegister.DE, ZRegister.IMM_16))
|
code.head.copy(registers = TwoRegisters(ZRegister.DE, ZRegister.IMM_16))
|
||||||
)),
|
)),
|
||||||
|
// 4
|
||||||
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
(Elidable & Is16BitLoad(ZRegister.HL, ZRegister.IMM_16)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> (code =>
|
||||||
@ -826,6 +831,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code.head.copy(registers = TwoRegisters(ZRegister.BC, ZRegister.IMM_16))
|
code.head.copy(registers = TwoRegisters(ZRegister.BC, ZRegister.IMM_16))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 5
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -835,6 +841,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(2).copy(registers = OneRegister(ZRegister.BC))
|
code(2).copy(registers = OneRegister(ZRegister.BC))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 6
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -844,6 +851,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(2).copy(registers = OneRegister(ZRegister.BC))
|
code(2).copy(registers = OneRegister(ZRegister.BC))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 7
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -853,6 +861,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(2).copy(registers = OneRegister(ZRegister.DE))
|
code(2).copy(registers = OneRegister(ZRegister.DE))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 8
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -862,6 +871,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(2).copy(registers = OneRegister(ZRegister.DE))
|
code(2).copy(registers = OneRegister(ZRegister.DE))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 9
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -873,6 +883,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code(2).copy(registers = OneRegister(ZRegister.BC))
|
code(2).copy(registers = OneRegister(ZRegister.BC))
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
// 10
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
(Elidable & HasOpcodeIn(Set(INC_16, DEC_16, PUSH, POP)) & HasRegisterParam(ZRegister.HL)) ~
|
||||||
@ -885,6 +896,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
)),
|
)),
|
||||||
|
|
||||||
|
|
||||||
|
// 11
|
||||||
// 2 bytes more, but 3 cycles fewer and frees BC
|
// 2 bytes more, but 3 cycles fewer and frees BC
|
||||||
(Elidable & Is16BitLoad(ZRegister.BC, ZRegister.IMM_16) & MatchParameter(0)) ~
|
(Elidable & Is16BitLoad(ZRegister.BC, ZRegister.IMM_16) & MatchParameter(0)) ~
|
||||||
(Linear & Not(Concerns(ZRegister.BC)) & Not(Concerns(ZRegister.HL))).*.capture(1) ~
|
(Linear & Not(Concerns(ZRegister.BC)) & Not(Concerns(ZRegister.HL))).*.capture(1) ~
|
||||||
@ -903,48 +915,57 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// 12
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.DE))
|
List(ZLine.register(PUSH, ZRegister.DE))
|
||||||
},
|
},
|
||||||
|
// 13
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.BC))
|
List(ZLine.register(PUSH, ZRegister.BC))
|
||||||
},
|
},
|
||||||
|
// 14
|
||||||
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L)) ~
|
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.HL))
|
List(ZLine.register(PUSH, ZRegister.HL))
|
||||||
},
|
},
|
||||||
|
// 15
|
||||||
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L)) ~
|
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.HL))
|
List(ZLine.register(PUSH, ZRegister.HL))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 16
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.E)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.D)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.DE))
|
List(ZLine.register(PUSH, ZRegister.DE))
|
||||||
},
|
},
|
||||||
|
// 17
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.BC))
|
List(ZLine.register(PUSH, ZRegister.BC))
|
||||||
},
|
},
|
||||||
|
// 18
|
||||||
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L)) ~
|
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.L)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.H)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.HL))
|
List(ZLine.register(PUSH, ZRegister.HL))
|
||||||
},
|
},
|
||||||
|
// 19
|
||||||
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L)) ~
|
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.L)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.H)) ~
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> {_ =>
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> {_ =>
|
||||||
List(ZLine.register(PUSH, ZRegister.HL))
|
List(ZLine.register(PUSH, ZRegister.HL))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 20
|
||||||
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.H, ZRegister.B)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.L, ZRegister.C)) ~
|
||||||
(Elidable & HasOpcode(EX_DE_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { _ =>
|
(Elidable & HasOpcode(EX_DE_HL) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { _ =>
|
||||||
@ -953,48 +974,57 @@ object AlwaysGoodI80Optimizations {
|
|||||||
ZLine.ld8(ZRegister.E, ZRegister.C))
|
ZLine.ld8(ZRegister.E, ZRegister.C))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 21
|
||||||
Is8BitLoad(ZRegister.D, ZRegister.H) ~
|
Is8BitLoad(ZRegister.D, ZRegister.H) ~
|
||||||
Is8BitLoad(ZRegister.E, ZRegister.L) ~
|
Is8BitLoad(ZRegister.E, ZRegister.L) ~
|
||||||
(Elidable & HasOpcode(EX_DE_HL)) ~~> { code =>
|
(Elidable & HasOpcode(EX_DE_HL)) ~~> { code =>
|
||||||
code.init
|
code.init
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 22
|
||||||
Is8BitLoad(ZRegister.H, ZRegister.D) ~
|
Is8BitLoad(ZRegister.H, ZRegister.D) ~
|
||||||
Is8BitLoad(ZRegister.L, ZRegister.E) ~
|
Is8BitLoad(ZRegister.L, ZRegister.E) ~
|
||||||
(Elidable & HasOpcode(EX_DE_HL)) ~~> { code =>
|
(Elidable & HasOpcode(EX_DE_HL)) ~~> { code =>
|
||||||
code.init
|
code.init
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 23
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//24
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.H) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.H) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 25
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.E) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.E) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 26
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.D) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.D) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 27
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.C) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.C) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0)))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 28
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.B) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoad(ZRegister.A, ZRegister.B) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 29
|
||||||
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.B)) ~
|
(Elidable & Is8BitLoad(ZRegister.D, ZRegister.B)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.C)) ~
|
(Elidable & Is8BitLoad(ZRegister.E, ZRegister.C)) ~
|
||||||
(Not(Concerns(ZRegister.DE)) & Not(Concerns(ZRegister.BC))).* ~
|
(Not(Concerns(ZRegister.DE)) & Not(Concerns(ZRegister.BC))).* ~
|
||||||
@ -1002,6 +1032,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code.drop(2).init :+ code.last.copy(registers = TwoRegisters(ZRegister.HL, ZRegister.BC))
|
code.drop(2).init :+ code.last.copy(registers = TwoRegisters(ZRegister.HL, ZRegister.BC))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 30
|
||||||
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.D)) ~
|
(Elidable & Is8BitLoad(ZRegister.B, ZRegister.D)) ~
|
||||||
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.E)) ~
|
(Elidable & Is8BitLoad(ZRegister.C, ZRegister.E)) ~
|
||||||
(Not(Concerns(ZRegister.DE)) & Not(Concerns(ZRegister.BC))).* ~
|
(Not(Concerns(ZRegister.DE)) & Not(Concerns(ZRegister.BC))).* ~
|
||||||
@ -1009,21 +1040,25 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code.drop(2).init :+ code.last.copy(registers = TwoRegisters(ZRegister.HL, ZRegister.DE))
|
code.drop(2).init :+ code.last.copy(registers = TwoRegisters(ZRegister.HL, ZRegister.DE))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 31
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.H) & MatchImmediate(1)) ~
|
(Elidable & Is8BitLoadTo(ZRegister.H) & MatchImmediate(1)) ~
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.L) & MatchImmediate(0)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoadTo(ZRegister.L) & MatchImmediate(0)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldImm16(ZRegister.HL, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
List(ZLine.ldImm16(ZRegister.HL, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 32
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.D) & MatchImmediate(1)) ~
|
(Elidable & Is8BitLoadTo(ZRegister.D) & MatchImmediate(1)) ~
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.E) & MatchImmediate(0)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoadTo(ZRegister.E) & MatchImmediate(0)) ~~> { (_, ctx) =>
|
||||||
List(ZLine.ldImm16(ZRegister.DE, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
List(ZLine.ldImm16(ZRegister.DE, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 33
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.B) & MatchImmediate(1)) ~
|
(Elidable & Is8BitLoadTo(ZRegister.B) & MatchImmediate(1)) ~
|
||||||
(Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (_, ctx) =>
|
(Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (_, 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))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 34
|
||||||
(Elidable & Is8BitLoad(A, MEM_ABS_8) & MatchParameter(1)) ~
|
(Elidable & Is8BitLoad(A, MEM_ABS_8) & MatchParameter(1)) ~
|
||||||
(Not(Concerns(ZRegister.HL)) & IsNotALabelUsedManyTimes).*.capture(5) ~
|
(Not(Concerns(ZRegister.HL)) & IsNotALabelUsedManyTimes).*.capture(5) ~
|
||||||
Where(ctx => ctx.isExternallyLinearBlock(5)) ~
|
Where(ctx => ctx.isExternallyLinearBlock(5)) ~
|
||||||
@ -1032,6 +1067,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
code.head.copy(registers = TwoRegisters(A, MEM_HL), parameter = Constant.Zero) ::
|
code.head.copy(registers = TwoRegisters(A, MEM_HL), parameter = Constant.Zero) ::
|
||||||
code.tail.init),
|
code.tail.init),
|
||||||
|
|
||||||
|
// 35
|
||||||
// TODO: this is a bit controversial
|
// TODO: this is a bit controversial
|
||||||
// 41 cycles 6 bytes → 24 cycles 8 bytes
|
// 41 cycles 6 bytes → 24 cycles 8 bytes
|
||||||
MultipleAssemblyRules(Seq(BC, DE).map{ reg =>
|
MultipleAssemblyRules(Seq(BC, DE).map{ reg =>
|
||||||
@ -1051,6 +1087,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// 36
|
||||||
(Elidable & Is8BitLoadTo(E)).capture(1) ~
|
(Elidable & Is8BitLoadTo(E)).capture(1) ~
|
||||||
(Not(Concerns(A)) & Not(Concerns(DE))).*.capture(2) ~
|
(Not(Concerns(A)) & Not(Concerns(DE))).*.capture(2) ~
|
||||||
(Elidable & Is8BitLoadTo(D)).capture(3) ~
|
(Elidable & Is8BitLoadTo(D)).capture(3) ~
|
||||||
@ -1066,6 +1103,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
ctx.get[List[ZLine]](7).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(source = BC)))
|
ctx.get[List[ZLine]](7).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(source = BC)))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 37
|
||||||
(Elidable & Is8BitLoadTo(C)).capture(1) ~
|
(Elidable & Is8BitLoadTo(C)).capture(1) ~
|
||||||
(Not(Concerns(A)) & Not(Concerns(BC))).*.capture(2) ~
|
(Not(Concerns(A)) & Not(Concerns(BC))).*.capture(2) ~
|
||||||
(Elidable & Is8BitLoadTo(B)).capture(3) ~
|
(Elidable & Is8BitLoadTo(B)).capture(3) ~
|
||||||
@ -1081,6 +1119,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
ctx.get[List[ZLine]](7).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(source = DE)))
|
ctx.get[List[ZLine]](7).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(source = DE)))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 38
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(MEM_ABS_16, HL)) & MatchParameter(0)).captureLine(10) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(MEM_ABS_16, HL)) & MatchParameter(0)).captureLine(10) ~
|
||||||
(Linear & DoesntChangeMemoryAt(10) & Not(Concerns(HL))).*.capture(55) ~
|
(Linear & DoesntChangeMemoryAt(10) & Not(Concerns(HL))).*.capture(55) ~
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(HL, IMM_16)) & MatchParameter(0)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(HL, IMM_16)) & MatchParameter(0)) ~
|
||||||
@ -1088,6 +1127,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
ctx.get[List[ZLine]](55) ++ ctx.get[List[ZLine]](11).map(_.copy(registers = OneRegister(L))) :+ code.head
|
ctx.get[List[ZLine]](55) ++ ctx.get[List[ZLine]](11).map(_.copy(registers = OneRegister(L))) :+ code.head
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 39
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(MEM_ABS_16, HL)) & MatchParameter(0)).captureLine(10) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(MEM_ABS_16, HL)) & MatchParameter(0)).captureLine(10) ~
|
||||||
(Linear & DoesntChangeMemoryAt(10) & Not(Concerns(HL))).*.capture(55) ~
|
(Linear & DoesntChangeMemoryAt(10) & Not(Concerns(HL))).*.capture(55) ~
|
||||||
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(HL, IMM_16)) & MatchParameter(1)) ~
|
(Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(HL, IMM_16)) & MatchParameter(1)) ~
|
||||||
|
@ -177,8 +177,7 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions) {
|
|||||||
}
|
}
|
||||||
// if a jump leads inside the block, then it's internal
|
// if a jump leads inside the block, then it's internal
|
||||||
// if a jump leads outside the block, then it's external
|
// if a jump leads outside the block, then it's external
|
||||||
jumps --= labels
|
jumps == labels
|
||||||
jumps.isEmpty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def isStackPreservingBlock(i: Int): Boolean = {
|
def isStackPreservingBlock(i: Int): Boolean = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user