mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-26 20:33:02 +00:00
Z80: detect read/changed registers more accurately
This commit is contained in:
parent
190b398711
commit
80aef5c412
@ -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
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user