1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Z80: detect read/changed registers more accurately

This commit is contained in:
Karol Stasiak 2018-07-17 13:08:25 +02:00
parent 190b398711
commit 80aef5c412
2 changed files with 62 additions and 3 deletions

View File

@ -351,7 +351,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
POP |
DISCARD_A | DISCARD_BCDEIX | DISCARD_HL | DISCARD_F => false
case DJNZ => r == B
case DAA | NEG => r == A
case DAA | NEG | CPL => r == A
case LABEL | DI | EI | NOP | HALT => false
case _ => true // TODO
}
@ -376,7 +376,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
case OneRegister(IX | IY) => true
case _ => false
}
case LD_16 | ADD_16 => registers match {
case LD_16 | ADD_16 | ADC_16 | SBC_16 => registers match {
case TwoRegisters(IX | IY, _) => true
case _ => false
}
@ -386,6 +386,40 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
}
}
def readsRegisterAndOffset(r: ZRegister.Value, o: Int): Boolean = {
import ZOpcode._
import ZRegister._
r match {
case MEM_IX_D | MEM_IY_D =>
opcode match {
case LD => registers match {
case TwoRegistersOffset(_, s, p) => r == s && o == p
case _ => false
}
case ADD | ADC | OR | XOR | AND | SUB | SBC | CP |
INC | DEC | RL | RLC | RR | RRC | SLA | SLL | SRA | SRL => registers match {
case OneRegisterOffset(s, p) => r == s && o == p
case _ => false
}
case PUSH | INC_16 | DEC_16 => registers match {
case OneRegister(IX | IY) => true
case _ => false
}
case LD_16 => registers match {
case TwoRegisters(_, IX | IY) => true
case _ => false
}
case ADD_16 | ADC_16 | SBC_16 => registers match {
case TwoRegisters(_, IX | IY) => true
case TwoRegisters(IX | IY, _) => true
case _ => false
}
case _ => false // TODO
}
case _ => readsRegister(r)
}
}
def changesRegister(r: ZRegister.Value): Boolean = {
import ZOpcode._
import ZRegister._
@ -433,7 +467,7 @@ case class ZLine(opcode: ZOpcode.Value, registers: ZRegisters, parameter: Consta
case JP | JR | RET | RETI | RETN |
POP |
DISCARD_A | DISCARD_BCDEIX | DISCARD_HL | DISCARD_F => false
case ADD | ADC | OR | XOR | SUB | SBC | DAA | NEG => r == A
case ADD | ADC | AND | OR | XOR | SUB | SBC | DAA | NEG | CPL => r == A
case CP => false
case DJNZ => r == B
case LABEL | DI | EI | NOP | HALT => false

View File

@ -496,6 +496,15 @@ case class MatchTargetRegisterAndOffset(i: Int) extends AssemblyLinePattern {
}
}
case class MatchSoleRegisterAndOffset(i: Int) extends AssemblyLinePattern {
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
line.registers match {
case OneRegister(t) => ctx.addObject(i, RegisterAndOffset(t, 0))
case OneRegisterOffset(t, o) => ctx.addObject(i, RegisterAndOffset(t, o))
case _ => false
}
}
case class DoesntChangeMatchedRegisterAndOffset(i: Int) extends AssemblyLinePattern {
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = {
val ro = ctx.get[RegisterAndOffset](i)
@ -511,6 +520,22 @@ case class DoesntChangeMatchedRegisterAndOffset(i: Int) extends AssemblyLinePatt
}
}
case class DoesntConcernMatchedRegisterAndOffset(i: Int) extends AssemblyLinePattern {
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean = {
val ro = ctx.get[RegisterAndOffset](i)
import ZRegister._
ro.register match {
case AF | SP => false // ?
case MEM_ABS_8 | MEM_ABS_16 => !line.changesMemory && !line.readsMemory
case MEM_HL => !line.changesMemory && !line.readsMemory && !line.changesRegister(ZRegister.HL) && !line.readsRegister(ZRegister.HL)
case MEM_BC => !line.changesMemory && !line.readsMemory && !line.changesRegister(ZRegister.BC) && !line.readsRegister(ZRegister.BC)
case MEM_DE => !line.changesMemory && !line.readsMemory && !line.changesRegister(ZRegister.DE) && !line.readsRegister(ZRegister.DE)
case _ => !line.changesRegisterAndOffset(ro.register, ro.offset) && !line.readsRegisterAndOffset(ro.register, ro.offset)
}
}
}
case class MatchParameter(i: Int) extends AssemblyLinePattern {
override def matchLineTo(ctx: AssemblyMatchingContext, flowInfo: FlowInfo, line: ZLine): Boolean =
line.registers match {