1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-03-24 10:33:53 +00:00

Code cleanup

This commit is contained in:
Karol Stasiak 2019-06-12 22:55:34 +02:00
parent e219830ba1
commit dc13dbaa9a
30 changed files with 184 additions and 187 deletions

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)
}

View File

@ -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)

View File

@ -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)

View File

@ -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] = {

View File

@ -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

View File

@ -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(
"+", "+'", "-", "-'",
"*", "*'",
"<<", "<<'", ">>", ">>'", ">>>>",

View File

@ -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

View File

@ -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 {

View File

@ -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)
}

View File

@ -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) {

View File

@ -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] =

View File

@ -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",

View File

@ -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 =>

View File

@ -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))

View File

@ -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))
}

View File

@ -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

View File

@ -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 = {

View File

@ -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._

View File

@ -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

View File

@ -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")
}

View File

@ -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))

View File

@ -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")

View File

@ -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)

View File

@ -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))