1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-11 12:29:46 +00:00

8080: optimize some more cases of stack use

This commit is contained in:
Karol Stasiak 2020-04-05 23:13:43 +02:00
parent 064a9d7022
commit 078b22869a
3 changed files with 34 additions and 5 deletions

View File

@ -474,7 +474,7 @@ object AlwaysGoodI80Optimizations {
//27-31
for5LargeRegisters(register => {
(Elidable & HasOpcode(PUSH) & HasRegisterParam(register)) ~
(Linear & IsLocallyAlignable).*.capture(1) ~
(IsLocallyAlignable & Not(HasOpcode(POP) & HasRegisterParam(register))).*.capture(1) ~
Where(ctx => ctx.isAlignableBlock(1)) ~
(Elidable & HasOpcode(POP) & HasRegisterParam(register) & DoesntMatterWhatItDoesWith(register)) ~~> { (code, _) =>
shallowerStack(code.tail.init)
@ -482,11 +482,20 @@ object AlwaysGoodI80Optimizations {
}),
//32
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.AF)) ~
(Linear & Not(Changes(ZRegister.A)) & Not(ReadsStackPointer)).*.capture(2) ~
(Not(Changes(ZRegister.A)) & Not(ReadsStackPointer)).*.capture(2) ~
Where(ctx => ctx.isStackPreservingBlock(2)) ~
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.AF) & DoesntMatterWhatItDoesWithFlags) ~~> {code =>
code.tail.init
},
//32-36
for5LargeRegisters(register => {
(Elidable & HasOpcode(PUSH) & HasRegisterParam(register)) ~
(IsLocallyAlignable & Not(Changes(register))).*.capture(1) ~
Where(ctx => ctx.isAlignableBlock(1)) ~
(Elidable & HasOpcode(POP) & HasRegisterParam(register)) ~~> { (code, _) =>
shallowerStack(code.tail.init)
}
}),
)
private def shallowerStack(lines: List[ZLine]): List[ZLine] = lines match {

View File

@ -163,7 +163,7 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions) {
import millfork.assembly.z80.ZOpcode._
get[List[ZLine]](i).foreach {
// JSR and BSR are allowed
case ZLine0(RET | RST | RETI | RETN, _, _) =>
case ZLine0(RET | RST | RETI | RETN | BYTE, _, _) =>
return false
case ZLine0(JP | JR, OneRegister(_), _) =>
return false
@ -184,7 +184,7 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions) {
import millfork.assembly.z80.ZOpcode._
var pushCount = 0
get[List[ZLine]](i).foreach {
case ZLine0(RET | RST | RETI | RETN, _, _) =>
case ZLine0(RET | RST | RETI | RETN | BYTE, _, _) =>
return false
case ZLine0(PUSH, _, _) =>
pushCount += 1
@ -203,7 +203,7 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions) {
import ZRegister.{SP, HL, IMM_16}
@tailrec
def impl(list: List[ZLine]): Boolean = list match {
case ZLine0(PUSH | POP | CALL | RET | RETI | RETN | EX_SP | EXX | EX_AF_AF | RST | RSTV | HALT | STOP, _, _) :: _ => false
case ZLine0(PUSH | POP | CALL | RET | RETI | RETN | EX_SP | EXX | EX_AF_AF | RST | RSTV | HALT | STOP | BYTE, _, _) :: _ => false
case ZLine0(LD_DESP | LD_HLSP, _, c) :: xs => if (c.isProvablyInRange(2, 127)) impl(xs) else false
case ZLine0(LD_16, TwoRegisters(HL, IMM_16), c) :: ZLine0(ADD_16, TwoRegisters(HL, SP), _) :: xs => if (c.isProvablyInRange(2, 127)) impl(xs) else false
case ZLine0(_, TwoRegisters(SP, _), _) :: _ => false

View File

@ -871,4 +871,24 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
}
}
test("Some combinations of shifting and indexing") {
EmuZ80BenchmarkRun(
"""
|volatile byte x
|
|noinline void f() {
| pointer(x/8)[0] |= 0x80>>(x&7)
|}
|
|void main() {
| byte i
| for i,0,parallelto,255 { pointer(i)[0] = 0 }
| x = $91
| f()
|}
|""".stripMargin) { m =>
m.readByte(0x91/8) should be (0x80>>(0x91 & 7))
}
}
}