diff --git a/src/main/scala/millfork/assembly/z80/ZLine.scala b/src/main/scala/millfork/assembly/z80/ZLine.scala index 1ef6e281..c1aa6118 100644 --- a/src/main/scala/millfork/assembly/z80/ZLine.scala +++ b/src/main/scala/millfork/assembly/z80/ZLine.scala @@ -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 diff --git a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala index 6c96b6fb..110a1f2b 100644 --- a/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/z80/opt/RuleBasedAssemblyOptimization.scala @@ -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 {