diff --git a/src/main/scala/millfork/SeparatedList.scala b/src/main/scala/millfork/SeparatedList.scala index c58c848c..61f6c739 100644 --- a/src/main/scala/millfork/SeparatedList.scala +++ b/src/main/scala/millfork/SeparatedList.scala @@ -5,7 +5,7 @@ package millfork */ case class SeparatedList[T, S](head: T, tail: List[(S, T)]) { - def toPairList(initialSeparator: S) = (initialSeparator -> head) :: tail + def toPairList(initialSeparator: S): List[(S, T)] = (initialSeparator -> head) :: tail def size: Int = tail.size + 1 diff --git a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala index 41222882..27d6cec9 100644 --- a/src/main/scala/millfork/assembly/mos/AssemblyLine.scala +++ b/src/main/scala/millfork/assembly/mos/AssemblyLine.scala @@ -437,7 +437,7 @@ object AssemblyLine { def absolute(opcode: Opcode.Value, addr: Constant) = AssemblyLine(opcode, AddrMode.Absolute, addr) - def absoluteOrLongAbsolute(opcode: Opcode.Value, thing: ThingInMemory, options: CompilationOptions) = + def absoluteOrLongAbsolute(opcode: Opcode.Value, thing: ThingInMemory, options: CompilationOptions): AssemblyLine = if (thing.isFar(options)) AssemblyLine(opcode, AddrMode.LongAbsolute, thing.toAddress) else AssemblyLine(opcode, AddrMode.Absolute, thing.toAddress) diff --git a/src/main/scala/millfork/assembly/mos/opt/CmosOptimizations.scala b/src/main/scala/millfork/assembly/mos/opt/CmosOptimizations.scala index 2e483cd0..5f14a69f 100644 --- a/src/main/scala/millfork/assembly/mos/opt/CmosOptimizations.scala +++ b/src/main/scala/millfork/assembly/mos/opt/CmosOptimizations.scala @@ -12,7 +12,7 @@ import millfork.env._ */ object CmosOptimizations { - val StzAddrModes = Set(ZeroPage, ZeroPageX, Absolute, AbsoluteX) + val StzAddrModes: Set[AddrMode.Value] = Set(ZeroPage, ZeroPageX, Absolute, AbsoluteX) val ZeroStoreAsStz = new RuleBasedAssemblyOptimization("Zero store", needsFlowInfo = FlowInfoRequirement.ForwardFlow, diff --git a/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala b/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala index 01d5402c..cd7de367 100644 --- a/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/mos/opt/FlowAnalyzer.scala @@ -18,7 +18,7 @@ class FlowHolder(_statusBefore: () => List[CpuStatus], _importanceAfter: () => L case class FlowInfo(holder: FlowHolder, index: Int, _labelUseCountMap: () => Option[Map[String, Int]]) { lazy val statusBefore: CpuStatus = holder.statusBefore(index) - lazy val importanceAfter = holder.importanceAfter(index) + lazy val importanceAfter: CpuImportance = holder.importanceAfter(index) lazy val labelUseCountMap: Option[Map[String, Int]] = _labelUseCountMap() def hasClear(state: State.Value): Boolean = statusBefore.hasClear(state) diff --git a/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala index 3ed07c79..02760aea 100644 --- a/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/mos/opt/ReverseFlowAnalyzer.scala @@ -113,7 +113,7 @@ object ReverseFlowAnalyzer { val cache = new FlowCache[AssemblyLine, CpuImportance]("mos reverse") - val functionsThatReadC = Set("__adc_decimal", "__sbc_decimal") + val functionsThatReadC: Set[String] = Set("__adc_decimal", "__sbc_decimal") private val aluAdders = Set(Opcode.ADC, Opcode.SBC, Opcode.ISC, Opcode.DCP, Opcode.ADC_W, Opcode.SBC_W) private val readAsPointer = Set(AddrMode.IndexedZ, AddrMode.IndexedSY, AddrMode.IndexedY, AddrMode.LongIndexedY, AddrMode.LongIndexedZ, AddrMode.IndexedX, AddrMode.Indirect, AddrMode.AbsoluteIndexedX) private val absoluteLike = Set(AddrMode.ZeroPage, AddrMode.Absolute, AddrMode.LongAbsolute) diff --git a/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala b/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala index 34f64e1b..cacb2bde 100644 --- a/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala +++ b/src/main/scala/millfork/assembly/mos/opt/RuleBasedAssemblyOptimization.scala @@ -2,7 +2,7 @@ package millfork.assembly.mos.opt import millfork.{CompilationFlag, CompilationOptions} import millfork.assembly._ -import millfork.assembly.mos._ +import millfork.assembly.mos.{AddrMode, _} import millfork.assembly.opt.SingleStatus import millfork.compiler.LabelGenerator import millfork.env._ @@ -174,7 +174,7 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions, if (clazz.isInstance(t)) { t.asInstanceOf[AnyRef] } else { - if (i eq null) { + if (t.asInstanceOf[AnyRef] eq null) { log.fatal(s"Value at index $i is null") } else { log.fatal(s"Value at index $i is a ${t.getClass.getSimpleName}, not a ${clazz.getSimpleName}") @@ -893,7 +893,7 @@ case object IsNonvolatile extends TrivialAssemblyLinePattern { } case object ReadsX extends TrivialAssemblyLinePattern { - val XAddrModes = Set(AddrMode.AbsoluteX, AddrMode.IndexedX, AddrMode.ZeroPageX, AddrMode.AbsoluteIndexedX) + val XAddrModes: Set[AddrMode.Value] = Set(AddrMode.AbsoluteX, AddrMode.IndexedX, AddrMode.ZeroPageX, AddrMode.AbsoluteIndexedX) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ReadsXAlways(line.opcode) || XAddrModes(line.addrMode) @@ -902,7 +902,7 @@ case object ReadsX extends TrivialAssemblyLinePattern { } case object ReadsY extends TrivialAssemblyLinePattern { - val YAddrModes = Set(AddrMode.AbsoluteY, AddrMode.IndexedY, AddrMode.ZeroPageY) + val YAddrModes: Set[AddrMode.Value] = Set(AddrMode.AbsoluteY, AddrMode.IndexedY, AddrMode.ZeroPageY) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ReadsYAlways(line.opcode) || YAddrModes(line.addrMode) @@ -932,7 +932,7 @@ case object ConcernsAH extends TrivialAssemblyLinePattern { } case object ConcernsX extends TrivialAssemblyLinePattern { - val XAddrModes = Set(AddrMode.AbsoluteX, AddrMode.AbsoluteIndexedX, AddrMode.LongAbsoluteX, AddrMode.IndexedX, AddrMode.ZeroPageX) + val XAddrModes: Set[AddrMode.Value] = Set(AddrMode.AbsoluteX, AddrMode.AbsoluteIndexedX, AddrMode.LongAbsoluteX, AddrMode.IndexedX, AddrMode.ZeroPageX) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ConcernsXAlways(line.opcode) || XAddrModes(line.addrMode) @@ -941,7 +941,7 @@ case object ConcernsX extends TrivialAssemblyLinePattern { } case object ConcernsS extends TrivialAssemblyLinePattern { - val SAddrModes = Set(AddrMode.Stack, AddrMode.IndexedSY) + val SAddrModes: Set[AddrMode.Value] = Set(AddrMode.Stack, AddrMode.IndexedSY) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ConcernsSAlways(line.opcode) || SAddrModes(line.addrMode) @@ -950,7 +950,7 @@ case object ConcernsS extends TrivialAssemblyLinePattern { } case object ConcernsY extends TrivialAssemblyLinePattern { - val YAddrModes = Set(AddrMode.AbsoluteY, AddrMode.IndexedSY, AddrMode.IndexedY, AddrMode.LongIndexedY, AddrMode.ZeroPageY) + val YAddrModes: Set[AddrMode.Value] = Set(AddrMode.AbsoluteY, AddrMode.IndexedSY, AddrMode.IndexedY, AddrMode.LongIndexedY, AddrMode.ZeroPageY) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ConcernsYAlways(line.opcode) || YAddrModes(line.addrMode) @@ -959,7 +959,7 @@ case object ConcernsY extends TrivialAssemblyLinePattern { } case object ConcernsStack extends TrivialAssemblyLinePattern { - val SAddrModes = Set(AddrMode.IndexedSY, AddrMode.Stack) + val SAddrModes: Set[AddrMode.Value] = Set(AddrMode.IndexedSY, AddrMode.Stack) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ConcernsStackAlways(line.opcode) || SAddrModes(line.addrMode) @@ -968,7 +968,7 @@ case object ConcernsStack extends TrivialAssemblyLinePattern { } case object ConcernsIZ extends TrivialAssemblyLinePattern { - val IZAddrModes = Set(AddrMode.IndexedZ, AddrMode.LongIndexedZ) + val IZAddrModes: Set[AddrMode.Value] = Set(AddrMode.IndexedZ, AddrMode.LongIndexedZ) override def apply(line: AssemblyLine): Boolean = OpcodeClasses.ConcernsIZAlways(line.opcode) || IZAddrModes(line.addrMode) diff --git a/src/main/scala/millfork/assembly/z80/ZOpcode.scala b/src/main/scala/millfork/assembly/z80/ZOpcode.scala index 85d85efc..d40e7bd0 100644 --- a/src/main/scala/millfork/assembly/z80/ZOpcode.scala +++ b/src/main/scala/millfork/assembly/z80/ZOpcode.scala @@ -38,9 +38,9 @@ object ZOpcodeClasses { import ZOpcode._ - val RES_seq = IndexedSeq(RES0, RES1, RES2, RES3, RES4, RES5, RES6, RES7) - val SET_seq = IndexedSeq(SET0, SET1, SET2, SET3, SET4, SET5, SET6, SET7) - val BIT_seq = IndexedSeq(BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7) + val RES_seq: IndexedSeq[ZOpcode.Value] = IndexedSeq(RES0, RES1, RES2, RES3, RES4, RES5, RES6, RES7) + val SET_seq: IndexedSeq[ZOpcode.Value] = IndexedSeq(SET0, SET1, SET2, SET3, SET4, SET5, SET6, SET7) + val BIT_seq: IndexedSeq[ZOpcode.Value] = IndexedSeq(BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7) private val all_bit_seq = BIT_seq ++ RES_seq ++ SET_seq def singleBitOpcode(op:ZOpcode.Value): Int = 0x40 + all_bit_seq.indexOf(op) * 8 @@ -56,9 +56,9 @@ object ZOpcodeClasses { INI, INIR, OUTI, OUTIR, IND, INDR, OUTD, OUTDR, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR) ++ BIT ++ RES ++ SET - val NoopDiscards = Set(DISCARD_F, DISCARD_A, DISCARD_HL, DISCARD_BC, DISCARD_DE, DISCARD_IX, DISCARD_IY) + val NoopDiscards: Set[ZOpcode.Value] = Set(DISCARD_F, DISCARD_A, DISCARD_HL, DISCARD_BC, DISCARD_DE, DISCARD_IX, DISCARD_IY) - val ChangesAFAlways = Set( // TODO: ! + val ChangesAFAlways: Set[ZOpcode.Value] = Set( // TODO: ! DAA, ADD, ADC, SUB, SBC, XOR, OR, AND, INC, DEC, SCF, CCF, NEG, RIM, LDH_AC, LDH_AD, LD_AHLI, LD_AHLD, @@ -66,22 +66,22 @@ object ZOpcodeClasses { INI, INIR, OUTI, OUTIR, IND, INDR, OUTD, OUTDR, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, EXX, CALL, JR, JP, LABEL, DJNZ) - val ChangesBCAlways = Set( + val ChangesBCAlways: Set[ZOpcode.Value] = Set( INI, INIR, OUTI, OUTIR, IND, INDR, OUTD, OUTDR, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, EXX, CALL, JR, JP, LABEL, DJNZ) - val ChangesHLAlways = Set( + val ChangesHLAlways: Set[ZOpcode.Value] = Set( INI, INIR, OUTI, OUTIR, IND, INDR, OUTD, OUTDR, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, LD_AHLI, LD_AHLD, LD_HLIA, LD_HLDA, LD_HLSP, DSUB, RRHL, LHLX, EXX, EX_DE_HL, CALL, JR, JP, LABEL) - val ChangesDEAlways = Set( + val ChangesDEAlways: Set[ZOpcode.Value] = Set( LDI, LDIR, LDD, LDDR, LD_DESP, LD_DEHL, RLDE, EXX, EX_DE_HL, CALL, JR, JP, LABEL) val ChangesOnlyRegister: Set[ZOpcode.Value] = Set(INC, DEC, INC_16, DEC_16, POP, EX_SP, IN_C, IN_IMM, RL, RR, RLC, RRC, SLA, SRA, SRL, SLL) ++ SET ++ RES - val ChangesFirstRegister = Set(LD, LD_16, ADD_16, SBC_16) - val ChangesAAlways = Set(DAA, ADD, ADC, SUB, SBC, XOR, OR, AND, LD_AHLI, LD_AHLD, RIM) - val NonLinear = Set(JP, JR, CALL, LABEL, BYTE, EXX, EX_DE_HL, EX_SP, EXX, RET, RETI, RETN, HALT, RST, RSTV) + val ChangesFirstRegister: Set[ZOpcode.Value] = Set(LD, LD_16, ADD_16, SBC_16) + val ChangesAAlways: Set[ZOpcode.Value] = Set(DAA, ADD, ADC, SUB, SBC, XOR, OR, AND, LD_AHLI, LD_AHLD, RIM) + val NonLinear: Set[ZOpcode.Value] = Set(JP, JR, CALL, LABEL, BYTE, EXX, EX_DE_HL, EX_SP, EXX, RET, RETI, RETN, HALT, RST, RSTV) } diff --git a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala index ff85da61..7caa0005 100644 --- a/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala +++ b/src/main/scala/millfork/assembly/z80/opt/AlwaysGoodI80Optimizations.scala @@ -17,8 +17,8 @@ object AlwaysGoodI80Optimizations { def change8BitLoadTarget(line: ZLine, newTarget: ZRegister.Value): ZLine = { line match { - case ZLine0(LD, TwoRegistersOffset(_, s, o), p) => line.copy(registers = TwoRegistersOffset(newTarget, s, o)) - case ZLine0(LD, TwoRegisters(_, s), p) => line.copy(registers = TwoRegisters(newTarget, s)) + case ZLine0(LD, TwoRegistersOffset(_, s, o), _) => line.copy(registers = TwoRegistersOffset(newTarget, s, o)) + case ZLine0(LD, TwoRegisters(_, s), _) => line.copy(registers = TwoRegisters(newTarget, s)) } } @@ -277,7 +277,7 @@ object AlwaysGoodI80Optimizations { (Elidable & HasOpcode(INC_16) & HasRegisterParam(HL)) ~ (Linear & Not(Changes(HL)) & Not(Changes(DE))).*).capture(2) ~ (Elidable & Is8BitLoad(H, D)) ~ - (Elidable & Is8BitLoad(L, E)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(L, E)) ~~> { (_, ctx) => ctx.get[List[ZLine]](2) :+ ZLine.register(DEC_16, HL) }, // 66: @@ -287,7 +287,7 @@ object AlwaysGoodI80Optimizations { (Elidable & HasOpcode(INC_16) & HasRegisterParam(HL)) ~ (Linear & Not(Changes(HL)) & Not(Changes(BC))).*).capture(2) ~ (Elidable & Is8BitLoad(H, B)) ~ - (Elidable & Is8BitLoad(L, C)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(L, C)) ~~> { (_, ctx) => ctx.get[List[ZLine]](2) :+ ZLine.register(DEC_16, HL) }, @@ -433,7 +433,7 @@ object AlwaysGoodI80Optimizations { (Elidable & HasOpcode(PUSH) & HasRegisterParam(register)) ~ (Linear & IsLocallyAlignable).*.capture(1) ~ Where(ctx => ctx.isAlignableBlock(1)) ~ - (Elidable & HasOpcode(POP) & HasRegisterParam(register) & DoesntMatterWhatItDoesWith(register)) ~~> { (code, ctx) => + (Elidable & HasOpcode(POP) & HasRegisterParam(register) & DoesntMatterWhatItDoesWith(register)) ~~> { (code, _) => shallowerStack(code.tail.init) } }), @@ -466,7 +466,7 @@ object AlwaysGoodI80Optimizations { for5LargeRegisters(register => { (Elidable & HasOpcode(POP) & HasRegisterParam(register)) ~ (Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Concerns(register))).* ~ - (Elidable & HasOpcode(PUSH) & HasRegisterParam(register) & DoesntMatterWhatItDoesWith(register)) ~~> { (code, ctx) => + (Elidable & HasOpcode(PUSH) & HasRegisterParam(register) & DoesntMatterWhatItDoesWith(register)) ~~> { (code, _) => code.tail.init } }), @@ -519,31 +519,31 @@ object AlwaysGoodI80Optimizations { needsFlowInfo = FlowInfoRequirement.BothFlows, for7Registers(register => (Elidable & HasOpcode(ADD) & MatchRegister(ZRegister.A, 0) & HasRegisterParam(register) & MatchRegister(register, 1) & - DoesntMatterWhatItDoesWithFlags) ~~> ((code, ctx) => List(ZLine.ldImm8(ZRegister.A, (ctx.get[Int](0) + ctx.get[Int](1)) & 0xff))), + DoesntMatterWhatItDoesWithFlags) ~~> ((_, ctx) => List(ZLine.ldImm8(ZRegister.A, (ctx.get[Int](0) + ctx.get[Int](1)) & 0xff))), ), for7Registers(register => (Elidable & HasOpcode(ADD) & MatchRegister(ZRegister.A, 0) & HasRegisterParam(register) & MatchRegister(register, 1)) ~ - (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, asDecimal(ctx.get[Int](0) & 0xff, ctx.get[Int](1) & 0xff, _ + _).toInt & 0xff)) }, ), simplifiable16BitAddWithSplitTarget(ZRegister.H, ZRegister.L, ZRegister.HL, ZRegister.BC), simplifiable16BitAddWithSplitTarget(ZRegister.H, ZRegister.L, ZRegister.HL, ZRegister.DE), - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & MatchRegister(ZRegister.BC, 0) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & MatchRegister(ZRegister.BC, 0) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, ctx.get[Int](0) + ctx.get[Int](1))) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & MatchRegister(ZRegister.DE, 0) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & MatchRegister(ZRegister.DE, 0) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, ctx.get[Int](0) + ctx.get[Int](1))) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.HL)) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.HL)) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, 2 * ctx.get[Int](1) & 0xffff)) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & HasRegister(ZRegister.BC, 0) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & HasRegister(ZRegister.BC, 0) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, _) => Nil }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & HasRegister(ZRegister.DE, 0) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & HasRegister(ZRegister.DE, 0) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, _) => Nil }, @@ -555,18 +555,18 @@ object AlwaysGoodI80Optimizations { List(ZLine.register(DEC, A)) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & HasRegister(ZRegister.BC, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & HasRegister(ZRegister.BC, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, _) => List(ZLine.register(ZOpcode.INC_16, ZRegister.HL)) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & HasRegister(ZRegister.DE, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & HasRegister(ZRegister.DE, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, _) => List(ZLine.register(ZOpcode.INC_16, ZRegister.HL)) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & MatchRegister(ZRegister.BC, 0) & MatchConstantInHL(1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & MatchRegister(ZRegister.BC, 0) & MatchConstantInHL(1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, (ctx.get[Constant](1) + ctx.get[Int](0)).quickSimplify)) }, - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & MatchRegister(ZRegister.DE, 0) & MatchConstantInHL(1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.DE)) & MatchRegister(ZRegister.DE, 0) & MatchConstantInHL(1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, (ctx.get[Constant](1) + ctx.get[Int](0)).quickSimplify)) }, @@ -614,33 +614,33 @@ object AlwaysGoodI80Optimizations { else List(ZLine.ldImm8(ZRegister.A, value), code.last.copy(registers = NoRegisters)) }, - (Elidable & HasOpcode(ADD) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(ADD) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, (ctx.get[Constant](1) + ctx.get[Int](0)).quickSimplify)) }, - (Elidable & HasOpcode(SUB) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(SUB) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, (NumericConstant(ctx.get[Int](0) & 0xff, 1) - ctx.get[Constant](1)).quickSimplify)) }, - (Elidable & HasOpcode(OR) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(OR) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, CompoundConstant(MathOperator.Or, NumericConstant(ctx.get[Int](0) & 0xff, 1), ctx.get[Constant](1)).quickSimplify)) }, - (Elidable & HasOpcode(XOR) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(XOR) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, CompoundConstant(MathOperator.Exor, NumericConstant(ctx.get[Int](0) & 0xff, 1), ctx.get[Constant](1)).quickSimplify)) }, - (Elidable & HasOpcode(AND) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(AND) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, CompoundConstant(MathOperator.And, NumericConstant(ctx.get[Int](0) & 0xff, 1), ctx.get[Constant](1)).quickSimplify)) }, (Elidable & HasOpcode(ADD) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0)) ~ - (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, CompoundConstant(MathOperator.DecimalPlus, NumericConstant(ctx.get[Int](0) & 0xff, 1), ctx.get[Constant](1)).quickSimplify)) }, (Elidable & HasOpcode(SUB) & Match8BitImmediate(1) & MatchRegister(ZRegister.A, 0)) ~ - (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(code, ctx) => + (Elidable & HasOpcode(DAA) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => List(ZLine.ldImm8(ZRegister.A, CompoundConstant(MathOperator.DecimalMinus, NumericConstant(ctx.get[Int](0) & 0xff, 1), ctx.get[Constant](1)).quickSimplify)) }, @@ -855,7 +855,7 @@ object AlwaysGoodI80Optimizations { (Elidable & Is8BitLoadTo(ZRegister.H) & Has8BitImmediate(0)) ~ (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.BC)) & DoesntMatterWhatItDoesWithFlagsExceptCarry & - DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (code, ctx) => + DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (_, ctx) => val offset = ctx.get[Constant](0) ctx.get[List[ZLine]](1) ++ List( ZLine.imm8(ADD, offset.loByte), @@ -929,32 +929,32 @@ object AlwaysGoodI80Optimizations { }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.L) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0))) }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.HL, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.H) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.H) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify)) }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.E) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.E) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0))) }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.DE, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.D) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.D) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify)) }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.C) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.C) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, ctx.get[Constant](0))) }, (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(ZRegister.BC, ZRegister.MEM_ABS_16)) & MatchParameter(0)) ~ - (Elidable & Is8BitLoad(ZRegister.A, ZRegister.B) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (code, ctx) => + (Elidable & Is8BitLoad(ZRegister.A, ZRegister.B) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~~> { (_, ctx) => List(ZLine.ldAbs8(ZRegister.A, (ctx.get[Constant](0) + 1).quickSimplify)) }, @@ -973,17 +973,17 @@ object AlwaysGoodI80Optimizations { }, (Elidable & Is8BitLoadTo(ZRegister.H) & MatchImmediate(1)) ~ - (Elidable & Is8BitLoadTo(ZRegister.L) & MatchImmediate(0)) ~~> { (code, ctx) => + (Elidable & Is8BitLoadTo(ZRegister.L) & MatchImmediate(0)) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.HL, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify)) }, (Elidable & Is8BitLoadTo(ZRegister.D) & MatchImmediate(1)) ~ - (Elidable & Is8BitLoadTo(ZRegister.E) & MatchImmediate(0)) ~~> { (code, ctx) => + (Elidable & Is8BitLoadTo(ZRegister.E) & MatchImmediate(0)) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.DE, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify)) }, (Elidable & Is8BitLoadTo(ZRegister.B) & MatchImmediate(1)) ~ - (Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (code, ctx) => + (Elidable & Is8BitLoadTo(ZRegister.C) & MatchImmediate(0)) ~~> { (_, ctx) => List(ZLine.ldImm16(ZRegister.BC, (ctx.get[Constant](0) + ctx.get[Constant](1).asl(8)).quickSimplify)) }, @@ -1001,7 +1001,7 @@ object AlwaysGoodI80Optimizations { (Elidable & HasOpcode(PUSH) & HasRegisterParam(reg)) ~ (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(reg, IMM_16)) & MatchParameter(0)) ~ (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, reg))) ~ - (Elidable & HasOpcode(POP) & HasRegisterParam(reg) & DoesntMatterWhatItDoesWithFlagsExceptCarry & DoesntMatterWhatItDoesWith(A)) ~~> { (code, ctx) => + (Elidable & HasOpcode(POP) & HasRegisterParam(reg) & DoesntMatterWhatItDoesWithFlagsExceptCarry & DoesntMatterWhatItDoesWith(A)) ~~> { (_, ctx) => val offset = ctx.get[Constant](0) List( ZLine.ld8(A, L), @@ -1020,7 +1020,7 @@ object AlwaysGoodI80Optimizations { (Not(Concerns(HL)) & Not(Concerns(DE))).*.capture(4) ~ (Elidable & Is8BitLoad(H, B)).capture(5) ~ (Elidable & Is8BitLoad(L, C)).capture(6) ~ - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, DE)) & DoesntMatterWhatItDoesWith(BC) & DoesntMatterWhatItDoesWith(DE)).capture(7) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, DE)) & DoesntMatterWhatItDoesWith(BC) & DoesntMatterWhatItDoesWith(DE)).capture(7) ~~> { (_, ctx) => ctx.get[List[ZLine]](1).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(target = A))) ++ ctx.get[List[ZLine]](2) ++ ctx.get[List[ZLine]](3).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(target = H))) ++ @@ -1035,7 +1035,7 @@ object AlwaysGoodI80Optimizations { (Not(Concerns(BC)) & Not(Concerns(HL))).*.capture(4) ~ (Elidable & Is8BitLoad(H, D)).capture(5) ~ (Elidable & Is8BitLoad(L, E)).capture(6) ~ - (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, BC)) & DoesntMatterWhatItDoesWith(BC) & DoesntMatterWhatItDoesWith(DE)).capture(7) ~~> { (code, ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisters(TwoRegisters(HL, BC)) & DoesntMatterWhatItDoesWith(BC) & DoesntMatterWhatItDoesWith(DE)).capture(7) ~~> { (_, ctx) => ctx.get[List[ZLine]](1).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(target = A))) ++ ctx.get[List[ZLine]](2) ++ ctx.get[List[ZLine]](3).map(x => x.copy(registers = x.registers.asInstanceOf[TwoRegisters].copy(target = H))) ++ @@ -1328,7 +1328,7 @@ object AlwaysGoodI80Optimizations { & MatchRegister(ZRegister.A, 4) & MatchRegister(ZRegister.D, 5) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (_, ctx) => val product = ctx.get[Int](4) * ctx.get[Int](5) List(ZLine.ldImm8(ZRegister.A, product & 0xff)) }, @@ -1339,7 +1339,7 @@ object AlwaysGoodI80Optimizations { & MatchRegister(ZRegister.A, 4) & MatchRegister(ZRegister.DE, 5) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (_, ctx) => val product = ctx.get[Int](4) * ctx.get[Int](5) List(ZLine.ldImm16(ZRegister.HL, product & 0xffff)) }, @@ -1349,7 +1349,7 @@ object AlwaysGoodI80Optimizations { & RefersTo("__mul_u8u8u8", 0) & MatchRegister(ZRegister.D, 1) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (_, ctx) => val multiplicand = ctx.get[Int](1) if (multiplicand == 0) List(ZLine.ldImm8(A, 0)) else ZLine.ld8(ZRegister.D, ZRegister.A) :: compileMultiply(multiplicand, List(ZLine.register(ADD, ZRegister.D)), List(ZLine.register(ADD, ZRegister.A))) @@ -1360,7 +1360,7 @@ object AlwaysGoodI80Optimizations { & RefersTo("__mul_u8u8u8", 0) & MatchRegister(ZRegister.A, 1) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (_, ctx) => val multiplicand = ctx.get[Int](1) if (multiplicand == 0) List(ZLine.ldImm8(A, 0)) else ZLine.ld8(ZRegister.A, ZRegister.D) :: compileMultiply(multiplicand, List(ZLine.register(ADD, ZRegister.D)), List(ZLine.register(ADD, ZRegister.A))) @@ -1371,7 +1371,7 @@ object AlwaysGoodI80Optimizations { & RefersTo("__mul_u16u8u16", 0) & MatchRegister(ZRegister.A, 1) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (_, ctx) => val multiplicand = ctx.get[Int](1) if (multiplicand == 0) List(ZLine.ldImm16(HL, 0)) else ZLine.ld8(ZRegister.L, ZRegister.E) :: @@ -1384,7 +1384,7 @@ object AlwaysGoodI80Optimizations { & RefersTo("__mul_u16u8u16", 0) & MatchRegister(ZRegister.DE, 1) & DoesntMatterWhatItDoesWithFlags - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C, ZRegister.B, ZRegister.A)) ~~> { (_, ctx) => val multiplicand = ctx.get[Int](1) if (multiplicand == 0) List(ZLine.ldImm16(HL, 0)) else ZLine.ld8(ZRegister.L, ZRegister.A) :: @@ -1397,7 +1397,7 @@ object AlwaysGoodI80Optimizations { (Elidable & Is8BitLoad(D, A)) ~ (Elidable & Is8BitLoad(A, IMM_8)) ~ (Elidable & HasOpcode(CALL) & IsUnconditional & RefersTo("__mul_u8u8u8", 0) - & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (code, ctx) => + & DoesntMatterWhatItDoesWith(ZRegister.D, ZRegister.E, ZRegister.C)) ~~> { (code, _) => List(code(1).copy(registers = TwoRegisters(D, IMM_8)), code(2)) }, ) @@ -1411,7 +1411,7 @@ object AlwaysGoodI80Optimizations { (Elidable & IsLabelMatching(2) & MatchRegister(ZRegister.B, 1)) ~ Where(ctx => ctx.get[Int](1) > 0) ~ (Elidable & HasOpcodeIn(Set(ADD, SLA, SRL, SLL, RLC, RLCA, RRC, RRCA, RR, RL, RLA, RRA)) & Not(HasRegisterParam(ZRegister.B))).*.capture(5) ~ - (Elidable & HasOpcode(DJNZ) & MatchJumpTarget(2) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(DJNZ) & MatchJumpTarget(2) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => val iter = ctx.get[Int](1) val code = ctx.get[List[ZLine]](5) List.fill(iter)(code).flatten :+ ZLine.ldImm8(ZRegister.B, 0) @@ -1421,7 +1421,7 @@ object AlwaysGoodI80Optimizations { (Elidable & IsLabelMatching(2)) ~ (Elidable & HasOpcodeIn(Set(ADD, SLA, SRL, SLL, RLC, RLCA, RRC, RRCA, RR, RL, RLA, RRA)) & Not(HasRegisterParam(ZRegister.B))).*.capture(5) ~ (Elidable & IsLabelMatching(3)) ~ - (Elidable & HasOpcode(DJNZ) & MatchJumpTarget(2) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(DJNZ) & MatchJumpTarget(2) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => val iter = ctx.get[Int](1).-(1).&(0xff) val code = ctx.get[List[ZLine]](5) List.fill(iter)(code).flatten :+ ZLine.ldImm8(ZRegister.B, 0) @@ -1433,24 +1433,24 @@ object AlwaysGoodI80Optimizations { needsFlowInfo = FlowInfoRequirement.BothFlows, for7Registers(register => - (Elidable & HasOpcode(SLA) & HasRegisterParam(register) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(code,ctx) => + (Elidable & HasOpcode(SLA) & HasRegisterParam(register) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => val value = ctx.get[Int](1) List(ZLine.ldImm8(register, value.<<(1).&(0xff))) } ), - (Elidable & HasOpcode(ADD) & HasRegisterParam(ZRegister.A) & MatchRegister(ZRegister.A, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(code,ctx) => + (Elidable & HasOpcode(ADD) & HasRegisterParam(ZRegister.A) & MatchRegister(ZRegister.A, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => val value = ctx.get[Int](1) List(ZLine.ldImm8(ZRegister.A, value.<<(1).&(0xff))) }, - (Elidable & HasOpcode(ADD_16) & HasRegisterParam(ZRegister.HL) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(code,ctx) => + (Elidable & HasOpcode(ADD_16) & HasRegisterParam(ZRegister.HL) & MatchRegister(ZRegister.HL, 1) & DoesntMatterWhatItDoesWithFlags) ~~> {(_, ctx) => val value = ctx.get[Int](1) List(ZLine.ldImm16(ZRegister.HL, value.<<(1).&(0xffff))) }, for7Registers(register => - (Elidable & HasOpcode(SLA) & HasRegisterParam(register) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {(code,ctx) => + (Elidable & HasOpcode(SLA) & HasRegisterParam(register) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> {(_, ctx) => val value = ctx.get[Int](1) if (value.&(0x80) != 0) { List(ZLine.ldImm8(register, value.<<(1).&(0xff)), ZLine.implied(SCF)) @@ -1461,21 +1461,21 @@ object AlwaysGoodI80Optimizations { ), for7Registers(register => - (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasSet(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasSet(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => val value = ctx.get[Int](1) List(ZLine.ldImm8(register, value.<<(1).&(0xff).+(1))) } ), for7Registers(register => - (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasClear(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (code, ctx) => + (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasClear(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlags) ~~> { (_, ctx) => val value = ctx.get[Int](1) List(ZLine.ldImm8(register, value.<<(1).&(0xff))) } ), for7Registers(register => - (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasSet(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> { (code, ctx) => + (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasSet(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> { (_, ctx) => val value = ctx.get[Int](1) if (value.&(0x80) != 0) { List(ZLine.ldImm8(register, value.<<(1).&(0xff).+(1)), ZLine.implied(SCF)) @@ -1486,7 +1486,7 @@ object AlwaysGoodI80Optimizations { ), for7Registers(register => - (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasClear(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> { (code, ctx) => + (Elidable & HasOpcode(RL) & HasRegisterParam(register) & HasClear(ZFlag.C) & MatchRegister(register, 1) & DoesntMatterWhatItDoesWithFlagsExceptCarry) ~~> { (_, ctx) => val value = ctx.get[Int](1) if (value.&(0x80) != 0) { List(ZLine.ldImm8(register, value.<<(1).&(0xff)), ZLine.implied(SCF)) @@ -1514,7 +1514,7 @@ object AlwaysGoodI80Optimizations { (Linear & Not(Concerns(reg))).*).capture(1) ~ (Elidable & HasOpcode(LD_16) & HasRegisters(TwoRegisters(reg, IMM_16))).capture(2) ~ ((Linear & Not(Changes(reg))).* ~ - (HasOpcodeIn(Set(JP, JR, DJNZ)) & MatchParameterOrNothing(0))).capture(3) ~~> { (code, ctx) => + (HasOpcodeIn(Set(JP, JR, DJNZ)) & MatchParameterOrNothing(0))).capture(3) ~~> { (_, ctx) => ctx.get[List[ZLine]](2) ++ ctx.get[List[ZLine]](1) ++ ctx.get[List[ZLine]](3) @@ -1526,7 +1526,7 @@ object AlwaysGoodI80Optimizations { (Linear & Not(Concerns(reg))).*).capture(1) ~ (Elidable & HasOpcode(LD) & HasRegisters(TwoRegisters(reg, IMM_8))).capture(2) ~ ((Linear & Not(Changes(reg))).* ~ - (HasOpcodeIn(Set(JP, JR, DJNZ)) & MatchParameterOrNothing(0))).capture(3) ~~> { (code, ctx) => + (HasOpcodeIn(Set(JP, JR, DJNZ)) & MatchParameterOrNothing(0))).capture(3) ~~> { (_, ctx) => ctx.get[List[ZLine]](2) ++ ctx.get[List[ZLine]](1) ++ ctx.get[List[ZLine]](3) diff --git a/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala b/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala index a546a914..ca00c875 100644 --- a/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/z80/opt/FlowAnalyzer.scala @@ -18,7 +18,7 @@ class FlowHolder(_statusBefore: () => List[CpuStatus], _importanceAfter: () => L case class FlowInfo(holder: FlowHolder, index: Int, _labelUseCountMap: () => Option[Map[String, Int]]) { lazy val statusBefore: CpuStatus = holder.statusBefore(index) - lazy val importanceAfter = holder.importanceAfter(index) + lazy val importanceAfter: CpuImportance = holder.importanceAfter(index) lazy val labelUseCountMap: Option[Map[String, Int]] = _labelUseCountMap() def labelUseCount(label: String): Int = labelUseCountMap.map(_.getOrElse(label, 0)).getOrElse(-1) diff --git a/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala b/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala index 935ef072..22bf9a51 100644 --- a/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala +++ b/src/main/scala/millfork/assembly/z80/opt/ReverseFlowAnalyzer.scala @@ -183,13 +183,13 @@ object ReverseFlowAnalyzer { val cache = new FlowCache[ZLine, CpuImportance]("z80 reverse") - val readsA = Set("__mul_u8u8u8", "__mul_u16u8u16") - val readsB = Set("") - val readsC = Set("") - val readsD = Set("__mul_u8u8u8","__mul_u16u8u16", "__divmod_u16u8u16u8") - val readsE = Set("__mul_u16u8u16") - val readsH = Set("__divmod_u16u8u16u8") - val readsL = Set("__divmod_u16u8u16u8") + val readsA: Set[String] = Set("__mul_u8u8u8", "__mul_u16u8u16") + val readsB: Set[String] = Set("") + val readsC: Set[String] = Set("") + val readsD: Set[String] = Set("__mul_u8u8u8","__mul_u16u8u16", "__divmod_u16u8u16u8") + val readsE: Set[String] = Set("__mul_u16u8u16") + val readsH: Set[String] = Set("__divmod_u16u8u16u8") + val readsL: Set[String] = Set("__divmod_u16u8u16u8") //noinspection RedundantNewCaseClass def analyze(f: NormalFunction, code: List[ZLine]): List[CpuImportance] = { diff --git a/src/main/scala/millfork/compiler/AbstractExpressionCompiler.scala b/src/main/scala/millfork/compiler/AbstractExpressionCompiler.scala index 51846f00..0b6d1a49 100644 --- a/src/main/scala/millfork/compiler/AbstractExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/AbstractExpressionCompiler.scala @@ -12,7 +12,7 @@ class AbstractExpressionCompiler[T <: AbstractCode] { def getExpressionType(ctx: CompilationContext, expr: Expression): Type = AbstractExpressionCompiler.getExpressionType(ctx, expr) - def assertAllArithmetic(ctx: CompilationContext,expressions: List[Expression]) = { + def assertAllArithmetic(ctx: CompilationContext,expressions: List[Expression]): Unit = { for(e <- expressions) { val typ = getExpressionType(ctx, e) if (!typ.isArithmetic) { @@ -253,14 +253,14 @@ object AbstractExpressionCompiler { val v = env.get[Type]("void") val w = env.get[Type]("word") val t = expr match { - case LiteralExpression(value, size) => + case LiteralExpression(_, size) => size match { case 1 => b case 2 => w case 3 => env.get[Type]("farword") case 4 => env.get[Type]("long") } - case GeneratedConstantExpression(c, t) => t + case GeneratedConstantExpression(_, typ) => typ case TextLiteralExpression(_) => env.get[Type]("pointer") case VariableExpression(name) => env.get[TypedThing](name, expr.position).typ @@ -326,14 +326,14 @@ object AbstractExpressionCompiler { case 2 => w case _ => log.error("Adding values bigger than words", expr.position); w } - case FunctionCallExpression("nonet", params) => w + case FunctionCallExpression("nonet", _) => w case FunctionCallExpression("not", params) => toAllBooleanConstants(params) match { case Some(List(x)) => toType(!x) case _ => bool } - case FunctionCallExpression("hi", params) => b - case FunctionCallExpression("lo", params) => b + case FunctionCallExpression("hi", _) => b + case FunctionCallExpression("lo", _) => b case FunctionCallExpression("sin", params) => if (params.size < 2) b else getExpressionType(env, log, params(1)) case FunctionCallExpression("cos", params) => if (params.size < 2) b else getExpressionType(env, log, params(1)) case FunctionCallExpression("tan", params) => if (params.size < 2) b else getExpressionType(env, log, params(1)) @@ -357,9 +357,9 @@ object AbstractExpressionCompiler { case FunctionCallExpression(">>", List(a1, a2)) => if (getExpressionType(env, log, a2).size > 1) log.error("Shift amount too large", a2.position) getExpressionType(env, log, a1) - case FunctionCallExpression("<<'", params) => b - case FunctionCallExpression(">>'", params) => b - case FunctionCallExpression(">>>>", params) => b + case FunctionCallExpression("<<'", _) => b + case FunctionCallExpression(">>'", _) => b + case FunctionCallExpression(">>>>", _) => b case FunctionCallExpression("&&", params) => toAllBooleanConstants(params).fold(bool)(list => toType(list.reduce(_ && _))) case FunctionCallExpression("||", params) => @@ -381,20 +381,20 @@ object AbstractExpressionCompiler { toAllNumericConstants(params).fold(bool)(list => toType(monotonous(list, _ <= _))) case FunctionCallExpression(">=", params) => toAllNumericConstants(params).fold(bool)(list => toType(monotonous(list, _ >= _))) - case FunctionCallExpression("+=", params) => v - case FunctionCallExpression("-=", params) => v - case FunctionCallExpression("*=", params) => v - case FunctionCallExpression("+'=", params) => v - case FunctionCallExpression("-'=", params) => v - case FunctionCallExpression("*'=", params) => v - case FunctionCallExpression("|=", params) => v - case FunctionCallExpression("&=", params) => v - case FunctionCallExpression("^=", params) => v - case FunctionCallExpression("<<=", params) => v - case FunctionCallExpression(">>=", params) => v - case FunctionCallExpression("<<'=", params) => v - case FunctionCallExpression(">>'=", params) => v - case f@FunctionCallExpression(name, params) => + case FunctionCallExpression("+=", _) => v + case FunctionCallExpression("-=", _) => v + case FunctionCallExpression("*=", _) => v + case FunctionCallExpression("+'=", _) => v + case FunctionCallExpression("-'=", _) => v + case FunctionCallExpression("*'=", _) => v + case FunctionCallExpression("|=", _) => v + case FunctionCallExpression("&=", _) => v + case FunctionCallExpression("^=", _) => v + case FunctionCallExpression("<<=", _) => v + case FunctionCallExpression(">>=", _) => v + case FunctionCallExpression("<<'=", _) => v + case FunctionCallExpression(">>'=", _) => v + case f@FunctionCallExpression(name, _) => env.maybeGet[Type](name) match { case Some(typ) => typ diff --git a/src/main/scala/millfork/compiler/AbstractStatementPreprocessor.scala b/src/main/scala/millfork/compiler/AbstractStatementPreprocessor.scala index a8ac7fca..dcf7851b 100644 --- a/src/main/scala/millfork/compiler/AbstractStatementPreprocessor.scala +++ b/src/main/scala/millfork/compiler/AbstractStatementPreprocessor.scala @@ -6,6 +6,7 @@ import millfork.node._ import AbstractExpressionCompiler.getExpressionType import millfork.compiler.AbstractStatementPreprocessor.hiddenEffectFreeFunctions +import scala.collection.immutable import scala.collection.mutable.ListBuffer /** @@ -15,8 +16,8 @@ abstract class AbstractStatementPreprocessor(ctx: CompilationContext, statements type VV = Map[String, Constant] protected val optimize = true // TODO protected val env: Environment = ctx.env - protected val localPrefix = ctx.function.name + "$" - protected val usedIdentifiers = if (optimize) statements.flatMap(_.getAllExpressions).flatMap(_.getAllIdentifiers) else Set() + protected val localPrefix: String = ctx.function.name + "$" + protected val usedIdentifiers: immutable.Iterable[String] with (Nothing => Any) = if (optimize) statements.flatMap(_.getAllExpressions).flatMap(_.getAllIdentifiers) else Set() protected val trackableVars: Set[String] = if (optimize) { env.getAllLocalVariables .filterNot(_.typ.isSigned) // sadly, tracking loses signedness @@ -382,7 +383,7 @@ abstract class AbstractStatementPreprocessor(ctx: CompilationContext, statements } object AbstractStatementPreprocessor { - val hiddenEffectFreeFunctions = Set( + val hiddenEffectFreeFunctions: Set[String] = Set( "+", "+'", "-", "-'", "*", "*'", "<<", "<<'", ">>", ">>'", ">>>>", diff --git a/src/main/scala/millfork/compiler/MacroExpander.scala b/src/main/scala/millfork/compiler/MacroExpander.scala index f0715cc7..bfd505ce 100644 --- a/src/main/scala/millfork/compiler/MacroExpander.scala +++ b/src/main/scala/millfork/compiler/MacroExpander.scala @@ -14,13 +14,13 @@ abstract class MacroExpander[T <: AbstractCode] { def prepareAssemblyParams(ctx: CompilationContext, assParams: List[AssemblyParam], params: List[Expression], code: List[ExecutableStatement]): (List[T], List[ExecutableStatement]) def replaceVariable(stmt: Statement, paramName: String, target: Expression): Statement = { - def f[T <: Expression](e: T) = e.replaceVariable(paramName, target) + def f[S <: Expression](e: S) = e.replaceVariable(paramName, target) - def fx[T <: Expression](e: T) = e.replaceVariable(paramName, target).asInstanceOf[LhsExpression] + def fx[S <: Expression](e: S) = e.replaceVariable(paramName, target).asInstanceOf[LhsExpression] - def g[T <: Statement](s: T) = replaceVariable(s, paramName, target) + def g[S <: Statement](s: S) = replaceVariable(s, paramName, target) - def gx[T <: ExecutableStatement](s: T) = replaceVariable(s, paramName, target).asInstanceOf[ExecutableStatement] + def gx[S <: ExecutableStatement](s: S) = replaceVariable(s, paramName, target).asInstanceOf[ExecutableStatement] def h(s: String) = if (s == paramName) target.asInstanceOf[VariableExpression].name else s diff --git a/src/main/scala/millfork/compiler/mos/BuiltIns.scala b/src/main/scala/millfork/compiler/mos/BuiltIns.scala index 89d7594a..8a791b64 100644 --- a/src/main/scala/millfork/compiler/mos/BuiltIns.scala +++ b/src/main/scala/millfork/compiler/mos/BuiltIns.scala @@ -457,7 +457,7 @@ object BuiltIns { case ComparisonType.Equal | ComparisonType.NotEqual | ComparisonType.LessSigned | ComparisonType.GreaterOrEqualSigned => val secondParamCompiledUnoptimized = simpleOperation(cmpOp, ctx, rhs, IndexChoice.PreferY, preserveA = true, commutative = false) secondParamCompiledUnoptimized match { - case List(AssemblyLine(cmpOp, Immediate, NumericConstant(0, _), Elidability.Elidable, _)) => + case List(AssemblyLine(_, Immediate, NumericConstant(0, _), Elidability.Elidable, _)) => if (OpcodeClasses.ChangesAAlways(firstParamCompiled.last.opcode)) { Nil } else { diff --git a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala index 9d628999..43f9dc92 100644 --- a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala @@ -1316,7 +1316,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] { BuiltIns.compileUnsignedByteDivision(ctx, l, r, f.functionName == "%%=") ++ compileByteStorage(ctx, MosRegister.A, l) case 2 => if (f.functionName == "%%=") { - BuiltIns.compileUnsignedWordByByteDivision(ctx, l, r, true) ++ compileByteStorage(ctx, MosRegister.A, l) + BuiltIns.compileUnsignedWordByByteDivision(ctx, l, r, modulo = true) ++ compileByteStorage(ctx, MosRegister.A, l) } else { compileAssignment(ctx, FunctionCallExpression("/", List(l, r)).pos(f.position), l) } diff --git a/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala b/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala index 175cddb6..97c7c629 100644 --- a/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala +++ b/src/main/scala/millfork/compiler/z80/Z80DecimalBuiltIns.scala @@ -322,8 +322,8 @@ object Z80DecimalBuiltIns { // println((2 to 99).map(ways).map(_.length).max) println() println() - val multiplyCostsCycles2 = multiplyCostsCycles.map{case(k,v) => k -> (v + multiplyCostsBytes(k) / 2048.0)}.toMap - val multiplyCostsBytes2 = multiplyCostsBytes.map{case(k,v) => k -> (v + multiplyCostsCycles(k) / 2048.0)}.toMap + val multiplyCostsCycles2 = multiplyCostsCycles.map { case (k, v) => k -> (v + multiplyCostsBytes(k) / 2048.0) } + val multiplyCostsBytes2 = multiplyCostsBytes.map { case (k, v) => k -> (v + multiplyCostsCycles(k) / 2048.0) } val mc = (2 to 99).map{i => i -> findWay(i, multiplyCostsCycles2)}.toMap val mb = (2 to 99).map{i => i -> findWay(i, multiplyCostsBytes2)}.toMap for (i <- 2 to 99) { diff --git a/src/main/scala/millfork/compiler/z80/Z80Shifting.scala b/src/main/scala/millfork/compiler/z80/Z80Shifting.scala index 493c0112..b1d57caa 100644 --- a/src/main/scala/millfork/compiler/z80/Z80Shifting.scala +++ b/src/main/scala/millfork/compiler/z80/Z80Shifting.scala @@ -15,7 +15,7 @@ import scala.collection.GenTraversableOnce object Z80Shifting { private def calculateIterationCountPlus1(ctx: CompilationContext, rhs: Expression) = { - Z80ExpressionCompiler.compile8BitTo(ctx, SumExpression(List(false -> rhs, false -> LiteralExpression(1, 1)), false), ZRegister.B) + Z80ExpressionCompiler.compile8BitTo(ctx, SumExpression(List(false -> rhs, false -> LiteralExpression(1, 1)), decimal = false), ZRegister.B) } private def fixAfterShiftIfNeeded(extendedOps: Boolean, left: Boolean, i: Long): List[ZLine] = diff --git a/src/main/scala/millfork/env/Environment.scala b/src/main/scala/millfork/env/Environment.scala index 625ece8f..e7d9bece 100644 --- a/src/main/scala/millfork/env/Environment.scala +++ b/src/main/scala/millfork/env/Environment.scala @@ -1752,6 +1752,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa def hintTypo(name: String): Unit = { val realThings = this.things.keySet ++ parent.map(_.things.keySet).getOrElse(Set()) + //noinspection ScalaDeprecation val matchingThings = realThings.filter(thing => !thing.contains("$") && StringUtils.getJaroWinklerDistance(thing,name) > 0.9) if (matchingThings.nonEmpty) { log.info("Did you mean: " + matchingThings.mkString(", ")) @@ -1839,7 +1840,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa } object Environment { - val predefinedFunctions = Set("not", "hi", "lo", "nonet", "sizeof") + val predefinedFunctions: Set[String] = Set("not", "hi", "lo", "nonet", "sizeof") val keywords: Set[String] = Set( "true", "false", "byte", "sbyte", "word", "pointer", "void", "long", diff --git a/src/main/scala/millfork/error/ConsoleLogger.scala b/src/main/scala/millfork/error/ConsoleLogger.scala index f6568e0f..41e408b2 100644 --- a/src/main/scala/millfork/error/ConsoleLogger.scala +++ b/src/main/scala/millfork/error/ConsoleLogger.scala @@ -17,7 +17,7 @@ class ConsoleLogger extends Logger { var hasErrors = false - private var sourceLines: mutable.Map[String, IndexedSeq[String]] = mutable.Map() + private val sourceLines: mutable.Map[String, IndexedSeq[String]] = mutable.Map() private def printErrorContext(pos: Option[Position]): Unit = synchronized { pos.foreach { position => diff --git a/src/main/scala/millfork/node/CallGraph.scala b/src/main/scala/millfork/node/CallGraph.scala index 9470f8d6..9d465cd2 100644 --- a/src/main/scala/millfork/node/CallGraph.scala +++ b/src/main/scala/millfork/node/CallGraph.scala @@ -25,15 +25,15 @@ abstract class CallGraph(program: Program, log: Logger) { def canOverlap(a: VariableVertex, b: VariableVertex): Boolean - protected val entryPoints = mutable.Set[String]() + protected val entryPoints: mutable.Set[String] = mutable.Set[String]() // (F,G) means function F calls function G - protected val callEdges = mutable.Set[(String, String)]() + protected val callEdges: mutable.Set[(String, String)] = mutable.Set[(String, String)]() // (F,G) means function G is called when building parameters for function F - protected val paramEdges = mutable.Set[(String, String)]() - protected val multiaccessibleFunctions = mutable.Set[String]() - protected val everCalledFunctions = mutable.Set[String]() - protected val allFunctions = mutable.Set[String]() - protected val aliases = mutable.Map[String, String]() + protected val paramEdges: mutable.Set[(String, String)] = mutable.Set[(String, String)]() + protected val multiaccessibleFunctions: mutable.Set[String] = mutable.Set[String]() + protected val everCalledFunctions: mutable.Set[String] = mutable.Set[String]() + protected val allFunctions: mutable.Set[String] = mutable.Set[String]() + protected val aliases: mutable.Map[String, String] = mutable.Map[String, String]() entryPoints += "main" program.declarations.foreach(s => add(None, Nil, s)) diff --git a/src/main/scala/millfork/output/AbstractAssembler.scala b/src/main/scala/millfork/output/AbstractAssembler.scala index 4164505c..57699a2d 100644 --- a/src/main/scala/millfork/output/AbstractAssembler.scala +++ b/src/main/scala/millfork/output/AbstractAssembler.scala @@ -285,9 +285,9 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program val bank0 = mem.banks(bank) val index = f.address.get.asInstanceOf[NumericConstant].value.toInt compiledFunctions(f.name) match { - case NormalCompiledFunction(_, code, _, _) => + case NormalCompiledFunction(_, functionCode, _, _) => labelMap(f.name) = index - val end = outputFunction(bank, code, index, assembly, options) + val end = outputFunction(bank, functionCode, index, assembly, options) for (i <- index until end) { bank0.occupied(index) = true bank0.initialized(index) = true @@ -306,11 +306,11 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program sortedCompilerFunctions.filterNot(o => unusedRuntimeObjects(o._1)).foreach { case (_, NormalCompiledFunction(_, _, true, _)) => // already done before - case (name, NormalCompiledFunction(bank, code, false, alignment)) => - val size = code.map(_.sizeInBytes).sum + case (name, NormalCompiledFunction(bank, functionCode, false, alignment)) => + val size = functionCode.map(_.sizeInBytes).sum val index = codeAllocators(bank).allocateBytes(mem.banks(bank), options, size, initialized = true, writeable = false, location = AllocationLocation.High, alignment = alignment) labelMap(name) = index - justAfterCode += bank -> outputFunction(bank, code, index, assembly, options) + justAfterCode += bank -> outputFunction(bank, functionCode, index, assembly, options) case _ => } sortedCompilerFunctions.foreach { @@ -323,7 +323,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program env.allThings.things.foreach { case (_, m@UninitializedMemoryVariable(name, typ, _, _, _, _)) if name.endsWith(".addr") || env.maybeGet[Thing](name + ".array").isDefined => val isUsed = compiledFunctions.values.exists{ - case NormalCompiledFunction(_, code, _, _) => code.exists(_.parameter.isRelatedTo(m)) + case NormalCompiledFunction(_, functionCode, _, _) => functionCode.exists(_.parameter.isRelatedTo(m)) case _ => false } // println(m.name -> isUsed) @@ -507,11 +507,11 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program lastSource = instr.source if (printLineNumbers) { lastSource match { - case Some(sl@SourceLine(moduleName, line)) if line > 0 => + case Some(sl@SourceLine(moduleName, lineNo)) if lineNo > 0 => if (sourceInAssembly) { assOut.append("; ") } - assOut.append(s";line:$line:$moduleName") + assOut.append(s";line:$lineNo:$moduleName") if (sourceInAssembly) { log.getLine(sl).foreach(l => assOut.append("; " + l)) } diff --git a/src/main/scala/millfork/output/CompiledMemory.scala b/src/main/scala/millfork/output/CompiledMemory.scala index b683839c..44ee3242 100644 --- a/src/main/scala/millfork/output/CompiledMemory.scala +++ b/src/main/scala/millfork/output/CompiledMemory.scala @@ -7,25 +7,25 @@ import scala.collection.mutable */ class CompiledMemory(bankNames: List[String]) { var programName = "MILLFORK" - val banks = mutable.Map(bankNames.map(_ -> new MemoryBank): _*) + val banks: mutable.Map[String, MemoryBank] = mutable.Map(bankNames.map(_ -> new MemoryBank): _*) } class MemoryBank { - def readByte(addr: Int) = output(addr) & 0xff + def readByte(addr: Int): Int = output(addr) & 0xff - def readWord(addr: Int) = readByte(addr) + (readByte(addr + 1) << 8) + def readWord(addr: Int): Int = readByte(addr) + (readByte(addr + 1) << 8) - def readMedium(addr: Int) = readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + def readMedium(addr: Int): Int = readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) - def readLong(addr: Int) = readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + (readByte(addr + 3) << 24) + def readLong(addr: Int): Int = readByte(addr) + (readByte(addr + 1) << 8) + (readByte(addr + 2) << 16) + (readByte(addr + 3) << 24) - def readWord(addrHi: Int, addrLo: Int) = readByte(addrLo) + (readByte(addrHi) << 8) + def readWord(addrHi: Int, addrLo: Int): Int = readByte(addrLo) + (readByte(addrHi) << 8) - val output = Array.fill[Byte](1 << 16)(0) - val occupied = Array.fill(1 << 16)(false) - val initialized = Array.fill(1 << 16)(false) - val readable = Array.fill(1 << 16)(false) - val writeable = Array.fill(1 << 16)(false) + val output: Array[Byte] = Array.fill[Byte](1 << 16)(0) + val occupied: Array[Boolean] = Array.fill(1 << 16)(false) + val initialized: Array[Boolean] = Array.fill(1 << 16)(false) + val readable: Array[Boolean] = Array.fill(1 << 16)(false) + val writeable: Array[Boolean] = Array.fill(1 << 16)(false) var start: Int = 0 var end: Int = 0 diff --git a/src/main/scala/millfork/output/Deduplicate.scala b/src/main/scala/millfork/output/Deduplicate.scala index 102f6281..ae884b7a 100644 --- a/src/main/scala/millfork/output/Deduplicate.scala +++ b/src/main/scala/millfork/output/Deduplicate.scala @@ -142,7 +142,7 @@ abstract class Deduplicate[T <: AbstractCode](env: Environment, options: Compila } } - result.toSeq + result } def deduplicateIdenticalFunctions(segmentName: String, segContents: Map[String, Either[String, CodeAndAlignment[T]]]): Seq[(String, CompiledFunction[T])] = { @@ -173,7 +173,7 @@ abstract class Deduplicate[T <: AbstractCode](env: Environment, options: Compila } } } - result.toSeq + result } private def follow(segContents: Map[String, Either[String, CodeAndAlignment[T]]], to: String): Option[String] = { @@ -224,7 +224,7 @@ abstract class Deduplicate[T <: AbstractCode](env: Environment, options: Compila result += to -> NonexistentFunction() } } - result.toSeq + result } def eliminateRemainingTrivialTailJumps(segmentName: String, segContents: Map[String, Either[String, CodeAndAlignment[T]]]): Seq[(String, CompiledFunction[T])] = { @@ -260,7 +260,7 @@ abstract class Deduplicate[T <: AbstractCode](env: Environment, options: Compila } } } - result.toSeq + result } def fixDoubleRedirects(compiledFunctions: mutable.Map[String, CompiledFunction[T]]): Unit = { diff --git a/src/main/scala/millfork/output/Z80Assembler.scala b/src/main/scala/millfork/output/Z80Assembler.scala index 049072a8..6f062496 100644 --- a/src/main/scala/millfork/output/Z80Assembler.scala +++ b/src/main/scala/millfork/output/Z80Assembler.scala @@ -1,7 +1,7 @@ package millfork.output import millfork.{CompilationFlag, CompilationOptions, Cpu, Platform} -import millfork.assembly.z80._ +import millfork.assembly.z80.{ZOpcode, _} import millfork.assembly.z80.opt.{ConditionalInstructions, JumpFollowing, JumpShortening} import millfork.compiler.z80.Z80Compiler import millfork.env._ @@ -706,11 +706,11 @@ object Z80Assembler { case class One(opcode: Int, multiplier: Int) - val implieds = mutable.Map[ZOpcode.Value, Int]() - val immediates = mutable.Map[ZOpcode.Value, Int]() - val edImplieds = mutable.Map[ZOpcode.Value, Int]() - val oneRegister = mutable.Map[ZOpcode.Value, One]() - val cbOneRegister = mutable.Map[ZOpcode.Value, One]() + val implieds: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val immediates: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val edImplieds: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val oneRegister: mutable.Map[ZOpcode.Value, One] = mutable.Map[ZOpcode.Value, One]() + val cbOneRegister: mutable.Map[ZOpcode.Value, One] = mutable.Map[ZOpcode.Value, One]() do { import ZOpcode._ diff --git a/src/main/scala/millfork/output/Z80ToX86Crossassembler.scala b/src/main/scala/millfork/output/Z80ToX86Crossassembler.scala index 8769f584..7c753d51 100644 --- a/src/main/scala/millfork/output/Z80ToX86Crossassembler.scala +++ b/src/main/scala/millfork/output/Z80ToX86Crossassembler.scala @@ -1,7 +1,7 @@ package millfork.output import millfork.{CompilationFlag, CompilationOptions, Cpu, Platform} -import millfork.assembly.z80._ +import millfork.assembly.z80.{ZOpcode, _} import millfork.assembly.z80.opt.{ConditionalInstructions, JumpFollowing, JumpShortening} import millfork.compiler.z80.Z80Compiler import millfork.env._ @@ -83,7 +83,7 @@ class Z80ToX86Crossassembler(program: Program, index case ZLine0(LABEL | BYTE | DISCARD_F | DISCARD_HL | DISCARD_BC | DISCARD_DE | DISCARD_IX | DISCARD_IY | DISCARD_A | CHANGED_MEM, _, _) => ??? - case ZLine0(op, NoRegisters, _) if implieds.contains(op) && implieds(op) != 666 => + case ZLine0(op, NoRegisters, _) if implieds.contains(op) => writeByte(bank, index, implieds(op)) index + 1 @@ -398,27 +398,22 @@ object Z80ToX86Crossassembler { case class One(opcode: Int, multiplier: Int) - val implieds = mutable.Map[ZOpcode.Value, Int]() - val arith = mutable.Map[ZOpcode.Value, Int]() - val edImplieds = mutable.Map[ZOpcode.Value, Int]() - val oneRegister = mutable.Map[ZOpcode.Value, One]() - val cbOneRegister = mutable.Map[ZOpcode.Value, One]() + val implieds: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val arith: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val edImplieds: mutable.Map[ZOpcode.Value, Int] = mutable.Map[ZOpcode.Value, Int]() + val oneRegister: mutable.Map[ZOpcode.Value, One] = mutable.Map[ZOpcode.Value, One]() + val cbOneRegister: mutable.Map[ZOpcode.Value, One] = mutable.Map[ZOpcode.Value, One]() do { import ZOpcode._ implieds(NOP) = 0x90 implieds(DAA) = 0x27 implieds(SCF) = 0xf9 - implieds(CPL) = 666 implieds(CCF) = 0xf5 implieds(RET) = 0xc3 implieds(EI) = 0xfb implieds(DI) = 0xfa implieds(HALT) = 0xf4 - implieds(RLCA) = 666 - implieds(RRCA) = 666 - implieds(RLA) = 666 - implieds(RRA) = 666 arith(ADD) = 0x00 arith(ADC) = 0x10 diff --git a/src/main/scala/millfork/parser/MfParser.scala b/src/main/scala/millfork/parser/MfParser.scala index ad8ec9a4..e25b1466 100644 --- a/src/main/scala/millfork/parser/MfParser.scala +++ b/src/main/scala/millfork/parser/MfParser.scala @@ -87,7 +87,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri val textLiteral: P[List[Expression]] = P(position() ~ doubleQuotedString ~/ HWS ~ codec).map { case (p, s, ((co, zt), lenient)) => - val characters = co.encode(options.log, None, s.toList, lenient = lenient).map(c => LiteralExpression(c, 1).pos(p)) + val characters = co.encode(options.log, None, s, lenient = lenient).map(c => LiteralExpression(c, 1).pos(p)) if (zt) characters :+ LiteralExpression(0,1) else characters } @@ -185,7 +185,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri LiteralContents(slice.map(c => LiteralExpression(c & 0xff, 1)).toList) } - def arrayStringContents: P[ArrayContents] = textLiteral.map(LiteralContents(_)) + def arrayStringContents: P[ArrayContents] = textLiteral.map(LiteralContents) def arrayLoopContents: P[ArrayContents] = for { identifier <- "for" ~ SWS ~/ identifier ~/ HWS ~ "," ~/ HWS ~ Pass @@ -317,14 +317,14 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri def index: P[Expression] = HWS ~ "[" ~/ AWS ~/ mfExpression(nonStatementLevel, false) ~ AWS ~/ "]" ~/ Pass - def mfExpressionWrapper[T <: Expression](inner: P[T]): P[T] = for { + def mfExpressionWrapper[E <: Expression](inner: P[E]): P[E] = for { expr <- inner firstIndices <- index.rep fieldPath <- (HWS ~ "->" ~/ AWS ~/ identifier ~/ index.rep).rep } yield (expr, firstIndices, fieldPath) match { case (_, Seq(), Seq()) => expr - case (VariableExpression(vname), Seq(i), Seq()) => IndexedExpression(vname, i).pos(expr.position).asInstanceOf[T] - case _ => IndirectFieldExpression(expr, firstIndices, fieldPath).pos(expr.position).asInstanceOf[T] + case (VariableExpression(vname), Seq(i), Seq()) => IndexedExpression(vname, i).pos(expr.position).asInstanceOf[E] + case _ => IndirectFieldExpression(expr, firstIndices, fieldPath).pos(expr.position).asInstanceOf[E] } // def mfLhsExpression: P[LhsExpression] = for { @@ -665,7 +665,7 @@ object MfParser { List("+'", "-'", "<<'", ">>'", ">>>>", "+", "-", "&", "|", "^", "<<", ">>"), List("*'", "*", "/", "%%")) - val mfOperatorsDropFlatten: IndexedSeq[List[String]] = (0 until mfOperators.length).map(i => mfOperators.drop(i).flatten) + val mfOperatorsDropFlatten: IndexedSeq[List[String]] = mfOperators.indices.map(i => mfOperators.drop(i).flatten) val nonStatementLevel = 1 // everything but not `=` val mathLevel = 4 // the `:` operator @@ -699,5 +699,5 @@ object MfParser { val functionFlags: P[Set[String]] = flags_("asm", "inline", "interrupt", "macro", "noinline", "reentrant", "kernal_interrupt") - val InvalidReturnTypes = Set("enum", "alias", "array", "const", "stack", "register", "static", "volatile", "import", "struct", "union") + val InvalidReturnTypes: Set[String] = Set("enum", "alias", "array", "const", "stack", "register", "static", "volatile", "import", "struct", "union") } diff --git a/src/main/scala/millfork/parser/Preprocessor.scala b/src/main/scala/millfork/parser/Preprocessor.scala index a6d94cb4..5b922b4c 100644 --- a/src/main/scala/millfork/parser/Preprocessor.scala +++ b/src/main/scala/millfork/parser/Preprocessor.scala @@ -77,9 +77,9 @@ object Preprocessor { if (enabled) { val value = evalParam(param, pos) enabled = value != 0 - ifStack.push(IfContext(enabled, false, true)) + ifStack.push(IfContext(hadEnabled = enabled, hadElse = false, enabledBefore = true)) } else { - ifStack.push(IfContext(false, false, false)) + ifStack.push(IfContext(hadEnabled = false, hadElse = false, enabledBefore = false)) } case "endif" => if (param != "") log.error("#endif shouldn't have a parameter", pos) @@ -149,7 +149,7 @@ class PreprocessorParser(options: CompilationOptions) { type M = Map[String, Long] type Q = M => Option[Long] val alwaysNone: M => Option[Long] = (_: M) => None - val log = options.log + val log: Logger = options.log val literalAtom: P[Q] = (MfParser.binaryAtom | MfParser.hexAtom | MfParser.octalAtom | MfParser.quaternaryAtom | MfParser.decimalAtom).map(l => _ => Some(l.value)) diff --git a/src/test/scala/millfork/test/emu/EmuCmosBenchmarkRun.scala b/src/test/scala/millfork/test/emu/EmuCmosBenchmarkRun.scala index 71643a01..4ba79f12 100644 --- a/src/test/scala/millfork/test/emu/EmuCmosBenchmarkRun.scala +++ b/src/test/scala/millfork/test/emu/EmuCmosBenchmarkRun.scala @@ -6,7 +6,7 @@ import millfork.output.MemoryBank * @author Karol Stasiak */ object EmuCmosBenchmarkRun { - def apply(source:String)(verifier: MemoryBank=>Unit) = { + def apply(source:String)(verifier: MemoryBank=>Unit): Unit = { println(f"Compiling for NMOS (unoptimized)") val (Timings(_, t0), m0) = EmuUnoptimizedRun.apply2(source) println(f"Compiling for NMOS") diff --git a/src/test/scala/millfork/test/emu/EmuUltraBenchmarkRun.scala b/src/test/scala/millfork/test/emu/EmuUltraBenchmarkRun.scala index 36773caa..2f1e11c2 100644 --- a/src/test/scala/millfork/test/emu/EmuUltraBenchmarkRun.scala +++ b/src/test/scala/millfork/test/emu/EmuUltraBenchmarkRun.scala @@ -6,7 +6,7 @@ import millfork.output.MemoryBank * @author Karol Stasiak */ object EmuUltraBenchmarkRun { - def apply(source:String)(verifier: MemoryBank=>Unit) = { + def apply(source:String)(verifier: MemoryBank=>Unit): Unit = { val (Timings(t0, _), m0) = EmuUnoptimizedRun.apply2(source) val (Timings(t1, _), m1) = EmuOptimizedRun.apply2(source) val (Timings(ti, _), mi) = EmuOptimizedInlinedRun.apply2(source) diff --git a/src/test/scala/millfork/test/emu/NashornEmulator.scala b/src/test/scala/millfork/test/emu/NashornEmulator.scala index c0ba9792..86e4ab0e 100644 --- a/src/test/scala/millfork/test/emu/NashornEmulator.scala +++ b/src/test/scala/millfork/test/emu/NashornEmulator.scala @@ -13,7 +13,7 @@ import scala.language.dynamics */ object NashornEmulator { - lazy val engine = { + lazy val engine: ScriptEngine = { val jsFile = Paths.get(classOf[Nothing].getResource("/cpu.js").toURI).toFile val engine: ScriptEngine = new ScriptEngineManager().getEngineByName("nashorn") engine.eval(new FileReader(jsFile))