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:
parent
064a9d7022
commit
078b22869a
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user