mirror of
https://github.com/KarolS/millfork.git
synced 2025-04-13 05:39:54 +00:00
Move label generation into a separate class
This commit is contained in:
parent
f929e396df
commit
e914ad6d7b
@ -1,15 +1,25 @@
|
||||
package millfork
|
||||
|
||||
import millfork.error.{Logger, ConsoleLogger}
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.error.{ConsoleLogger, Logger}
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
case class CompilationOptions(platform: Platform, commandLineFlags: Map[CompilationFlag.Value, Boolean], outputFileName: Option[String], zpRegisterSize: Int, log: Logger) {
|
||||
case class CompilationOptions(platform: Platform,
|
||||
commandLineFlags: Map[CompilationFlag.Value, Boolean],
|
||||
outputFileName: Option[String],
|
||||
zpRegisterSize: Int,
|
||||
jobContext: JobContext) {
|
||||
|
||||
import CompilationFlag._
|
||||
import Cpu._
|
||||
|
||||
@inline
|
||||
def log: Logger = jobContext.log
|
||||
@inline
|
||||
def nextLabel: LabelGenerator = jobContext.nextLabel
|
||||
|
||||
val flags: Map[CompilationFlag.Value, Boolean] = CompilationFlag.values.map { f =>
|
||||
f -> commandLineFlags.getOrElse(f, platform.flagOverrides.getOrElse(f, Cpu.defaultFlags(platform.cpu)(f)))
|
||||
}.toMap
|
||||
|
9
src/main/scala/millfork/JobContext.scala
Normal file
9
src/main/scala/millfork/JobContext.scala
Normal file
@ -0,0 +1,9 @@
|
||||
package millfork
|
||||
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.error.Logger
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
case class JobContext(log: Logger, nextLabel: LabelGenerator)
|
@ -9,9 +9,10 @@ import millfork.assembly.mos.opt._
|
||||
import millfork.assembly.z80.opt.Z80OptimizationPresets
|
||||
import millfork.buildinfo.BuildInfo
|
||||
import millfork.cli.{CliParser, CliStatus}
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.compiler.mos.MosCompiler
|
||||
import millfork.env.Environment
|
||||
import millfork.error.{Logger, ConsoleLogger}
|
||||
import millfork.error.{ConsoleLogger, Logger}
|
||||
import millfork.node.StandardCallGraph
|
||||
import millfork.output._
|
||||
import millfork.parser.{MosSourceLoadingQueue, ZSourceLoadingQueue}
|
||||
@ -80,7 +81,7 @@ object Main {
|
||||
errorReporting.info("No platform selected, defaulting to `c64`")
|
||||
"c64"
|
||||
}, c.features)
|
||||
val options = CompilationOptions(platform, c.flags, c.outputFileName, c.zpRegisterSize.getOrElse(platform.zpRegisterSize), errorReporting)
|
||||
val options = CompilationOptions(platform, c.flags, c.outputFileName, c.zpRegisterSize.getOrElse(platform.zpRegisterSize), JobContext(errorReporting, new LabelGenerator))
|
||||
errorReporting.debug("Effective flags: ")
|
||||
options.flags.toSeq.sortBy(_._1).foreach{
|
||||
case (f, b) => errorReporting.debug(f" $f%-30s : $b%s")
|
||||
@ -162,7 +163,7 @@ object Main {
|
||||
}
|
||||
val callGraph = new StandardCallGraph(program, options.log)
|
||||
|
||||
val env = new Environment(None, "", platform.cpuFamily, options.log)
|
||||
val env = new Environment(None, "", platform.cpuFamily, options.jobContext)
|
||||
env.collectDeclarations(program, options)
|
||||
|
||||
val assemblyOptimizations = optLevel match {
|
||||
@ -213,7 +214,7 @@ object Main {
|
||||
}
|
||||
val callGraph = new StandardCallGraph(program, options.log)
|
||||
|
||||
val env = new Environment(None, "", platform.cpuFamily, options.log)
|
||||
val env = new Environment(None, "", platform.cpuFamily, options.jobContext)
|
||||
env.collectDeclarations(program, options)
|
||||
|
||||
val assemblyOptimizations = optLevel match {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package millfork.assembly
|
||||
|
||||
import millfork.CompilationOptions
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.env.{NormalFunction, ThingInMemory}
|
||||
import millfork.error.Logger
|
||||
import millfork.node.NiceFunctionProperty
|
||||
@ -12,7 +13,10 @@ case class OptimizationContext(options: CompilationOptions,
|
||||
labelMap: Map[String, Int],
|
||||
zreg: Option[ThingInMemory],
|
||||
niceFunctionProperties: Set[(NiceFunctionProperty, String)]) {
|
||||
@inline
|
||||
def log: Logger = options.log
|
||||
@inline
|
||||
def nextLabel: LabelGenerator = options.nextLabel
|
||||
}
|
||||
|
||||
trait AssemblyOptimization[T <: AbstractCode] {
|
||||
|
@ -380,7 +380,7 @@ object AssemblyLine {
|
||||
List(AssemblyLine.immediate(opcode, 0))
|
||||
} else if (opcodesForZeroedOrSignExtendedVariableOperation(opcode)) {
|
||||
if (variable.typ.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
AssemblyLine.variable(ctx, LDA, variable, variable.typ.size - 1) ++ List(
|
||||
AssemblyLine.immediate(ORA, 0x7f),
|
||||
AssemblyLine.relative(BMI, label),
|
||||
|
@ -17,12 +17,9 @@ import millfork.env._
|
||||
//noinspection ZeroIndexToHead
|
||||
object AlwaysGoodOptimizations {
|
||||
|
||||
val counter = new AtomicInteger(30000)
|
||||
val LdxAddrModes = Set(Immediate, Absolute, ZeroPage, ZeroPageY, AbsoluteY)
|
||||
val LdyAddrModes = Set(Immediate, Absolute, ZeroPage, ZeroPageX, AbsoluteX)
|
||||
|
||||
def getNextLabel(prefix: String) = f".$prefix%s__${counter.getAndIncrement()}%05d"
|
||||
|
||||
private def jvmFix(r: => RuleBasedAssemblyOptimization): RuleBasedAssemblyOptimization = r
|
||||
|
||||
val PointlessMath = jvmFix(new RuleBasedAssemblyOptimization("Pointless math",
|
||||
@ -1725,8 +1722,8 @@ object AlwaysGoodOptimizations {
|
||||
needsFlowInfo = FlowInfoRequirement.BothFlows,
|
||||
(Elidable & HasOpcode(LDA) & HasImmediate(0) & HasClear(State.D)) ~
|
||||
(Elidable & HasOpcode(ADC) & MatchAddrMode(1) & MatchParameter(2) & HasAddrModeIn(ZeroPage, ZeroPageX, Absolute, AbsoluteX)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(1) & MatchParameter(2) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { code =>
|
||||
val label = getNextLabel("ah")
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(1) & MatchParameter(2) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("ah")
|
||||
List(
|
||||
AssemblyLine.relative(BCC, label),
|
||||
code.last.copy(opcode = INC),
|
||||
@ -1734,8 +1731,8 @@ object AlwaysGoodOptimizations {
|
||||
},
|
||||
(Elidable & HasOpcode(LDA) & MatchAddrMode(1) & MatchParameter(2) & HasAddrModeIn(ZeroPage, ZeroPageX, Absolute, AbsoluteX)) ~
|
||||
(Elidable & HasOpcode(ADC) & HasImmediate(0) & HasClear(State.D)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(1) & MatchParameter(2) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { code =>
|
||||
val label = getNextLabel("ah")
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(1) & MatchParameter(2) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("ah")
|
||||
List(
|
||||
AssemblyLine.relative(BCC, label),
|
||||
code.last.copy(opcode = INC),
|
||||
@ -1753,8 +1750,8 @@ object AlwaysGoodOptimizations {
|
||||
},
|
||||
(Elidable & HasOpcode(TXA) & HasClear(State.D)) ~
|
||||
(Elidable & HasOpcode(ADC) & HasImmediate(0)) ~
|
||||
(Elidable & HasOpcode(TAX) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { code =>
|
||||
val label = getNextLabel("ah")
|
||||
(Elidable & HasOpcode(TAX) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("ah")
|
||||
List(
|
||||
AssemblyLine.relative(BCC, label),
|
||||
AssemblyLine.implied(INX),
|
||||
@ -1762,8 +1759,8 @@ object AlwaysGoodOptimizations {
|
||||
},
|
||||
(Elidable & HasOpcode(TYA) & HasClear(State.D)) ~
|
||||
(Elidable & HasOpcode(ADC) & HasImmediate(0)) ~
|
||||
(Elidable & HasOpcode(TAY) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { code =>
|
||||
val label = getNextLabel("ah")
|
||||
(Elidable & HasOpcode(TAY) & DoesntMatterWhatItDoesWith(State.A, State.C, State.Z, State.N, State.V)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("ah")
|
||||
List(
|
||||
AssemblyLine.relative(BCC, label),
|
||||
AssemblyLine.implied(INY),
|
||||
@ -1796,8 +1793,8 @@ object AlwaysGoodOptimizations {
|
||||
(Linear & Not(ChangesNAndZ) & Not(HasOpcode(CLC)) & Not(ChangesA)).* ~
|
||||
(Elidable & HasOpcode(CLC) & HasClear(State.D)) ~
|
||||
(Elidable & HasOpcode(ADC) & MatchAddrMode(0) & MatchParameter(1) & HasAddrModeIn(ZeroPage, ZeroPageX, Absolute, AbsoluteX)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.V, State.Z, State.N, State.A)) ~~> { code =>
|
||||
val label = getNextLabel("in")
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.V, State.Z, State.N, State.A)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("in")
|
||||
code.take(code.length - 3) ++ List(
|
||||
AssemblyLine.relative(BEQ, label),
|
||||
code.last.copy(opcode = INC),
|
||||
@ -1807,8 +1804,8 @@ object AlwaysGoodOptimizations {
|
||||
(HasOpcode(ANC) & HasImmediate(1)) ~
|
||||
(Linear & Not(ChangesNAndZ) & Not(ChangesA) & (Not(ChangesC) | HasOpcode(CLC))).* ~
|
||||
(Elidable & HasOpcode(ADC) & MatchAddrMode(0) & MatchParameter(1) & HasClear(State.D) & HasAddrModeIn(ZeroPage, ZeroPageX, Absolute, AbsoluteX)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.V, State.Z, State.N, State.A)) ~~> { code =>
|
||||
val label = getNextLabel("in")
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & DoesntMatterWhatItDoesWith(State.C, State.V, State.Z, State.N, State.A)) ~~> { (code, ctx) =>
|
||||
val label = ctx.nextLabel("in")
|
||||
code.head.copy(opcode = AND) :: code.take(code.length - 2).tail ++ List(
|
||||
AssemblyLine.relative(BEQ, label),
|
||||
code.last.copy(opcode = INC),
|
||||
@ -2234,7 +2231,7 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcode(TXA)) ~
|
||||
(Elidable & HasOpcode(ADC) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesNotConcernMemoryAt(0, 1)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesntMatterWhatItDoesWith(State.C, State.N, State.V, State.Z)) ~~> { (code, ctx) =>
|
||||
val label = getNextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
List(
|
||||
code(1), // BCC
|
||||
code(8).copy(opcode = INC),
|
||||
@ -2256,7 +2253,7 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcode(TXA)) ~
|
||||
(Elidable & HasOpcode(ADC) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesNotConcernMemoryAt(0, 1)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesntMatterWhatItDoesWith(State.C, State.N, State.V, State.Z)) ~~> { (code, ctx) =>
|
||||
val label = getNextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
List(
|
||||
code(1), // BCC
|
||||
code(8).copy(opcode = INC),
|
||||
@ -2275,7 +2272,7 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & Not(ConcernsX)) ~
|
||||
(Elidable & HasOpcode(STX) & MatchAddrMode(2) & MatchParameter(3) & DoesNotConcernMemoryAt(0, 1) & Not(HasAddrMode(ZeroPageY)) &
|
||||
DoesntMatterWhatItDoesWith(State.X, State.A, State.C, State.V)) ~~> { (code, ctx) =>
|
||||
val label = getNextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
List(
|
||||
code(4), // STA
|
||||
code.head.copy(opcode = LDA), // LDX
|
||||
@ -2289,7 +2286,7 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(0) & MatchParameter(1) & Not(ConcernsX)) ~
|
||||
(Elidable & HasOpcode(STX) & MatchAddrMode(2) & MatchParameter(3) & DoesNotConcernMemoryAt(0, 1) & Not(HasAddrMode(ZeroPageY)) &
|
||||
DoesntMatterWhatItDoesWith(State.X, State.A, State.C, State.V)) ~~> { (code, ctx) =>
|
||||
val label = getNextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
List(
|
||||
code(4), // STA
|
||||
AssemblyLine.immediate(ADC, 0),
|
||||
@ -2308,7 +2305,7 @@ object AlwaysGoodOptimizations {
|
||||
(Elidable & HasOpcode(TXA)) ~
|
||||
(Elidable & HasOpcodeIn(ORA, EOR) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesNotConcernMemoryAt(0, 1)) ~
|
||||
(Elidable & HasOpcode(STA) & MatchAddrMode(2) & MatchParameter(3) & Not(ConcernsX) & DoesntMatterWhatItDoesWith(State.C, State.N, State.V, State.Z)) ~~>{ (code, ctx) =>
|
||||
val label = getNextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
List(
|
||||
code(4), //EOR/ORA
|
||||
code(5), //STA
|
||||
|
@ -4,6 +4,7 @@ import millfork.CompilationOptions
|
||||
import millfork.assembly._
|
||||
import millfork.assembly.mos._
|
||||
import millfork.assembly.opt.SingleStatus
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.env._
|
||||
import millfork.error.{FatalErrorReporting, Logger}
|
||||
import millfork.node.{MosNiceFunctionProperty, NiceFunctionProperty}
|
||||
@ -85,7 +86,10 @@ class AssemblyMatchingContext(val compilationOptions: CompilationOptions,
|
||||
val labelMap: Map[String, Int],
|
||||
val zeropageRegister: Option[ThingInMemory],
|
||||
val niceFunctionProperties: Set[(NiceFunctionProperty, String)]) {
|
||||
@inline
|
||||
def log: Logger = compilationOptions.log
|
||||
@inline
|
||||
def nextLabel: LabelGenerator = compilationOptions.nextLabel
|
||||
|
||||
def functionChangesA(name: String): Boolean = !niceFunctionProperties(MosNiceFunctionProperty.DoesntChangeA -> name)
|
||||
|
||||
|
@ -3,6 +3,7 @@ package millfork.assembly.mos.opt
|
||||
import millfork.{CompilationFlag, CompilationOptions, OptimizationPresets}
|
||||
import millfork.assembly.{AssemblyOptimization, OptimizationContext}
|
||||
import millfork.assembly.mos.{AddrMode, AssemblyLine, Opcode}
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.env.NormalFunction
|
||||
import millfork.error.{ConsoleLogger, ErrorsOnlyLogger}
|
||||
|
||||
@ -56,7 +57,7 @@ object SuperOptimizer extends AssemblyOptimization[AssemblyLine] {
|
||||
)
|
||||
val optionsForMeasurements = options.copy(
|
||||
commandLineFlags = options.commandLineFlags + (CompilationFlag.InternalCurrentlyOptimizingForMeasurement -> true),
|
||||
log = new ErrorsOnlyLogger(options.log)
|
||||
jobContext = options.jobContext.copy(log = new ErrorsOnlyLogger(options.log))
|
||||
)
|
||||
val optimizationContextForMeasurements = optimizationContext.copy(options = optionsForMeasurements)
|
||||
val quicklyCleanedCode = quickScrub.foldLeft(code)((c, o) => o.optimize(m, c, optimizationContextForMeasurements))
|
||||
|
@ -6,6 +6,5 @@ import millfork.assembly.AbstractCode
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
abstract class AbstractCompiler[T <: AbstractCode] {
|
||||
def nextLabel(prefix: String): String
|
||||
def compile(ctx: CompilationContext): List[T]
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class AbstractExpressionCompiler[T <: AbstractCode] {
|
||||
}
|
||||
|
||||
def callingContext(ctx: CompilationContext, v: MemoryVariable): CompilationContext = {
|
||||
val result = new Environment(Some(ctx.env), "", ctx.options.platform.cpuFamily, ctx.log)
|
||||
val result = new Environment(Some(ctx.env), "", ctx.options.platform.cpuFamily, ctx.jobContext)
|
||||
result.registerVariable(VariableDeclarationStatement(v.name, v.typ.name, stack = false, global = false, constant = false, volatile = false, register = false, initialValue = None, address = None, bank = v.declaredBank), ctx.options)
|
||||
ctx.copy(env = result)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ abstract class AbstractReturnDispatch[T <: AbstractCode] {
|
||||
|
||||
val env = ctx.env.root
|
||||
val b = env.get[VariableType]("byte")
|
||||
val label = nextLabel("di")
|
||||
val label = ctx.nextLabel("di")
|
||||
val paramArrays = stmt.params.indices.map { ix =>
|
||||
val a = InitializedArray(label + "$" + ix + ".array", None, (paramMins(ix) to paramMaxes(ix)).map { key =>
|
||||
map(key)._2.lift(ix).getOrElse(LiteralExpression(0, 1))
|
||||
@ -132,8 +132,6 @@ abstract class AbstractReturnDispatch[T <: AbstractCode] {
|
||||
compileImpl(ctx, stmt, label, actualMin, actualMax, paramArrays, paramMins, map)
|
||||
}
|
||||
|
||||
def nextLabel(prefix: String): String
|
||||
|
||||
def compileImpl(ctx: CompilationContext,
|
||||
stmt: ReturnDispatchStatement,
|
||||
label: String,
|
||||
|
@ -19,8 +19,6 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
|
||||
def compile(ctx: CompilationContext, statement: ExecutableStatement): List[T]
|
||||
|
||||
def nextLabel(prefix: String): String
|
||||
|
||||
def labelChunk(labelName: String): List[T]
|
||||
|
||||
def jmpChunk(labelName: String): List[T] = jmpChunk(Label(labelName))
|
||||
@ -34,10 +32,10 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
def areBlocksLarge(blocks: List[T]*): Boolean
|
||||
|
||||
def compileWhileStatement(ctx: CompilationContext, s: WhileStatement): List[T] = {
|
||||
val start = nextLabel("wh")
|
||||
val middle = nextLabel("he")
|
||||
val inc = nextLabel("fp")
|
||||
val end = nextLabel("ew")
|
||||
val start = ctx.nextLabel("wh")
|
||||
val middle = ctx.nextLabel("he")
|
||||
val inc = ctx.nextLabel("fp")
|
||||
val end = ctx.nextLabel("ew")
|
||||
val condType = AbstractExpressionCompiler.getExpressionType(ctx, s.condition)
|
||||
val bodyBlock = compile(ctx.addLabels(s.labels, Label(end), Label(inc)), s.body)
|
||||
val incrementBlock = compile(ctx.addLabels(s.labels, Label(end), Label(inc)), s.increment)
|
||||
@ -71,9 +69,9 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
}
|
||||
|
||||
def compileDoWhileStatement(ctx: CompilationContext, s: DoWhileStatement): List[T] = {
|
||||
val start = nextLabel("do")
|
||||
val inc = nextLabel("fp")
|
||||
val end = nextLabel("od")
|
||||
val start = ctx.nextLabel("do")
|
||||
val inc = ctx.nextLabel("fp")
|
||||
val end = ctx.nextLabel("od")
|
||||
val condType = AbstractExpressionCompiler.getExpressionType(ctx, s.condition)
|
||||
val bodyBlock = compile(ctx.addLabels(s.labels, Label(end), Label(inc)), s.body)
|
||||
val incrementBlock = compile(ctx.addLabels(s.labels, Label(end), Label(inc)), s.increment)
|
||||
@ -136,13 +134,13 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
(f.direction, startEvaluated, endEvaluated) match {
|
||||
|
||||
case (ForDirection.Until | ForDirection.ParallelUntil, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, _))) if s == e - 1 =>
|
||||
val end = nextLabel("of")
|
||||
val end = ctx.nextLabel("of")
|
||||
compile(ctx.addLabels(names, Label(end), Label(end)), Assignment(vex, f.start).pos(p) :: f.body) ++ labelChunk(end)
|
||||
case (ForDirection.Until | ForDirection.ParallelUntil, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, _))) if s >= e =>
|
||||
Nil
|
||||
|
||||
case (ForDirection.To | ForDirection.ParallelTo, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, _))) if s == e =>
|
||||
val end = nextLabel("of")
|
||||
val end = ctx.nextLabel("of")
|
||||
compile(ctx.addLabels(names, Label(end), Label(end)), Assignment(vex, f.start).pos(p) :: f.body) ++ labelChunk(end)
|
||||
case (ForDirection.To | ForDirection.ParallelTo, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, _))) if s > e =>
|
||||
Nil
|
||||
@ -166,7 +164,7 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
))
|
||||
|
||||
case (ForDirection.DownTo, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, esize))) if s == e =>
|
||||
val end = nextLabel("of")
|
||||
val end = ctx.nextLabel("of")
|
||||
compile(ctx.addLabels(names, Label(end), Label(end)), Assignment(vex, LiteralExpression(s, ssize)).pos(p) :: f.body) ++ labelChunk(end)
|
||||
case (ForDirection.DownTo, Some(NumericConstant(s, ssize)), Some(NumericConstant(e, esize))) if s < e =>
|
||||
Nil
|
||||
@ -288,39 +286,39 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
case (Nil, _) =>
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, NoBranching)
|
||||
if (largeElseBlock) {
|
||||
val middle = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfFalse, middle), jmpChunk(end), labelChunk(middle), elseBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val end = nextLabel("fi")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfTrue, end), elseBlock, labelChunk(end)).flatten
|
||||
}
|
||||
case (_, Nil) =>
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, NoBranching)
|
||||
if (largeThenBlock) {
|
||||
val middle = nextLabel("th")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("th")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfTrue, middle), jmpChunk(end), labelChunk(middle), thenBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val end = nextLabel("fi")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfFalse, end), thenBlock, labelChunk(end)).flatten
|
||||
}
|
||||
case _ =>
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, NoBranching)
|
||||
if (largeThenBlock) {
|
||||
if (largeElseBlock) {
|
||||
val middleT = nextLabel("th")
|
||||
val middleE = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middleT = ctx.nextLabel("th")
|
||||
val middleE = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfTrue, middleT), jmpChunk(middleE), labelChunk(middleT), thenBlock, jmpChunk(end), labelChunk(middleE), elseBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val middle = nextLabel("th")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("th")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfTrue, middle), elseBlock, jmpChunk(end), labelChunk(middle), thenBlock, labelChunk(end)).flatten
|
||||
}
|
||||
} else {
|
||||
val middle = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
List(conditionBlock, branchChunk(jumpIfFalse, middle), thenBlock, jmpChunk(end), labelChunk(middle), elseBlock, labelChunk(end)).flatten
|
||||
}
|
||||
}
|
||||
@ -330,43 +328,43 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
compileExpressionForBranching(ctx, s.condition, NoBranching)
|
||||
case (Nil, _) =>
|
||||
if (largeElseBlock) {
|
||||
val middle = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfFalse(middle))
|
||||
List(conditionBlock, jmpChunk(end), labelChunk(middle), elseBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val end = nextLabel("fi")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfTrue(end))
|
||||
List(conditionBlock, elseBlock, labelChunk(end)).flatten
|
||||
}
|
||||
case (_, Nil) =>
|
||||
if (largeThenBlock) {
|
||||
val middle = nextLabel("th")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("th")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfTrue(middle))
|
||||
List(conditionBlock, jmpChunk(end), labelChunk(middle), thenBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val end = nextLabel("fi")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfFalse(end))
|
||||
List(conditionBlock, thenBlock, labelChunk(end)).flatten
|
||||
}
|
||||
case _ =>
|
||||
if (largeThenBlock) {
|
||||
if (largeElseBlock) {
|
||||
val middleT = nextLabel("th")
|
||||
val middleE = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middleT = ctx.nextLabel("th")
|
||||
val middleE = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfTrue(middleT))
|
||||
List(conditionBlock, jmpChunk(middleE), labelChunk(middleT), thenBlock, jmpChunk(end), labelChunk(middleE), elseBlock, labelChunk(end)).flatten
|
||||
} else {
|
||||
val middle = nextLabel("th")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("th")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfTrue(middle))
|
||||
List(conditionBlock, elseBlock, jmpChunk(end), labelChunk(middle), thenBlock, labelChunk(end)).flatten
|
||||
}
|
||||
} else {
|
||||
val middle = nextLabel("el")
|
||||
val end = nextLabel("fi")
|
||||
val middle = ctx.nextLabel("el")
|
||||
val end = ctx.nextLabel("fi")
|
||||
val conditionBlock = compileExpressionForBranching(ctx, s.condition, BranchIfFalse(middle))
|
||||
List(conditionBlock, thenBlock, jmpChunk(end), labelChunk(middle), elseBlock, labelChunk(end)).flatten
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package millfork.compiler
|
||||
import millfork.env.{Environment, Label, NormalFunction}
|
||||
import millfork.error.Logger
|
||||
import millfork.node.NiceFunctionProperty
|
||||
import millfork.{CompilationFlag, CompilationOptions}
|
||||
import millfork.{CompilationFlag, CompilationOptions, JobContext}
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
@ -16,7 +16,7 @@ case class CompilationContext(env: Environment,
|
||||
breakLabels: Map[String, Label] = Map(),
|
||||
continueLabels: Map[String, Label] = Map()){
|
||||
def withInlinedEnv(environment: Environment, newLabel: String): CompilationContext = {
|
||||
val newEnv = new Environment(Some(env), newLabel, environment.cpuFamily, log)
|
||||
val newEnv = new Environment(Some(env), newLabel, environment.cpuFamily, jobContext)
|
||||
newEnv.things ++= environment.things
|
||||
copy(env = newEnv)
|
||||
}
|
||||
@ -36,5 +36,10 @@ case class CompilationContext(env: Environment,
|
||||
def neverCheckArrayBounds: CompilationContext =
|
||||
this.copy(options = options.copy(commandLineFlags = options.commandLineFlags + (CompilationFlag.CheckIndexOutOfBounds -> false)))
|
||||
|
||||
@inline
|
||||
def jobContext: JobContext = options.jobContext
|
||||
@inline
|
||||
def log: Logger = options.log
|
||||
@inline
|
||||
def nextLabel: LabelGenerator = options.nextLabel
|
||||
}
|
||||
|
13
src/main/scala/millfork/compiler/LabelGenerator.scala
Normal file
13
src/main/scala/millfork/compiler/LabelGenerator.scala
Normal file
@ -0,0 +1,13 @@
|
||||
package millfork.compiler
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
/**
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
class LabelGenerator {
|
||||
|
||||
private val labelCounter = new AtomicLong
|
||||
|
||||
def apply(prefix: String): String = "." + prefix + "__" + labelCounter.incrementAndGet().formatted("%05d")
|
||||
}
|
@ -12,8 +12,6 @@ import millfork.node.{MosRegister, _}
|
||||
*/
|
||||
abstract class MacroExpander[T <: AbstractCode] {
|
||||
|
||||
def nextLabel(prefix: String): String
|
||||
|
||||
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 = {
|
||||
@ -77,7 +75,7 @@ abstract class MacroExpander[T <: AbstractCode] {
|
||||
case MosAssemblyStatement(LABEL, _, VariableExpression(l), _) => Some(l)
|
||||
case _ => None
|
||||
}.toSet
|
||||
val labelPrefix = nextLabel("il")
|
||||
val labelPrefix = ctx.nextLabel("il")
|
||||
paramPreparation -> actualCode.map {
|
||||
case s@MosAssemblyStatement(_, _, VariableExpression(v), _) if localLabels(v) =>
|
||||
s.copy(expression = VariableExpression(labelPrefix + v))
|
||||
|
@ -201,8 +201,8 @@ object BuiltIns {
|
||||
case _ =>
|
||||
val compileCounter = MosExpressionCompiler.preserveRegisterIfNeeded(ctx, MosRegister.A,
|
||||
MosExpressionCompiler.compile(ctx, r, Some(b -> RegisterVariable(MosRegister.X, b)), NoBranching))
|
||||
val labelSkip = MosCompiler.nextLabel("ss")
|
||||
val labelRepeat = MosCompiler.nextLabel("sr")
|
||||
val labelSkip = ctx.nextLabel("ss")
|
||||
val labelRepeat = ctx.nextLabel("sr")
|
||||
val loop = List(
|
||||
AssemblyLine.relative(BEQ, labelSkip),
|
||||
AssemblyLine.label(labelRepeat),
|
||||
@ -297,8 +297,8 @@ object BuiltIns {
|
||||
|
||||
val compileCounter = MosExpressionCompiler.preserveRegisterIfNeeded(ctx, MosRegister.A,
|
||||
MosExpressionCompiler.compile(ctx, rhs, Some(b -> RegisterVariable(register, b)), NoBranching))
|
||||
val labelSkip = MosCompiler.nextLabel("ss")
|
||||
val labelRepeat = MosCompiler.nextLabel("sr")
|
||||
val labelSkip = ctx.nextLabel("ss")
|
||||
val labelRepeat = ctx.nextLabel("sr")
|
||||
|
||||
if (ctx.options.flags(CompilationFlag.EmitNative65816Opcodes)) {
|
||||
targetBytes match {
|
||||
@ -438,7 +438,7 @@ object BuiltIns {
|
||||
case ComparisonType.LessOrEqualUnsigned =>
|
||||
List(AssemblyLine.relative(BCC, Label(label)), AssemblyLine.relative(BEQ, Label(label)))
|
||||
case ComparisonType.GreaterUnsigned =>
|
||||
val x = MosCompiler.nextLabel("co")
|
||||
val x = ctx.nextLabel("co")
|
||||
List(
|
||||
AssemblyLine.relative(BEQ, x),
|
||||
AssemblyLine.relative(BCS, Label(label)),
|
||||
@ -451,7 +451,7 @@ object BuiltIns {
|
||||
case ComparisonType.LessOrEqualSigned =>
|
||||
List(AssemblyLine.relative(BMI, Label(label)), AssemblyLine.relative(BEQ, Label(label)))
|
||||
case ComparisonType.GreaterSigned =>
|
||||
val x = MosCompiler.nextLabel("co")
|
||||
val x = ctx.nextLabel("co")
|
||||
List(
|
||||
AssemblyLine.relative(BEQ, x),
|
||||
AssemblyLine.relative(BPL, Label(label)),
|
||||
@ -538,7 +538,7 @@ object BuiltIns {
|
||||
compactEqualityComparison match {
|
||||
case Some(code) => code :+ AssemblyLine.relative(BEQ, Label(x))
|
||||
case None =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
cmpTo(LDA, ll) ++
|
||||
cmpTo(CMP, rl) ++
|
||||
List(AssemblyLine.relative(BNE, innerLabel)) ++
|
||||
@ -562,7 +562,7 @@ object BuiltIns {
|
||||
}
|
||||
|
||||
case ComparisonType.LessUnsigned =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
cmpTo(LDA, lh) ++
|
||||
cmpTo(CMP, rh) ++
|
||||
List(
|
||||
@ -575,7 +575,7 @@ object BuiltIns {
|
||||
AssemblyLine.label(innerLabel))
|
||||
|
||||
case ComparisonType.LessOrEqualUnsigned =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
cmpTo(LDA, rh) ++
|
||||
cmpTo(CMP, lh) ++
|
||||
List(AssemblyLine.relative(BCC, innerLabel),
|
||||
@ -586,7 +586,7 @@ object BuiltIns {
|
||||
AssemblyLine.label(innerLabel))
|
||||
|
||||
case ComparisonType.GreaterUnsigned =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
cmpTo(LDA, rh) ++
|
||||
cmpTo(CMP, lh) ++
|
||||
List(AssemblyLine.relative(BCC, Label(x)),
|
||||
@ -597,7 +597,7 @@ object BuiltIns {
|
||||
AssemblyLine.label(innerLabel))
|
||||
|
||||
case ComparisonType.GreaterOrEqualUnsigned =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
cmpTo(LDA, lh) ++
|
||||
cmpTo(CMP, rh) ++
|
||||
List(AssemblyLine.relative(BCC, innerLabel),
|
||||
@ -660,7 +660,7 @@ object BuiltIns {
|
||||
case _ =>
|
||||
effectiveComparisonType match {
|
||||
case ComparisonType.Equal =>
|
||||
val innerLabel = MosCompiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
val bytewise = l.zip(r).map{
|
||||
case (cmpL, cmpR) => cmpTo(LDA, cmpL) ++ cmpTo(CMP, cmpR)
|
||||
}
|
||||
@ -838,7 +838,7 @@ object BuiltIns {
|
||||
case Nil => Nil
|
||||
case x :: Nil => staTo(DEC, x)
|
||||
case x :: xs =>
|
||||
val label = MosCompiler.nextLabel("de")
|
||||
val label = ctx.nextLabel("de")
|
||||
staTo(LDA, x) ++
|
||||
List(AssemblyLine.relative(BNE, label)) ++
|
||||
doDec(xs) ++
|
||||
@ -867,7 +867,7 @@ object BuiltIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
val label = MosCompiler.nextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
return staTo(INC, targetBytes.head) ++ targetBytes.tail.flatMap(l => AssemblyLine.relative(BNE, label)::staTo(INC, l)) :+ AssemblyLine.label(label)
|
||||
case Some(NumericConstant(-1, _)) if canUseIncDec && subtract =>
|
||||
if (ctx.options.flags(CompilationFlag.Emit65CE02Opcodes)) {
|
||||
@ -886,7 +886,7 @@ object BuiltIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
val label = MosCompiler.nextLabel("in")
|
||||
val label = ctx.nextLabel("in")
|
||||
return staTo(INC, targetBytes.head) ++ targetBytes.tail.flatMap(l => AssemblyLine.relative(BNE, label)::staTo(INC, l)) :+ AssemblyLine.label(label)
|
||||
case Some(NumericConstant(1, _)) if canUseIncDec && subtract =>
|
||||
if (ctx.options.flags(CompilationFlag.Emit65CE02Opcodes)) {
|
||||
@ -905,7 +905,7 @@ object BuiltIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
val label = MosCompiler.nextLabel("de")
|
||||
val label = ctx.nextLabel("de")
|
||||
return doDec(targetBytes)
|
||||
case Some(NumericConstant(-1, _)) if canUseIncDec && !subtract =>
|
||||
if (ctx.options.flags(CompilationFlag.Emit65CE02Opcodes)) {
|
||||
@ -924,7 +924,7 @@ object BuiltIns {
|
||||
}
|
||||
}
|
||||
}
|
||||
val label = MosCompiler.nextLabel("de")
|
||||
val label = ctx.nextLabel("de")
|
||||
return doDec(targetBytes)
|
||||
case Some(constant) =>
|
||||
addendSize = targetSize
|
||||
@ -1053,7 +1053,7 @@ object BuiltIns {
|
||||
} else {
|
||||
if (i >= addendSize) {
|
||||
if (addendType.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
buffer += AssemblyLine.implied(TXA)
|
||||
if (i == addendSize) {
|
||||
buffer += AssemblyLine.immediate(ORA, 0x7f)
|
||||
@ -1176,7 +1176,7 @@ object BuiltIns {
|
||||
}
|
||||
} else {
|
||||
if (paramType.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
buffer += AssemblyLine.implied(TXA)
|
||||
if (i == paramSize) {
|
||||
buffer += AssemblyLine.immediate(ORA, 0x7f)
|
||||
@ -1233,7 +1233,7 @@ object BuiltIns {
|
||||
if (i < variable.typ.size) {
|
||||
AssemblyLine.variable(ctx, CMP, variable, i)
|
||||
} else if (variable.typ.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
AssemblyLine.variable(ctx, LDA, variable, variable.typ.size - 1) ++ List(
|
||||
AssemblyLine.immediate(ORA, 0x7F),
|
||||
AssemblyLine.relative(BMI, label),
|
||||
|
@ -43,11 +43,11 @@ object DecimalBuiltIns {
|
||||
}
|
||||
|
||||
private def shiftOrRotateAccumulatorRight(ctx: CompilationContext, rotate: Boolean, preserveCarry: Boolean) = {
|
||||
val skipHiDigit = MosCompiler.nextLabel("ds")
|
||||
val skipLoDigit = MosCompiler.nextLabel("ds")
|
||||
val skipHiDigit = ctx.nextLabel("ds")
|
||||
val skipLoDigit = ctx.nextLabel("ds")
|
||||
val cmos = ctx.options.flags(CompilationFlag.EmitCmosOpcodes)
|
||||
if (preserveCarry) {
|
||||
val constantLabel = MosCompiler.nextLabel("c8")
|
||||
val constantLabel = ctx.nextLabel("c8")
|
||||
val bit = if (cmos) {
|
||||
AssemblyLine.immediate(BIT, 8)
|
||||
} else {
|
||||
|
@ -1,7 +1,5 @@
|
||||
package millfork.compiler.mos
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
import millfork.CompilationFlag
|
||||
import millfork.assembly.mos.Opcode._
|
||||
import millfork.assembly.mos._
|
||||
@ -15,10 +13,6 @@ import millfork.env._
|
||||
object MosCompiler extends AbstractCompiler[AssemblyLine] {
|
||||
|
||||
|
||||
private val labelCounter = new AtomicLong
|
||||
|
||||
def nextLabel(prefix: String): String = "." + prefix + "__" + labelCounter.incrementAndGet().formatted("%05d")
|
||||
|
||||
override def compile(ctx: CompilationContext): List[AssemblyLine] = {
|
||||
ctx.env.nameCheck(ctx.function.code)
|
||||
val chunk = MosStatementCompiler.compile(ctx, ctx.function.code)
|
||||
|
@ -326,7 +326,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA(ctx) ++ List(
|
||||
AssemblyLine.implied(XBA),
|
||||
AssemblyLine.implied(PLA))
|
||||
} else List(AssemblyLine.immediate(LDX, 0), AssemblyLine.implied(XBA)) ++ AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDX, 0)
|
||||
@ -340,7 +340,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA(ctx) ++ List(
|
||||
AssemblyLine.implied(TAX),
|
||||
AssemblyLine.implied(PLA))
|
||||
} else AssemblyLine.variable(ctx, LDA, source) :+ AssemblyLine.immediate(LDX, 0)
|
||||
@ -351,7 +351,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
AssemblyLine.variable(ctx, LDA, source) ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA(ctx) ++ List(
|
||||
AssemblyLine.implied(TAY),
|
||||
AssemblyLine.implied(PLA))
|
||||
} else {
|
||||
@ -363,7 +363,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case RegisterVariable(MosRegister.XA, _) =>
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
AssemblyLine.variable(ctx, LDX, source) ++ List(AssemblyLine.implied(TXA)) ++ signExtendA()
|
||||
AssemblyLine.variable(ctx, LDX, source) ++ List(AssemblyLine.implied(TXA)) ++ signExtendA(ctx)
|
||||
} else
|
||||
AssemblyLine.variable(ctx, LDX, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||
case 2 =>
|
||||
@ -372,7 +372,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case RegisterVariable(MosRegister.YA, _) =>
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
AssemblyLine.variable(ctx, LDY, source) ++ List(AssemblyLine.implied(TYA)) ++ signExtendA()
|
||||
AssemblyLine.variable(ctx, LDY, source) ++ List(AssemblyLine.implied(TYA)) ++ signExtendA(ctx)
|
||||
} else
|
||||
AssemblyLine.variable(ctx, LDY, source) :+ AssemblyLine.immediate(LDA, 0)
|
||||
case 2 =>
|
||||
@ -386,7 +386,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
val copyFromLo = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) ++ AssemblyLine.variable(ctx, STA, target, i))
|
||||
val copy = if (shouldCopyFromHiToLo(source.toAddress, target.toAddress)) copyFromLo.reverse else copyFromLo
|
||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
signExtendA(ctx) ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
} else {
|
||||
AssemblyLine.immediate(LDA, 0) ::
|
||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
@ -400,7 +400,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
} else {
|
||||
val copy = List.tabulate(exprType.size)(i => AssemblyLine.variable(ctx, LDA, source, i) :+ AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i))
|
||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
signExtendA(ctx) ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
} else {
|
||||
AssemblyLine.immediate(LDA, 0) ::
|
||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
@ -419,7 +419,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
List(
|
||||
AssemblyLine.implied(TSX),
|
||||
AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset),
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA() ++ List(
|
||||
AssemblyLine.implied(PHA)) ++ signExtendA(ctx) ++ List(
|
||||
AssemblyLine.implied(TAX),
|
||||
AssemblyLine.implied(PLA))
|
||||
} else List(
|
||||
@ -437,7 +437,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case RegisterVariable(MosRegister.AY, _) =>
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
??? // TODO
|
||||
} else {
|
||||
List(
|
||||
@ -455,7 +455,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case RegisterVariable(MosRegister.YA, _) =>
|
||||
exprType.size match {
|
||||
case 1 => if (exprType.isSigned) {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
??? // TODO
|
||||
} else {
|
||||
List(
|
||||
@ -475,7 +475,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
} else {
|
||||
val copy = List.tabulate(exprType.size)(i => AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i) :: AssemblyLine.variable(ctx, STA, target, i))
|
||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
signExtendA(ctx) ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
} else {
|
||||
AssemblyLine.immediate(LDA, 0) ::
|
||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.variable(ctx, STA, target, i + exprType.size)).flatten
|
||||
@ -490,7 +490,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
val copyFromLo = List.tabulate(exprType.size)(i => List(AssemblyLine.absoluteX(LDA, offset + ctx.extraStackOffset + i), AssemblyLine.absoluteX(STA, target.baseOffset + i)))
|
||||
val copy = if (shouldCopyFromHiToLo(NumericConstant(source.baseOffset, 2), NumericConstant(target.baseOffset, 2))) copyFromLo.reverse else copyFromLo
|
||||
val extend = if (exprType.size == target.typ.size) Nil else if (exprType.isSigned) {
|
||||
signExtendA() ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
signExtendA(ctx) ++ List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
} else {
|
||||
AssemblyLine.immediate(LDA, 0) ::
|
||||
List.tabulate(target.typ.size - exprType.size)(i => AssemblyLine.absoluteX(STA, target.baseOffset + ctx.extraStackOffset + i + exprType.size))
|
||||
@ -523,7 +523,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
AssemblyLine.variable(ctx, STA, target)
|
||||
}
|
||||
else if (target.typ.isSigned) {
|
||||
AssemblyLine.variable(ctx, STA, target) ++ signExtendA() ++
|
||||
AssemblyLine.variable(ctx, STA, target) ++ signExtendA(ctx) ++
|
||||
List.tabulate(target.typ.size - 1)(i => AssemblyLine.variable(ctx, STA, target, i + 1)).flatten
|
||||
} else {
|
||||
AssemblyLine.variable(ctx, STA, target) ++
|
||||
@ -697,7 +697,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
val compilation = compile(ctx, param, Some(MosExpressionCompiler.getExpressionType(ctx, param) -> RegisterVariable(MosRegister.AX, w)), BranchSpec.None)
|
||||
if (hi) {
|
||||
if (typ.size == 2) compilation :+ AssemblyLine.implied(TXA)
|
||||
else if (typ.isSigned) compilation ++ signExtendA()
|
||||
else if (typ.isSigned) compilation ++ signExtendA(ctx)
|
||||
else List(AssemblyLine.immediate(LDA, 0))
|
||||
} else compilation
|
||||
}
|
||||
@ -720,7 +720,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case _ =>
|
||||
ctx.log.warn("Unspecified nonet operation, results might be unpredictable", expr.position)
|
||||
}
|
||||
val label = MosCompiler.nextLabel("no")
|
||||
val label = ctx.nextLabel("no")
|
||||
compile(ctx, params.head, Some(b -> RegisterVariable(MosRegister.A, b)), BranchSpec.None) ++ List(
|
||||
AssemblyLine.immediate(LDX, 0),
|
||||
AssemblyLine.relative(BCC, label),
|
||||
@ -734,7 +734,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case BranchIfFalse(_) =>
|
||||
params.flatMap(compile(ctx, _, exprTypeAndVariable, branches))
|
||||
case _ =>
|
||||
val skip = MosCompiler.nextLabel("an")
|
||||
val skip = ctx.nextLabel("an")
|
||||
params.init.flatMap(compile(ctx, _, exprTypeAndVariable, BranchIfFalse(skip))) ++
|
||||
compile(ctx, params.last, exprTypeAndVariable, branches) ++
|
||||
List(AssemblyLine.label(skip))
|
||||
@ -745,7 +745,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case BranchIfTrue(_) =>
|
||||
params.flatMap(compile(ctx, _, exprTypeAndVariable, branches))
|
||||
case _ =>
|
||||
val skip = MosCompiler.nextLabel("or")
|
||||
val skip = ctx.nextLabel("or")
|
||||
params.init.flatMap(compile(ctx, _, exprTypeAndVariable, BranchIfTrue(skip))) ++
|
||||
compile(ctx, params.last, exprTypeAndVariable, branches) ++
|
||||
List(AssemblyLine.label(skip))
|
||||
@ -1189,7 +1189,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
AssemblyLine.variable(ctx, STA, v)
|
||||
case s if s > 1 =>
|
||||
if (t.isSigned) {
|
||||
AssemblyLine.variable(ctx, STA, v) ++ signExtendA() ++ List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||
AssemblyLine.variable(ctx, STA, v) ++ signExtendA(ctx) ++ List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||
} else {
|
||||
AssemblyLine.variable(ctx, STA, v) ++ List(AssemblyLine.immediate(LDA, 0)) ++
|
||||
List.tabulate(s - 1)(i => AssemblyLine.variable(ctx, STA, v, i + 1)).flatten
|
||||
@ -1206,7 +1206,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
AssemblyLine.variable(ctx, STA, v) ++
|
||||
AssemblyLine.variable(ctx, STX, v, 1) ++
|
||||
List(AssemblyLine.implied(TXA)) ++
|
||||
signExtendA() ++
|
||||
signExtendA(ctx) ++
|
||||
List.tabulate(s - 2)(i => AssemblyLine.variable(ctx, STA, v, i + 2)).flatten
|
||||
} else {
|
||||
AssemblyLine.variable(ctx, STA, v) ++ AssemblyLine.variable(ctx, STX, v, 1) ++ List(
|
||||
@ -1224,7 +1224,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
List(
|
||||
AssemblyLine.implied(TSX),
|
||||
AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset)) ++
|
||||
signExtendA() ++
|
||||
signExtendA(ctx) ++
|
||||
List.tabulate(s - 1)(i => AssemblyLine.absoluteX(STA, v.baseOffset + ctx.extraStackOffset + i + 1))
|
||||
} else {
|
||||
List(
|
||||
@ -1293,7 +1293,7 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
case _ =>
|
||||
}
|
||||
if (arrayLength > 0 && arrayLength < 255) {
|
||||
val label = MosCompiler.nextLabel("bc")
|
||||
val label = ctx.nextLabel("bc")
|
||||
val compare = register match {
|
||||
case MosRegister.A => CMP
|
||||
case MosRegister.X => CPX
|
||||
@ -1311,8 +1311,8 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
||||
}
|
||||
}
|
||||
|
||||
private def signExtendA(): List[AssemblyLine] = {
|
||||
val label = MosCompiler.nextLabel("sx")
|
||||
private def signExtendA(ctx: CompilationContext): List[AssemblyLine] = {
|
||||
val label = ctx.nextLabel("sx")
|
||||
List(
|
||||
AssemblyLine.immediate(ORA, 0x7F),
|
||||
AssemblyLine.relative(BMI, label),
|
||||
|
@ -10,7 +10,6 @@ import millfork.node._
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object MosMacroExpander extends MacroExpander[AssemblyLine] {
|
||||
override def nextLabel(prefix: String): String = MosCompiler.nextLabel(prefix)
|
||||
|
||||
override def prepareAssemblyParams(ctx: CompilationContext, assParams: List[AssemblyParam], params: List[Expression], code: List[ExecutableStatement]): (List[AssemblyLine], List[ExecutableStatement]) = {
|
||||
var paramPreparation = List[AssemblyLine]()
|
||||
|
@ -80,5 +80,4 @@ object MosReturnDispatch extends AbstractReturnDispatch[AssemblyLine] {
|
||||
}
|
||||
}
|
||||
|
||||
override def nextLabel(prefix: String): String = MosCompiler.nextLabel("di")
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ object MosStatementCompiler extends AbstractStatementCompiler[AssemblyLine] {
|
||||
env.lookupFunction(name, params.map(p => MosExpressionCompiler.getExpressionType(ctx, p) -> p)) match {
|
||||
case Some(i: MacroFunction) =>
|
||||
val (paramPreparation, inlinedStatements) = MosMacroExpander.inlineFunction(ctx, i, params, e.position)
|
||||
paramPreparation ++ compile(ctx.withInlinedEnv(i.environment, MosCompiler.nextLabel("en")), inlinedStatements)
|
||||
paramPreparation ++ compile(ctx.withInlinedEnv(i.environment, ctx.nextLabel("en")), inlinedStatements)
|
||||
case _ =>
|
||||
MosExpressionCompiler.compile(ctx, e, None, NoBranching)
|
||||
}
|
||||
@ -308,8 +308,6 @@ object MosStatementCompiler extends AbstractStatementCompiler[AssemblyLine] {
|
||||
AssemblyLine.implied(TSX) :: (List.fill(m.stackVariablesSize)(AssemblyLine.implied(INX)) :+ AssemblyLine.implied(TXS)) // this TXS is fine, it won't appear in 65816 code
|
||||
}
|
||||
|
||||
override def nextLabel(prefix: String): String = MosCompiler.nextLabel(prefix)
|
||||
|
||||
override def getStatementPreprocessor(ctx: CompilationContext, statements: List[ExecutableStatement]): AbstractStatementPreprocessor =
|
||||
new MosStatementPreprocessor(ctx, statements)
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ object PseudoregisterBuiltIns {
|
||||
val typ = MosExpressionCompiler.getExpressionType(ctx, v)
|
||||
if (typ.size == 1 && !typ.isSigned) {
|
||||
val bytePart = MosExpressionCompiler.compile(ctx, v, Some(b -> RegisterVariable(MosRegister.A, b)), BranchSpec.None)
|
||||
val label = MosCompiler.nextLabel("ah")
|
||||
val label = ctx.nextLabel("ah")
|
||||
return bytePart ++ List(
|
||||
AssemblyLine.implied(CLC),
|
||||
AssemblyLine.immediate(ADC, constPart.loByte),
|
||||
@ -216,8 +216,8 @@ object PseudoregisterBuiltIns {
|
||||
else List(AssemblyLine.implied(PLA), AssemblyLine.implied(TAX))
|
||||
)
|
||||
}
|
||||
val labelRepeat = MosCompiler.nextLabel("sr")
|
||||
val labelSkip = MosCompiler.nextLabel("ss")
|
||||
val labelRepeat = ctx.nextLabel("sr")
|
||||
val labelSkip = ctx.nextLabel("ss")
|
||||
if (ctx.options.flag(CompilationFlag.EmitNative65816Opcodes)) {
|
||||
compileCounterAndPrepareFirstParam ++ List(
|
||||
AssemblyLine.relative(BEQ, labelSkip),
|
||||
|
@ -391,7 +391,7 @@ object Z80BulkMemoryOperations {
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, extraInitializationPair._2)
|
||||
}
|
||||
|
||||
val label = Z80Compiler.nextLabel("me")
|
||||
val label = ctx.nextLabel("me")
|
||||
val body = if (ldr.isDefined && ctx.options.flag(CompilationFlag.EmitZ80Opcodes)) {
|
||||
List(ZLine.implied(ldr.get))
|
||||
} else {
|
||||
|
@ -197,7 +197,7 @@ object Z80Comparisons {
|
||||
val calculateRight = Z80ExpressionCompiler.compileByteReads(ctx, r, size, ZExpressionTarget.BC)
|
||||
val preserveHl = isBytesFromHL(calculateLeft)
|
||||
val preserveBc = isBytesFromBC(calculateRight)
|
||||
val innerLabel = Z80Compiler.nextLabel("cp")
|
||||
val innerLabel = ctx.nextLabel("cp")
|
||||
val (jump, epilogue) = (compType, branches) match {
|
||||
case (Equal, BranchIfTrue(label)) =>
|
||||
ZLine.jump(innerLabel, IfFlagClear(ZFlag.Z)) -> ZLine.jump(label, IfFlagSet(ZFlag.Z))
|
||||
|
@ -1,12 +1,9 @@
|
||||
package millfork.compiler.z80
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
import millfork.CompilationFlag
|
||||
import millfork.assembly.z80.ZLine
|
||||
import millfork.compiler.{AbstractCompiler, CompilationContext}
|
||||
import millfork.env.{Label, NormalParamSignature}
|
||||
import millfork.error.ConsoleLogger
|
||||
import millfork.node.ZRegister
|
||||
|
||||
/**
|
||||
@ -14,10 +11,6 @@ import millfork.node.ZRegister
|
||||
*/
|
||||
object Z80Compiler extends AbstractCompiler[ZLine] {
|
||||
|
||||
private val labelCounter = new AtomicLong
|
||||
|
||||
override def nextLabel(prefix: String): String = "." + prefix + "__" + labelCounter.incrementAndGet().formatted("%05d")
|
||||
|
||||
override def compile(ctx: CompilationContext): List[ZLine] = {
|
||||
ctx.env.nameCheck(ctx.function.code)
|
||||
val chunk = Z80StatementCompiler.compile(ctx, ctx.function.code)
|
||||
|
@ -159,7 +159,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
||||
def targetifyA(ctx: CompilationContext, target: ZExpressionTarget.Value, lines: List[ZLine], isSigned: Boolean): List[ZLine] = {
|
||||
def toWord(h: ZRegister.Value, l: ZRegister.Value) = {
|
||||
lines ++ (if (isSigned) {
|
||||
val label = Z80Compiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
if (ctx.options.flag(CompilationFlag.EmitIntel8080Opcodes)) {
|
||||
List(
|
||||
ZLine.ld8(l, ZRegister.A),
|
||||
@ -554,7 +554,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
||||
case BranchIfFalse(_) =>
|
||||
params.flatMap(compile(ctx, _, target, branches))
|
||||
case _ =>
|
||||
val skip = Z80Compiler.nextLabel("an")
|
||||
val skip = ctx.nextLabel("an")
|
||||
params.init.flatMap(compile(ctx, _, target, BranchIfFalse(skip))) ++
|
||||
compile(ctx, params.last, target, branches) ++
|
||||
List(ZLine.label(skip))
|
||||
@ -565,7 +565,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
||||
case BranchIfTrue(_) =>
|
||||
params.flatMap(compile(ctx, _, target, branches))
|
||||
case _ =>
|
||||
val skip = Z80Compiler.nextLabel("or")
|
||||
val skip = ctx.nextLabel("or")
|
||||
params.init.flatMap(compile(ctx, _, target, BranchIfTrue(skip))) ++
|
||||
compile(ctx, params.last, target, branches) ++
|
||||
List(ZLine.label(skip))
|
||||
@ -1011,7 +1011,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
||||
|
||||
private def signExtendHighestByte(ctx: CompilationContext, hiRegister: ZRegister.Value): List[ZLine] = {
|
||||
val prefix = if (hiRegister == ZRegister.A) Nil else List(ZLine.ld8(ZRegister.A, hiRegister))
|
||||
val label = Z80Compiler.nextLabel("sx")
|
||||
val label = ctx.nextLabel("sx")
|
||||
if (ctx.options.flag(CompilationFlag.EmitIntel8080Opcodes)) {
|
||||
prefix ++ List(
|
||||
ZLine.imm8(OR, 0x7f),
|
||||
|
@ -12,7 +12,6 @@ import millfork.node._
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object Z80MacroExpander extends MacroExpander[ZLine] {
|
||||
override def nextLabel(prefix: String): String = Z80Compiler.nextLabel(prefix)
|
||||
|
||||
override def prepareAssemblyParams(ctx: CompilationContext, assParams: List[AssemblyParam], params: List[Expression], code: List[ExecutableStatement]): (List[ZLine], List[ExecutableStatement]) = {
|
||||
var paramPreparation = List[ZLine]()
|
||||
|
@ -19,9 +19,9 @@ object Z80Multiply {
|
||||
import ZRegister._
|
||||
import ZLine._
|
||||
if(ctx.options.flag(CompilationFlag.EmitExtended80Opcodes)) {
|
||||
val lblAdd = Z80Compiler.nextLabel("mu")
|
||||
val lblLoop = Z80Compiler.nextLabel("mu")
|
||||
val lblStart = Z80Compiler.nextLabel("mu")
|
||||
val lblAdd = ctx.nextLabel("mu")
|
||||
val lblLoop = ctx.nextLabel("mu")
|
||||
val lblStart = ctx.nextLabel("mu")
|
||||
List(
|
||||
ld8(E, A),
|
||||
ldImm8(A, 0),
|
||||
@ -36,9 +36,9 @@ object Z80Multiply {
|
||||
jumpR(ctx, lblLoop, IfFlagClear(ZFlag.Z)))
|
||||
} else {
|
||||
// TODO: optimize
|
||||
val lblAdd = Z80Compiler.nextLabel("mu")
|
||||
val lblLoop = Z80Compiler.nextLabel("mu")
|
||||
val lblStart = Z80Compiler.nextLabel("mu")
|
||||
val lblAdd = ctx.nextLabel("mu")
|
||||
val lblLoop = ctx.nextLabel("mu")
|
||||
val lblStart = ctx.nextLabel("mu")
|
||||
List(
|
||||
ld8(E, A),
|
||||
ldImm8(C, 0),
|
||||
|
@ -12,7 +12,6 @@ import scala.collection.mutable
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
object Z80ReturnDispatch extends AbstractReturnDispatch[ZLine] {
|
||||
override def nextLabel(prefix: String): String = Z80Compiler.nextLabel("di")
|
||||
|
||||
override def compileImpl(ctx: CompilationContext,
|
||||
stmt: ReturnDispatchStatement,
|
||||
|
@ -44,7 +44,7 @@ object Z80Shifting {
|
||||
val calcCount = Z80ExpressionCompiler.compile8BitTo(ctx, rhs, ZRegister.B)
|
||||
val l = Z80ExpressionCompiler.stashBCIfChanged(ctx, Z80ExpressionCompiler.compileToA(ctx, lhs))
|
||||
val loopBody = op :: fixAfterShiftIfNeeded(extendedOps, left, 1)
|
||||
val label = Z80Compiler.nextLabel("sh")
|
||||
val label = ctx.nextLabel("sh")
|
||||
calcCount ++ l ++ List(ZLine.label(label)) ++ loopBody ++ ZLine.djnz(ctx, label)
|
||||
}
|
||||
}
|
||||
@ -120,7 +120,7 @@ object Z80Shifting {
|
||||
val calcCount = Z80ExpressionCompiler.compile8BitTo(ctx, rhs, ZRegister.B)
|
||||
val l = Z80ExpressionCompiler.stashBCIfChanged(ctx, Z80ExpressionCompiler.compileToA(ctx, lhs))
|
||||
val loopBody = ZLine.register(op, ZRegister.A) :: fixAfterShiftIfNeeded(extendedOps, left, 1)
|
||||
val label = Z80Compiler.nextLabel("sh")
|
||||
val label = ctx.nextLabel("sh")
|
||||
calcCount ++ l ++ List(ZLine.label(label)) ++ loopBody ++ ZLine.djnz(ctx, label) ++ Z80ExpressionCompiler.storeA(ctx, lhs, signedSource = false)
|
||||
}
|
||||
}
|
||||
@ -200,7 +200,7 @@ object Z80Shifting {
|
||||
ZLine.ld8(ZRegister.L, ZRegister.A))
|
||||
}
|
||||
}
|
||||
val label = Z80Compiler.nextLabel("sh")
|
||||
val label = ctx.nextLabel("sh")
|
||||
calcCount ++ l ++ List(ZLine.label(label)) ++ loopBody ++ ZLine.djnz(ctx, label)
|
||||
}
|
||||
}
|
||||
@ -270,7 +270,7 @@ object Z80Shifting {
|
||||
case Some(NumericConstant(n, _)) =>
|
||||
List.fill(n.toInt)(shiftOne).flatten
|
||||
case _ =>
|
||||
val label = Z80Compiler.nextLabel("sh")
|
||||
val label = ctx.nextLabel("sh")
|
||||
val calcCount = Z80ExpressionCompiler.compile8BitTo(ctx, rhs, ZRegister.B)
|
||||
calcCount ++ List(ZLine.label(label)) ++ shiftOne ++ ZLine.djnz(ctx, label)
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ object Z80StatementCompiler extends AbstractStatementCompiler[ZLine] {
|
||||
env.lookupFunction(name, params.map(p => Z80ExpressionCompiler.getExpressionType(ctx, p) -> p)) match {
|
||||
case Some(i: MacroFunction) =>
|
||||
val (paramPreparation, inlinedStatements) = Z80MacroExpander.inlineFunction(ctx, i, params, e.position)
|
||||
paramPreparation ++ compile(ctx.withInlinedEnv(i.environment, Z80Compiler.nextLabel("en")), inlinedStatements)
|
||||
paramPreparation ++ compile(ctx.withInlinedEnv(i.environment, ctx.nextLabel("en")), inlinedStatements)
|
||||
case _ =>
|
||||
Z80ExpressionCompiler.compile(ctx, e, ZExpressionTarget.NOTHING)
|
||||
}
|
||||
@ -245,8 +245,6 @@ object Z80StatementCompiler extends AbstractStatementCompiler[ZLine] {
|
||||
|
||||
def areBlocksLarge(blocks: List[ZLine]*): Boolean = false
|
||||
|
||||
override def nextLabel(prefix: String): String = Z80Compiler.nextLabel(prefix)
|
||||
|
||||
override def compileExpressionForBranching(ctx: CompilationContext, expr: Expression, branching: BranchSpec): List[ZLine] =
|
||||
Z80ExpressionCompiler.compile(ctx, expr, ZExpressionTarget.NOTHING, branching)
|
||||
|
||||
|
18
src/main/scala/millfork/env/Environment.scala
vendored
18
src/main/scala/millfork/env/Environment.scala
vendored
@ -1,11 +1,10 @@
|
||||
package millfork.env
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
import millfork.assembly.BranchingOpcodeMapping
|
||||
import millfork.{CompilationFlag, CompilationOptions, Cpu, CpuFamily}
|
||||
import millfork._
|
||||
import millfork.assembly.mos.Opcode
|
||||
import millfork.assembly.z80.{IfFlagClear, IfFlagSet, ZFlag}
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.error.Logger
|
||||
import millfork.node._
|
||||
import millfork.output.{AllocationLocation, CompiledMemory, VariableAllocator}
|
||||
@ -17,8 +16,12 @@ import scala.collection.mutable
|
||||
* @author Karol Stasiak
|
||||
*/
|
||||
//noinspection NotImplementedCode
|
||||
class Environment(val parent: Option[Environment], val prefix: String, val cpuFamily: CpuFamily.Value, val log: Logger) {
|
||||
class Environment(val parent: Option[Environment], val prefix: String, val cpuFamily: CpuFamily.Value, val jobContext: JobContext) {
|
||||
|
||||
@inline
|
||||
def log: Logger = jobContext.log
|
||||
@inline
|
||||
def nextLabel: LabelGenerator = jobContext.nextLabel
|
||||
|
||||
private var baseStackOffset: Int = cpuFamily match {
|
||||
case CpuFamily.M6502 => 0x101
|
||||
@ -31,7 +34,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
}
|
||||
|
||||
def genRelativeVariable(constant: Constant, typ: Type, zeropage: Boolean): RelativeVariable = {
|
||||
val variable = RelativeVariable(".rv__" + Environment.relVarId.incrementAndGet().formatted("%06d"), constant, typ, zeropage = zeropage, declaredBank = None /*TODO*/)
|
||||
val variable = RelativeVariable(nextLabel("rv"), constant, typ, zeropage = zeropage, declaredBank = None /*TODO*/)
|
||||
addThing(variable, None)
|
||||
variable
|
||||
}
|
||||
@ -45,7 +48,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
m.environment.getAllPrefixedThings
|
||||
case _ => Map[String, Thing]()
|
||||
}.fold(things.toMap)(_ ++ _)
|
||||
val e = new Environment(None, "", cpuFamily, log)
|
||||
val e = new Environment(None, "", cpuFamily, jobContext)
|
||||
e.things.clear()
|
||||
e.things ++= allThings
|
||||
e
|
||||
@ -685,7 +688,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
log.error(s"Non-macro function `$name` cannot have inlinable parameters", stmt.position)
|
||||
}
|
||||
|
||||
val env = new Environment(Some(this), name + "$", cpuFamily, log)
|
||||
val env = new Environment(Some(this), name + "$", cpuFamily, jobContext)
|
||||
stmt.params.foreach(p => env.registerParameter(p, options))
|
||||
val params = if (stmt.assembly) {
|
||||
AssemblyParamSignature(stmt.params.map {
|
||||
@ -1242,5 +1245,4 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
|
||||
object Environment {
|
||||
val predefinedFunctions = Set("not", "hi", "lo", "nonet")
|
||||
val relVarId = new AtomicLong
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
|
||||
injectLabels(labelMap, inliningCalculator.inline(
|
||||
compiler.compile(CompilationContext(env = f.environment, function = f, extraStackOffset = 0, options = options, niceFunctionProperties = niceFunctionProperties)),
|
||||
inlinedFunctions,
|
||||
compiler))
|
||||
options.jobContext))
|
||||
unoptimizedCodeSize += unoptimized.map(_.sizeInBytes).sum
|
||||
val code = optimizations.foldLeft(unoptimized) { (c, opt) =>
|
||||
opt.optimize(f, c, OptimizationContext(options, labelMap, env.maybeGet[ThingInMemory]("__reg"), niceFunctionProperties))
|
||||
|
@ -1,5 +1,6 @@
|
||||
package millfork.output
|
||||
|
||||
import millfork.JobContext
|
||||
import millfork.assembly.AbstractCode
|
||||
import millfork.assembly.mos.Opcode
|
||||
import millfork.assembly.z80.ZOpcode
|
||||
@ -13,7 +14,7 @@ import scala.collection.mutable
|
||||
*/
|
||||
abstract class AbstractInliningCalculator[T <: AbstractCode] {
|
||||
def codeForInlining(fname: String, functionsAlreadyKnownToBeNonInlineable: Set[String], code: List[T]): Option[List[T]]
|
||||
def inline(code: List[T], inlinedFunctions: Map[String, List[T]], compiler: AbstractCompiler[T]): List[T]
|
||||
def inline(code: List[T], inlinedFunctions: Map[String, List[T]], jobContext: JobContext): List[T]
|
||||
|
||||
private val sizes = Seq(64, 64, 8, 6, 5, 5, 4)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package millfork.output
|
||||
|
||||
import millfork.JobContext
|
||||
import millfork.assembly.mos.Opcode._
|
||||
import millfork.assembly.mos.{AddrMode, _}
|
||||
import millfork.compiler.AbstractCompiler
|
||||
@ -42,10 +43,10 @@ object MosInliningCalculator extends AbstractInliningCalculator[AssemblyLine] {
|
||||
Some(result)
|
||||
}
|
||||
|
||||
def inline(code: List[AssemblyLine], inlinedFunctions: Map[String, List[AssemblyLine]], compiler: AbstractCompiler[AssemblyLine]): List[AssemblyLine] = {
|
||||
def inline(code: List[AssemblyLine], inlinedFunctions: Map[String, List[AssemblyLine]], jobContext: JobContext): List[AssemblyLine] = {
|
||||
code.flatMap {
|
||||
case AssemblyLine(Opcode.JSR, AddrMode.Absolute | AddrMode.LongAbsolute, p, true) if inlinedFunctions.contains(p.toString) =>
|
||||
val labelPrefix = compiler.nextLabel("ai")
|
||||
val labelPrefix = jobContext.nextLabel("ai")
|
||||
inlinedFunctions(p.toString).map {
|
||||
case line@AssemblyLine(_, _, MemoryAddressConstant(Label(label)), _) =>
|
||||
val newLabel = MemoryAddressConstant(Label(labelPrefix + label))
|
||||
@ -53,7 +54,7 @@ object MosInliningCalculator extends AbstractInliningCalculator[AssemblyLine] {
|
||||
case l => l
|
||||
}
|
||||
case AssemblyLine(Opcode.JMP, AddrMode.Absolute, p, true) if inlinedFunctions.contains(p.toString) =>
|
||||
val labelPrefix = compiler.nextLabel("ai")
|
||||
val labelPrefix = jobContext.nextLabel("ai")
|
||||
inlinedFunctions(p.toString).map {
|
||||
case line@AssemblyLine(_, _, MemoryAddressConstant(Label(label)), _) =>
|
||||
val newLabel = MemoryAddressConstant(Label(labelPrefix + label))
|
||||
|
@ -1,5 +1,6 @@
|
||||
package millfork.output
|
||||
|
||||
import millfork.JobContext
|
||||
import millfork.assembly.z80._
|
||||
import millfork.compiler.AbstractCompiler
|
||||
import millfork.env._
|
||||
@ -41,22 +42,22 @@ object Z80InliningCalculator extends AbstractInliningCalculator[ZLine] {
|
||||
Some(result)
|
||||
}
|
||||
|
||||
def wrap(registers: ZRegisters, compiler: AbstractCompiler[ZLine], lines: List[ZLine]): List[ZLine] = registers match {
|
||||
def wrap(registers: ZRegisters, jobContext: JobContext, lines: List[ZLine]): List[ZLine] = registers match {
|
||||
case NoRegisters => lines
|
||||
case IfFlagClear(flag) =>
|
||||
val label = compiler.nextLabel("ai")
|
||||
val label = jobContext.nextLabel("ai")
|
||||
ZLine.jump(label, IfFlagSet(flag)) :: (lines :+ ZLine.label(label))
|
||||
case IfFlagSet(flag) =>
|
||||
val label = compiler.nextLabel("ai")
|
||||
val label = jobContext.nextLabel("ai")
|
||||
ZLine.jump(label, IfFlagClear(flag)) :: (lines :+ ZLine.label(label))
|
||||
case _ => throw new IllegalArgumentException("registers")
|
||||
}
|
||||
|
||||
override def inline(code: List[ZLine], inlinedFunctions: Map[String, List[ZLine]], compiler: AbstractCompiler[ZLine]): List[ZLine] = {
|
||||
override def inline(code: List[ZLine], inlinedFunctions: Map[String, List[ZLine]], jobContext: JobContext): List[ZLine] = {
|
||||
code.flatMap {
|
||||
case ZLine(CALL, registers, p, true) if inlinedFunctions.contains(p.toString) =>
|
||||
val labelPrefix = compiler.nextLabel("ai")
|
||||
wrap(registers, compiler,
|
||||
val labelPrefix = jobContext.nextLabel("ai")
|
||||
wrap(registers, jobContext,
|
||||
inlinedFunctions(p.toString).map {
|
||||
case line@ZLine(_, _, MemoryAddressConstant(Label(label)), _) =>
|
||||
val newLabel = MemoryAddressConstant(Label(labelPrefix + label))
|
||||
@ -64,8 +65,8 @@ object Z80InliningCalculator extends AbstractInliningCalculator[ZLine] {
|
||||
case l => l
|
||||
})
|
||||
case ZLine(JP | JR, registers, p, true) if inlinedFunctions.contains(p.toString) =>
|
||||
val labelPrefix = compiler.nextLabel("ai")
|
||||
wrap(registers, compiler,
|
||||
val labelPrefix = jobContext.nextLabel("ai")
|
||||
wrap(registers, jobContext,
|
||||
inlinedFunctions(p.toString).map {
|
||||
case line@ZLine(_, _, MemoryAddressConstant(Label(label)), _) =>
|
||||
val newLabel = MemoryAddressConstant(Label(labelPrefix + label))
|
||||
|
@ -1,7 +1,8 @@
|
||||
package millfork.test
|
||||
|
||||
import millfork.{CompilationOptions, Cpu, CpuFamily}
|
||||
import millfork.{CompilationOptions, Cpu, CpuFamily, JobContext}
|
||||
import millfork.assembly.z80.{LocalVariableAddressViaIX, NoRegisters, ZLine}
|
||||
import millfork.compiler.LabelGenerator
|
||||
import millfork.env.{Constant, Environment, NumericConstant}
|
||||
import millfork.output.Z80Assembler
|
||||
import millfork.test.emu._
|
||||
@ -14,8 +15,9 @@ import org.scalatest.{FunSuite, Matchers}
|
||||
class ZLineSizeSuite extends FunSuite with Matchers {
|
||||
private def runCase(line: ZLine): Unit = {
|
||||
val platform = EmuPlatform.get(Cpu.Z80)
|
||||
val env = new Environment(None, "", CpuFamily.I80, TestErrorReporting.log)
|
||||
val options = CompilationOptions(platform, Map(), None, 0, TestErrorReporting.log)
|
||||
val jobContext = JobContext(TestErrorReporting.log, new LabelGenerator)
|
||||
val env = new Environment(None, "", CpuFamily.I80, jobContext)
|
||||
val options = CompilationOptions(platform, Map(), None, 0, jobContext)
|
||||
val correctSize = new Z80Assembler(null, env, platform).emitInstruction("default", options, 0x100, line) - 0x100
|
||||
val guessedSize = line.sizeInBytes
|
||||
guessedSize should equal(correctSize)
|
||||
|
@ -9,7 +9,7 @@ import com.loomcom.symon.{Bus, Cpu, CpuState}
|
||||
import fastparse.core.Parsed.{Failure, Success}
|
||||
import millfork.assembly.AssemblyOptimization
|
||||
import millfork.assembly.mos.AssemblyLine
|
||||
import millfork.compiler.CompilationContext
|
||||
import millfork.compiler.{CompilationContext, LabelGenerator}
|
||||
import millfork.compiler.mos.MosCompiler
|
||||
import millfork.env.{Environment, InitializedArray, InitializedMemoryVariable, NormalFunction}
|
||||
import millfork.error.{ConsoleLogger, Logger}
|
||||
@ -17,7 +17,7 @@ import millfork.node.StandardCallGraph
|
||||
import millfork.node.opt.NodeOptimization
|
||||
import millfork.output.{MemoryBank, MosAssembler}
|
||||
import millfork.parser.{MosParser, Preprocessor}
|
||||
import millfork.{CompilationFlag, CompilationOptions, CpuFamily}
|
||||
import millfork.{CompilationFlag, CompilationOptions, CpuFamily, JobContext}
|
||||
import org.scalatest.Matchers
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
@ -113,7 +113,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
||||
CompilationFlag.OptimizeForSpeed -> blastProcessing,
|
||||
CompilationFlag.OptimizeForSonicSpeed -> blastProcessing
|
||||
// CompilationFlag.CheckIndexOutOfBounds -> true,
|
||||
), None, 2, log)
|
||||
), None, 2, JobContext(log, new LabelGenerator))
|
||||
log.hasErrors = false
|
||||
log.verbosity = 999
|
||||
var effectiveSource = source
|
||||
@ -131,7 +131,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
||||
// prepare
|
||||
val program = nodeOptimizations.foldLeft(unoptimized)((p, opt) => p.applyNodeOptimization(opt, options))
|
||||
val callGraph = new StandardCallGraph(program, log)
|
||||
val env = new Environment(None, "", CpuFamily.M6502, log)
|
||||
val env = new Environment(None, "", CpuFamily.M6502, options.jobContext)
|
||||
env.collectDeclarations(program, options)
|
||||
|
||||
val hasOptimizations = assemblyOptimizations.nonEmpty
|
||||
@ -151,7 +151,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
|
||||
|
||||
|
||||
// compile
|
||||
val env2 = new Environment(None, "", CpuFamily.M6502, log)
|
||||
val env2 = new Environment(None, "", CpuFamily.M6502, options.jobContext)
|
||||
env2.collectDeclarations(program, options)
|
||||
val assembler = new MosAssembler(program, env2, platform)
|
||||
val output = assembler.assemble(callGraph, assemblyOptimizations, options)
|
||||
|
@ -7,14 +7,14 @@ import eu.rekawek.coffeegb.gpu.Gpu
|
||||
import fastparse.core.Parsed.{Failure, Success}
|
||||
import millfork.assembly.AssemblyOptimization
|
||||
import millfork.assembly.z80.ZLine
|
||||
import millfork.compiler.CompilationContext
|
||||
import millfork.compiler.{CompilationContext, LabelGenerator}
|
||||
import millfork.env.{Environment, InitializedArray, InitializedMemoryVariable, NormalFunction}
|
||||
import millfork.error.ConsoleLogger
|
||||
import millfork.node.StandardCallGraph
|
||||
import millfork.node.opt.NodeOptimization
|
||||
import millfork.output.{MemoryBank, Z80Assembler}
|
||||
import millfork.parser.{Preprocessor, Z80Parser}
|
||||
import millfork.{CompilationFlag, CompilationOptions, CpuFamily}
|
||||
import millfork.{CompilationFlag, CompilationOptions, CpuFamily, JobContext}
|
||||
import millfork.compiler.z80.Z80Compiler
|
||||
import org.scalatest.Matchers
|
||||
|
||||
@ -40,7 +40,7 @@ class EmuZ80Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizatio
|
||||
CompilationFlag.InlineFunctions -> this.inline,
|
||||
CompilationFlag.EmitIllegals -> (cpu == millfork.Cpu.Z80),
|
||||
CompilationFlag.LenientTextEncoding -> true)
|
||||
val options = CompilationOptions(platform, millfork.Cpu.defaultFlags(cpu).map(_ -> true).toMap ++ extraFlags, None, 0, log)
|
||||
val options = CompilationOptions(platform, millfork.Cpu.defaultFlags(cpu).map(_ -> true).toMap ++ extraFlags, None, 0, JobContext(log, new LabelGenerator))
|
||||
log.hasErrors = false
|
||||
log.verbosity = 999
|
||||
var effectiveSource = source
|
||||
@ -56,7 +56,7 @@ class EmuZ80Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizatio
|
||||
// prepare
|
||||
val program = nodeOptimizations.foldLeft(unoptimized)((p, opt) => p.applyNodeOptimization(opt, options))
|
||||
val callGraph = new StandardCallGraph(program, log)
|
||||
val env = new Environment(None, "", CpuFamily.I80, log)
|
||||
val env = new Environment(None, "", CpuFamily.I80, options.jobContext)
|
||||
env.collectDeclarations(program, options)
|
||||
|
||||
val hasOptimizations = assemblyOptimizations.nonEmpty
|
||||
@ -76,7 +76,7 @@ class EmuZ80Run(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimizatio
|
||||
|
||||
|
||||
// compile
|
||||
val env2 = new Environment(None, "", CpuFamily.I80, log)
|
||||
val env2 = new Environment(None, "", CpuFamily.I80, options.jobContext)
|
||||
env2.collectDeclarations(program, options)
|
||||
val assembler = new Z80Assembler(program, env2, platform)
|
||||
val output = assembler.assemble(callGraph, assemblyOptimizations, options)
|
||||
|
@ -4,13 +4,12 @@ import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.{Files, Paths}
|
||||
|
||||
import fastparse.core.Parsed.{Failure, Success}
|
||||
import millfork.compiler.CompilationContext
|
||||
import millfork.compiler.{CompilationContext, LabelGenerator}
|
||||
import millfork.compiler.mos.MosCompiler
|
||||
import millfork.env.{Environment, InitializedArray, InitializedMemoryVariable, NormalFunction}
|
||||
import millfork.error.{ConsoleLogger, FatalErrorReporting}
|
||||
import millfork.node.StandardCallGraph
|
||||
import millfork.parser.{MosParser, Preprocessor}
|
||||
import millfork.{CompilationFlag, CompilationOptions, Cpu, CpuFamily}
|
||||
import millfork._
|
||||
import org.scalatest.Matchers
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
@ -29,7 +28,7 @@ object ShouldNotCompile extends Matchers {
|
||||
val log = TestErrorReporting.log
|
||||
println(source)
|
||||
val platform = EmuPlatform.get(cpu)
|
||||
val options = CompilationOptions(platform, Map(CompilationFlag.LenientTextEncoding -> true), None, platform.zpRegisterSize, log)
|
||||
val options = CompilationOptions(platform, Map(CompilationFlag.LenientTextEncoding -> true), None, platform.zpRegisterSize, JobContext(log, new LabelGenerator))
|
||||
log.hasErrors = false
|
||||
log.verbosity = 999
|
||||
var effectiveSource = source
|
||||
@ -46,7 +45,7 @@ object ShouldNotCompile extends Matchers {
|
||||
// prepare
|
||||
val callGraph = new StandardCallGraph(program, log)
|
||||
val cpuFamily = CpuFamily.forType(cpu)
|
||||
val env = new Environment(None, "", cpuFamily, log)
|
||||
val env = new Environment(None, "", cpuFamily, options.jobContext)
|
||||
env.collectDeclarations(program, options)
|
||||
|
||||
var unoptimizedSize = 0L
|
||||
|
Loading…
x
Reference in New Issue
Block a user